Files
swift-mirror/test/SILOptimizer/for_each_loop_unroll_test.sil
Erik Eckstein 7cceaff5f3 SIL: don't print operand types in textual SIL
Type annotations for instruction operands are omitted, e.g.

```
  %3 = struct $S(%1, %2)
```

Operand types are redundant anyway and were only used for sanity checking in the SIL parser.

But: operand types _are_ printed if the definition of the operand value was not printed yet.
This happens:

* if the block with the definition appears after the block where the operand's instruction is located

* if a block or instruction is printed in isolation, e.g. in a debugger

The old behavior can be restored with `-Xllvm -sil-print-types`.
This option is added to many existing test files which check for operand types in their check-lines.
2024-11-21 18:49:52 +01:00

236 lines
15 KiB
Plaintext

// RUN: %target-sil-opt -sil-print-types -for-each-loop-unroll -enable-sil-verify-all %s 2>&1 | %FileCheck %s
// SIL tests for the ForEachLoopUnroll mandatory optimization pass that unrolls
// Sequence.forEach calls over array literals.
import Swift
import Builtin
sil [_semantics "array.uninitialized_intrinsic"] @_allocateUninitializedArray : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
sil [_semantics "sequence.forEach"] @forEach : $@convention(method) <τ_0_0 where τ_0_0 : Sequence> (@noescape @callee_guaranteed (@in_guaranteed τ_0_0.Element) -> @error any Error, @in_guaranteed τ_0_0) -> @error any Error
sil @forEachBody : $@convention(thin) (@in_guaranteed Builtin.Int64) -> @error any Error
// CHECK-LABEL: forEachLoopUnrollTest
// CHECK: [[LIT1:%[0-9]+]] = integer_literal $Builtin.Int64, 15
// CHECK: [[LIT2:%[0-9]+]] = integer_literal $Builtin.Int64, 27
// CHECK: [[BODYCLOSURE:%[0-9]+]] = thin_to_thick_function
// CHECK-NOT: forEach
// CHECK: [[STACK:%[0-9]+]] = alloc_stack $Builtin.Int64
// CHECK: store [[LIT1]] to [trivial] [[STACK]]
// CHECK: try_apply [[BODYCLOSURE]]([[STACK]]) : $@noescape @callee_guaranteed (@in_guaranteed Builtin.Int64) -> @error any Error, normal [[NORMAL:bb[0-9]+]], error [[ERROR:bb[0-9]+]]
// CHECK: [[ERROR]]([[ERRPARAM:%[0-9]+]] : @owned $any Error):
// CHECK: br [[ERROR3:bb[0-9]+]]([[ERRPARAM]] : $any Error)
// CHECK: [[NORMAL]](%{{.*}} : $()):
// CHECK: store [[LIT2]] to [trivial] [[STACK]] : $*Builtin.Int64
// CHECK: try_apply [[BODYCLOSURE]]([[STACK]]) : $@noescape @callee_guaranteed (@in_guaranteed Builtin.Int64) -> @error any Error, normal [[NORMAL2:bb[0-9]+]], error [[ERROR2:bb[0-9]+]]
// CHECK: [[ERROR2]]([[ERRPARAM2:%[0-9]+]] : @owned $any Error):
// CHECK: br [[ERROR3:bb[0-9]+]]([[ERRPARAM2]] : $any Error)
// CHECK: [[NORMAL2]](%{{.*}} : $()):
// CHECK: dealloc_stack [[STACK]]
// Note that the temporary alloc_stack of the array created for the forEach call
// will be cleaned up when the forEach call is removed.
// CHECK: destroy_value
// CHECK: [[ERROR3]]([[ERRPARAM3:%[0-9]+]] : @owned $any Error):
// CHECK: dealloc_stack [[STACK]]
// CHECK: unreachable
sil hidden [ossa] @forEachLoopUnrollTest : $@convention(thin) () -> () {
bb0:
%0 = integer_literal $Builtin.Word, 2
%1 = function_ref @_allocateUninitializedArray : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
%2 = apply %1<Builtin.Int64>(%0) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
(%3, %4a) = destructure_tuple %2 : $(Array<Builtin.Int64>, Builtin.RawPointer)
%4 = mark_dependence %4a : $Builtin.RawPointer on %3 : $Array<Builtin.Int64>
%5 = pointer_to_address %4 : $Builtin.RawPointer to [strict] $*Builtin.Int64
%6 = integer_literal $Builtin.Int64, 15
store %6 to [trivial] %5 : $*Builtin.Int64
%12 = integer_literal $Builtin.Word, 1
%13 = index_addr %5 : $*Builtin.Int64, %12 : $Builtin.Word
%14 = integer_literal $Builtin.Int64, 27
store %14 to [trivial] %13 : $*Builtin.Int64
%21 = begin_borrow %3 : $Array<Builtin.Int64>
%22 = alloc_stack $Array<Builtin.Int64>
%23 = store_borrow %21 to %22 : $*Array<Builtin.Int64>
%24 = function_ref @forEachBody : $@convention(thin) (@in_guaranteed Builtin.Int64) -> @error any Error
%25 = convert_function %24 : $@convention(thin) (@in_guaranteed Builtin.Int64) -> @error any Error to $@convention(thin) @noescape (@in_guaranteed Builtin.Int64) -> @error any Error
%26 = thin_to_thick_function %25 : $@convention(thin) @noescape (@in_guaranteed Builtin.Int64) -> @error any Error to $@noescape @callee_guaranteed (@in_guaranteed Builtin.Int64) -> @error any Error
// A stub for Sequence.forEach(_:)
%30 = function_ref @forEach : $@convention(method) <τ_0_0 where τ_0_0 : Sequence> (@noescape @callee_guaranteed (@in_guaranteed τ_0_0.Element) -> @error Error, @in_guaranteed τ_0_0) -> @error Error
try_apply %30<[Builtin.Int64]>(%26, %23) : $@convention(method) <τ_0_0 where τ_0_0 : Sequence> (@noescape @callee_guaranteed (@in_guaranteed τ_0_0.Element) -> @error Error, @in_guaranteed τ_0_0) -> @error Error, normal bb1, error bb2
bb1(%32 : $()):
end_borrow %23 : $*Array<Builtin.Int64>
dealloc_stack %22 : $*Array<Builtin.Int64>
end_borrow %21 : $Array<Builtin.Int64>
destroy_value %3 : $Array<Builtin.Int64>
%37 = tuple ()
return %37 : $()
bb2(%39 : @owned $Error):
unreachable
}
sil @forEachBody2 : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <A> () -> @out A for <Int>) -> @error any Error
// CHECK-LABEL: nonTrivialForEachLoopUnrollTest
// CHECK: [[ELEM1:%[0-9]+]] = copy_value %0
// CHECK-NEXT: store %0 to [init] %{{.*}} : $*@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Int>
// CHECK: [[ELEM2:%[0-9]+]] = copy_value %1
// CHECK-NEXT: store %1 to [init] %{{.*}} : $*@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Int>
// CHECK: [[BODYCLOSURE:%[0-9]+]] = thin_to_thick_function
// CHECK-NOT: forEach
// CHECK: [[STACK:%[0-9]+]] = alloc_stack $@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Int>
// CHECK: [[ELEM1BORROW:%[0-9]+]] = begin_borrow [[ELEM1]]
// CHECK: [[SB1:%.*]] = store_borrow [[ELEM1BORROW]] to [[STACK]]
// CHECK: try_apply [[BODYCLOSURE]]([[SB1]]) : $@noescape @callee_guaranteed (@in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Int>) -> @error any Error, normal [[NORMAL:bb[0-9]+]], error [[ERROR:bb[0-9]+]]
// CHECK: [[ERROR]]([[ERRPARAM:%[0-9]+]] : @owned $any Error):
// CHECK: br [[ERROR3:bb[0-9]+]]([[ERRPARAM]] : $any Error)
// CHECK: [[NORMAL]](%{{.*}} : $()):
// CHECK: end_borrow [[ELEM1BORROW]]
// CHECK: [[ELEM2BORROW:%[0-9]+]] = begin_borrow [[ELEM2]]
// CHECK: [[SB2:%.*]] = store_borrow [[ELEM2BORROW]] to [[STACK]]
// CHECK: try_apply [[BODYCLOSURE]]([[SB2]]) : $@noescape @callee_guaranteed (@in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Int>) -> @error any Error, normal [[NORMAL2:bb[0-9]+]], error [[ERROR2:bb[0-9]+]]
// CHECK: [[ERROR2]]([[ERRPARAM2:%[0-9]+]] : @owned $any Error):
// CHECK: br [[ERROR3:bb[0-9]+]]([[ERRPARAM2]] : $any Error)
// CHECK: [[NORMAL2]](%{{.*}} : $()):
// CHECK: end_borrow [[ELEM2BORROW]]
// CHECK: dealloc_stack [[STACK]]
// Note that the temporary alloc_stack of the array created for the forEach call
// will be cleaned up when the forEach call is removed.
// CHECK: destroy_value
// CHECK: [[ERROR3]]([[ERRPARAM3:%[0-9]+]] : @owned $any Error):
// CHECK: dealloc_stack [[STACK]]
// CHECK: unreachable
sil hidden [ossa] @nonTrivialForEachLoopUnrollTest : $@convention(thin) (@owned @callee_guaranteed @substituted <A> () -> @out A for <Int>, @owned @callee_guaranteed @substituted <A> () -> @out A for <Int>) -> () {
bb0(%0: @owned $@callee_guaranteed @substituted <A> () -> @out A for <Int>, %1: @owned $@callee_guaranteed @substituted <A> () -> @out A for <Int>):
%2 = integer_literal $Builtin.Word, 2
%3 = function_ref @_allocateUninitializedArray : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
%4 = apply %3<() -> Int>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
(%5, %6a) = destructure_tuple %4 : $(Array<()->Int>, Builtin.RawPointer)
%6 = mark_dependence %6a : $Builtin.RawPointer on %5 : $Array<() -> Int>
%7 = pointer_to_address %6 : $Builtin.RawPointer to [strict] $*@callee_guaranteed @substituted <A> () -> @out A for <Int>
store %0 to [init] %7 : $*@callee_guaranteed @substituted <A> () -> @out A for <Int>
%12 = integer_literal $Builtin.Word, 1
%13 = index_addr %7 : $*@callee_guaranteed @substituted <A> () -> @out A for <Int>, %12 : $Builtin.Word
store %1 to [init] %13 : $*@callee_guaranteed @substituted <A> () -> @out A for <Int>
%21 = begin_borrow %5 : $Array<()->Int>
%22 = alloc_stack $Array<()->Int>
%23 = store_borrow %21 to %22 : $*Array<()->Int>
%24 = function_ref @forEachBody2 : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <A> () -> @out A for <Int>) -> @error any Error
%25 = convert_function %24 : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <A> () -> @out A for <Int>) -> @error any Error to $@convention(thin) @noescape (@in_guaranteed @callee_guaranteed @substituted <A> () -> @out A for <Int>) -> @error any Error
%26 = thin_to_thick_function %25 : $@convention(thin) @noescape (@in_guaranteed @callee_guaranteed @substituted <A> () -> @out A for <Int>) -> @error any Error to $@noescape @callee_guaranteed (@in_guaranteed @callee_guaranteed @substituted <A> () -> @out A for <Int>) -> @error any Error
// A stub for Sequence.forEach(_:)
%30 = function_ref @forEach : $@convention(method) <τ_0_0 where τ_0_0 : Sequence> (@noescape @callee_guaranteed (@in_guaranteed τ_0_0.Element) -> @error Error, @in_guaranteed τ_0_0) -> @error Error
try_apply %30<[() -> Int]>(%26, %23) : $@convention(method) <τ_0_0 where τ_0_0 : Sequence> (@noescape @callee_guaranteed (@in_guaranteed τ_0_0.Element) -> @error Error, @in_guaranteed τ_0_0) -> @error Error, normal bb1, error bb2
bb1(%32 : $()):
end_borrow %23 : $*Array<() -> Int>
dealloc_stack %22 : $*Array<() -> Int>
end_borrow %21 : $Array<() -> Int>
destroy_value %5 : $Array<() -> Int>
%37 = tuple ()
return %37 : $()
bb2(%39 : @owned $Error):
unreachable
}
// CHECK-LABEL: @checkIndirectFixLifetimeUsesAreIgnored
// CHECK-NOT: function_ref @forEach : $@convention(method) <τ_0_0 where τ_0_0 : Sequence> (@noescape @callee_guaranteed (@in_guaranteed τ_0_0.Element) -> @error any Error, @in_guaranteed τ_0_0) -> @error any Error
// CHECK: end sil function 'checkIndirectFixLifetimeUsesAreIgnored'
sil hidden [ossa] @checkIndirectFixLifetimeUsesAreIgnored : $@convention(thin) () -> () {
bb0:
%0 = integer_literal $Builtin.Word, 2
%1 = function_ref @_allocateUninitializedArray : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
%2 = apply %1<Builtin.Int64>(%0) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
(%3, %4a) = destructure_tuple %2 : $(Array<Builtin.Int64>, Builtin.RawPointer)
%4 = mark_dependence %4a : $Builtin.RawPointer on %3 : $Array<Builtin.Int64>
%5 = pointer_to_address %4 : $Builtin.RawPointer to [strict] $*Builtin.Int64
%6 = integer_literal $Builtin.Int64, 15
store %6 to [trivial] %5 : $*Builtin.Int64
%12 = integer_literal $Builtin.Word, 1
%13 = index_addr %5 : $*Builtin.Int64, %12 : $Builtin.Word
%14 = integer_literal $Builtin.Int64, 27
store %14 to [trivial] %13 : $*Builtin.Int64
%21 = begin_borrow %3 : $Array<Builtin.Int64>
%22 = alloc_stack $Array<Builtin.Int64>
%23 = store_borrow %21 to %22 : $*Array<Builtin.Int64>
%24 = function_ref @forEachBody : $@convention(thin) (@in_guaranteed Builtin.Int64) -> @error Error
%25 = convert_function %24 : $@convention(thin) (@in_guaranteed Builtin.Int64) -> @error Error to $@convention(thin) @noescape (@in_guaranteed Builtin.Int64) -> @error Error
%26 = thin_to_thick_function %25 : $@convention(thin) @noescape (@in_guaranteed Builtin.Int64) -> @error Error to $@noescape @callee_guaranteed (@in_guaranteed Builtin.Int64) -> @error Error
// A stub for Sequence.forEach(_:)
%30 = function_ref @forEach : $@convention(method) <τ_0_0 where τ_0_0 : Sequence> (@noescape @callee_guaranteed (@in_guaranteed τ_0_0.Element) -> @error Error, @in_guaranteed τ_0_0) -> @error Error
try_apply %30<[Builtin.Int64]>(%26, %23) : $@convention(method) <τ_0_0 where τ_0_0 : Sequence> (@noescape @callee_guaranteed (@in_guaranteed τ_0_0.Element) -> @error Error, @in_guaranteed τ_0_0) -> @error Error, normal bb1, error bb2
bb1(%32 : $()):
end_borrow %23 : $*Array<Builtin.Int64>
// An indirect fixLifetime use
dealloc_stack %22 : $*Array<Builtin.Int64>
%33 = alloc_stack $Array<Builtin.Int64>
%34 = store_borrow %21 to %33 : $*Array<Builtin.Int64>
fix_lifetime %34 : $*Array<Builtin.Int64>
end_borrow %34 : $*Array<Builtin.Int64>
dealloc_stack %33 : $*Array<Builtin.Int64>
end_borrow %21 : $Array<Builtin.Int64>
destroy_value %3 : $Array<Builtin.Int64>
%37 = tuple ()
return %37 : $()
bb2(%39 : @owned $Error):
unreachable
}
// CHECK-LABEL: @testUnrollOfArrayWithPhiArguments
// CHECK-NOT: function_ref @forEach : $@convention(method) <τ_0_0 where τ_0_0 : Sequence> (@noescape @callee_guaranteed (@in_guaranteed τ_0_0.Element) -> @error any Error, @in_guaranteed τ_0_0) -> @error any Error
// CHECK: end sil function 'testUnrollOfArrayWithPhiArguments'
sil hidden [ossa] @testUnrollOfArrayWithPhiArguments : $@convention(thin) () -> () {
bb0:
%0 = integer_literal $Builtin.Int64, 57
br bb1(%0 : $Builtin.Int64)
bb1(%arg : $Builtin.Int64):
%10 = integer_literal $Builtin.Word, 1
%11 = function_ref @_allocateUninitializedArray : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
%12 = apply %11<Builtin.Int64>(%10) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
(%13, %14a) = destructure_tuple %12 : $(Array<Builtin.Int64>, Builtin.RawPointer)
%14 = mark_dependence %14a : $Builtin.RawPointer on %13 : $Array<Builtin.Int64>
%15 = pointer_to_address %14 : $Builtin.RawPointer to [strict] $*Builtin.Int64
store %arg to [trivial] %15 : $*Builtin.Int64
br bb2(%arg : $Builtin.Int64)
bb2(%arg2 : $Builtin.Int64):
%21 = begin_borrow %13 : $Array<Builtin.Int64>
%22 = alloc_stack $Array<Builtin.Int64>
%23 = store_borrow %21 to %22 : $*Array<Builtin.Int64>
%24 = function_ref @forEachBody : $@convention(thin) (@in_guaranteed Builtin.Int64) -> @error Error
%25 = convert_function %24 : $@convention(thin) (@in_guaranteed Builtin.Int64) -> @error Error to $@convention(thin) @noescape (@in_guaranteed Builtin.Int64) -> @error Error
%26 = thin_to_thick_function %25 : $@convention(thin) @noescape (@in_guaranteed Builtin.Int64) -> @error Error to $@noescape @callee_guaranteed (@in_guaranteed Builtin.Int64) -> @error Error
// A stub for Sequence.forEach(_:)
%30 = function_ref @forEach : $@convention(method) <τ_0_0 where τ_0_0 : Sequence> (@noescape @callee_guaranteed (@in_guaranteed τ_0_0.Element) -> @error Error, @in_guaranteed τ_0_0) -> @error Error
try_apply %30<[Builtin.Int64]>(%26, %23) : $@convention(method) <τ_0_0 where τ_0_0 : Sequence> (@noescape @callee_guaranteed (@in_guaranteed τ_0_0.Element) -> @error Error, @in_guaranteed τ_0_0) -> @error Error, normal bb3, error bb4
bb3(%32 : $()):
end_borrow %23 : $*Array<Builtin.Int64>
dealloc_stack %22 : $*Array<Builtin.Int64>
end_borrow %21 : $Array<Builtin.Int64>
destroy_value %13 : $Array<Builtin.Int64>
%37 = tuple ()
return %37 : $()
bb4(%39 : @owned $Error):
unreachable
}