|
| 1 | +// RUN: %target-swift-frontend -primary-file %s -O -module-name=test -emit-sil | %FileCheck %s |
| 2 | +// RUN: %target-swift-frontend -primary-file %s -O -module-name=test -emit-ir | %FileCheck %s -check-prefix=CHECK-LLVM |
| 3 | + |
| 4 | +// Also do an end-to-end test to check all components, including IRGen. |
| 5 | +// RUN: %empty-directory(%t) |
| 6 | +// RUN: %target-build-swift -O -module-name=test %s -o %t/a.out |
| 7 | +// RUN: %target-run %t/a.out | %FileCheck %s -check-prefix=CHECK-OUTPUT |
| 8 | + |
| 9 | +// REQUIRES: libswift,executable_test,swift_stdlib_no_asserts,optimized_stdlib |
| 10 | + |
| 11 | +// Check that we create reasonable optimized code for this function. |
| 12 | + |
| 13 | +@inline(never) |
| 14 | +public func reverseArray(_ a: [Int]) -> [Int] { |
| 15 | + var new: [Int] = [] |
| 16 | + new.reserveCapacity(a.count) |
| 17 | + |
| 18 | + var fromIndex = a.count &- 1 |
| 19 | + |
| 20 | + while fromIndex >= 0 { |
| 21 | + new.append(a[fromIndex]) |
| 22 | + fromIndex &-= 1 |
| 23 | + } |
| 24 | + |
| 25 | + return new |
| 26 | +} |
| 27 | + |
| 28 | + |
| 29 | +// CHECK-LABEL: sil [noinline] @$s4test12reverseArrayySaySiGACF |
| 30 | + |
| 31 | +// There must not be more than two begin_cow_mutation - end_cow_mutation pairs: |
| 32 | +// * the first one for the initial reserveCapacity |
| 33 | +// * the second for the append. |
| 34 | + |
| 35 | +// CHECK-NOT: {{.*(_cow_mutation|cond_fail)}} |
| 36 | +// CHECK: begin_cow_mutation |
| 37 | +// CHECK-NOT: {{.*(_cow_mutation|cond_fail)}} |
| 38 | +// CHECK: end_cow_mutation |
| 39 | +// CHECK-NOT: {{.*(_cow_mutation|cond_fail)}} |
| 40 | + |
| 41 | +// In SIL we fail to eliminate the bounds check of the input array. |
| 42 | +// But that's okay, because LLVM can do that. |
| 43 | +// So we accept one cond_fail in the SIL output. |
| 44 | + |
| 45 | +// CHECK: cond_fail {{.*}} "Index out of range" |
| 46 | + |
| 47 | +// The second begin_cow_mutation - end_cow_mutation pair: |
| 48 | + |
| 49 | +// CHECK-NOT: {{.*(_cow_mutation|cond_fail)}} |
| 50 | +// CHECK: begin_cow_mutation |
| 51 | +// CHECK-NOT: {{.*(_cow_mutation|cond_fail)}} |
| 52 | +// CHECK: end_cow_mutation |
| 53 | +// CHECK-NOT: {{.*(_cow_mutation|cond_fail)}} |
| 54 | + |
| 55 | +// CHECK: } // end sil function '$s4test12reverseArrayySaySiGACF' |
| 56 | + |
| 57 | + |
| 58 | +// Check that there are no cond_fails left in the LLVM output. |
| 59 | +// LLVM should be able to optimize away the bounds check of the input array. |
| 60 | + |
| 61 | +// CHECK-LLVM-LABEL: define {{.*}} @"$s4test12reverseArrayySaySiGACF" |
| 62 | +// CHECK-LLVM-NOT: llvm.trap |
| 63 | +// CHECK-LLVM: } |
| 64 | + |
| 65 | + |
| 66 | +// CHECK-OUTPUT: [3, 2, 1] |
| 67 | +print(reverseArray([1, 2, 3])) |
| 68 | + |
0 commit comments