Files
swift-mirror/test/SILOptimizer/unsafebufferpointer.swift
Erik Eckstein 1de19a1b32 SimplifyCFG: fix a compile time problem with block merging
When merging many blocks to a single block (in the wrong order), instructions are getting moved over and over again.
This is quadratic and can result in very long compile times for large functions.
To fix this, always move the instruction to smaller block to the larger block.

rdar://problem/56268570
2020-04-10 20:10:24 +02:00

92 lines
2.4 KiB
Swift

// RUN: %target-swift-frontend -parse-as-library -Osize -emit-ir %s | %FileCheck %s
// REQUIRES: swift_stdlib_no_asserts,optimized_stdlib
// This is an end-to-end test to ensure that the optimizer generates
// optimal code for UnsafeBufferPointer.
// CHECK-LABEL: define {{.*}}testIteration
// Check if the code contains no traps at all.
// CHECK-NOT: unreachable
public func testIteration(_ p: UnsafeBufferPointer<Int>) -> Int {
var s = 0
// Check for an optimal loop kernel
// CHECK: phi
// CHECK-NEXT: phi
// CHECK-NEXT: bitcast
// CHECK-NEXT: load
// CHECK-NEXT: getelementptr
// CHECK-NEXT: add
// CHECK-NEXT: icmp
// CHECK-NEXT: br
for x in p {
s = s &+ x
}
// CHECK-NOT: unreachable
// CHECK: phi
// CHECK-NEXT: ret
// CHECK-NOT: unreachable
return s
}
// CHECK-LABEL: define {{.*}}testIsEmpty
// CHECK: entry:
// CHECK-NEXT: icmp
// CHECK-NEXT: ret
public func testIsEmpty(_ x: UnsafeBufferPointer<UInt>) -> Bool {
return x.isEmpty
}
// CHECK-LABEL: define {{.*}}testCount
// CHECK: entry:
// CHECK-NEXT: ret
public func testCount(_ x: UnsafeBufferPointer<UInt>) -> Int {
return x.count
}
// Within the loop, there should be no extra checks.
// CHECK-LABEL: define {{.*}} float {{.*}}testSubscript
// The only unconditional branch is into the loop.
// CHECK: br label %[[LOOP:[0-9]+]]
//
// CHECK: [[LOOP]]:
// CHECK: phi float [ 0.000000e+00
// CHECK: load float, float*
// CHECK: fadd float
// CHECK: [[CMP:%[0-9]+]] = icmp eq
// CHECK: br i1 [[CMP]], label %.loopexit, label %[[LOOP]]
//
// CHECK: .loopexit: ; preds = %[[LOOP]]
// CHECK: ret float
public func testSubscript(_ ubp: UnsafeBufferPointer<Float>) -> Float {
var sum: Float = 0
for i in 0 ..< ubp.count {
sum += ubp[i]
}
return sum
}
// Within the loop, there should be no extra checks.
// CHECK-LABEL: define {{.*}} i64 {{.*}}testSubscript
// The only unconditional branch is into the loop.
// CHECK: br label %[[LOOP:[0-9]+]]
//
// CHECK: [[LOOP]]:
// CHECK: phi i64 [ 0
// CHECK: load i8, i8*
// CHECK: zext i8 %{{.*}} to i64
// CHECK: add i64
// CHECK: [[CMP:%[0-9]+]] = icmp eq
// CHECK: br i1 [[CMP]], label %[[RET:.*]], label %[[LOOP]]
//
// CHECK: [[RET]]: ; preds = %[[LOOP]], %entry
// CHECK: ret i64
public func testSubscript(_ ubp: UnsafeRawBufferPointer) -> Int64 {
var sum: Int64 = 0
for i in 0 ..< ubp.count {
sum &+= Int64(ubp[i])
}
return sum
}