Files
swift-mirror/test/SILOptimizer/partial_apply_simplification.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

213 lines
11 KiB
Plaintext

// RUN: %target-sil-opt -sil-print-types -enable-sil-verify-all %s -partial-apply-simplification | %FileCheck %s
import Swift
// CHECK-LABEL: sil private @closure_common_uses
// CHECK-SAME: : $@convention(method) (Int, @guaranteed { let Int }) -> Int {
// CHECK: bb0([[X:%.*]] : $Int, [[BOX:%.*]] : ${ let Int }):
// CHECK-NEXT: [[BOX_0:%.*]] = project_box [[BOX]] : ${ let Int }, 0
// CHECK-NEXT: [[Y:%.*]] = load [[BOX_0]] : $*Int
// CHECK-NEXT: return [[Y]]
sil private @closure_common_uses : $@convention(thin) (Int, Int) -> Int {
entry(%x : $Int, %y : $Int):
return %y : $Int
}
// CHECK-LABEL: sil @closure_common_uses_user_a
// CHECK: bb0([[Y:%.*]] : $Int):
// CHECK: [[F:%.*]] = function_ref @closure_common_uses
// CHECK-NEXT: [[BOX:%.*]] = alloc_box [reflection] ${ let Int }
// CHECK-NEXT: [[BOX_0:%.*]] = project_box [[BOX]] : ${ let Int }, 0
// CHECK-NEXT: store [[Y]] to [[BOX_0]]
// CHECK-NEXT: [[C:%.*]] = partial_apply [callee_guaranteed] [[F]]([[BOX]])
sil @closure_common_uses_user_a : $@convention(thin) (Int) -> @owned @callee_guaranteed (Int) -> Int {
entry(%y : $Int):
%f = function_ref @closure_common_uses : $@convention(thin) (Int, Int) -> Int
%c = partial_apply [callee_guaranteed] %f(%y) : $@convention(thin) (Int, Int) -> Int
return %c : $@callee_guaranteed (Int) -> Int
}
// CHECK-LABEL: sil @closure_common_uses_user_b
// CHECK: bb0([[Y:%.*]] : $Int):
// CHECK: [[F:%.*]] = function_ref @closure_common_uses
// CHECK-NEXT: [[BOX:%.*]] = alloc_box [reflection] ${ let Int }
// CHECK-NEXT: [[BOX_0:%.*]] = project_box [[BOX]] : ${ let Int }, 0
// CHECK-NEXT: store [[Y]] to [[BOX_0]]
// CHECK-NEXT: [[C:%.*]] = partial_apply [callee_guaranteed] [[F]]([[BOX]])
sil @closure_common_uses_user_b : $@convention(thin) (Int) -> @owned @callee_guaranteed (Int) -> Int {
entry(%y : $Int):
%f = function_ref @closure_common_uses : $@convention(thin) (Int, Int) -> Int
%c = partial_apply [callee_guaranteed] %f(%y) : $@convention(thin) (Int, Int) -> Int
return %c : $@callee_guaranteed (Int) -> Int
}
// CHECK-LABEL: sil private @closure_common_uses_owned
// CHECK-SAME: : $@convention(method) (Int, @owned { let Int }) -> Int {
// CHECK: bb0([[X:%.*]] : $Int, [[BOX:%.*]] : ${ let Int }):
// CHECK-NEXT: [[BOX_0:%.*]] = project_box [[BOX]] : ${ let Int }, 0
// CHECK-NEXT: [[Y:%.*]] = load [[BOX_0]] : $*Int
// CHECK-NEXT: strong_release [[BOX]]
// CHECK-NEXT: return [[Y]]
sil private @closure_common_uses_owned : $@convention(thin) (Int, Int) -> Int {
entry(%x : $Int, %y : $Int):
return %y : $Int
}
sil @closure_common_uses_owned_user_a : $@convention(thin) (Int) -> @owned @callee_owned (Int) -> Int {
entry(%y : $Int):
%f = function_ref @closure_common_uses_owned : $@convention(thin) (Int, Int) -> Int
%c = partial_apply %f(%y) : $@convention(thin) (Int, Int) -> Int
return %c : $@callee_owned (Int) -> Int
}
sil @closure_common_uses_owned_user_b : $@convention(thin) (Int) -> @owned @callee_owned (Int) -> Int {
entry(%y : $Int):
%f = function_ref @closure_common_uses_owned : $@convention(thin) (Int, Int) -> Int
%c = partial_apply %f(%y) : $@convention(thin) (Int, Int) -> Int
return %c : $@callee_owned (Int) -> Int
}
// CHECK-LABEL: sil private @closure_out_param
// CHECK-SAME: : $@convention(method) (Int, @guaranteed { let Int }) -> @out Int {
// CHECK: bb0([[R:%.*]] : $*Int, [[X:%.*]] : $Int, [[BOX:%.*]] : ${ let Int }):
// CHECK-NEXT: [[BOX_0:%.*]] = project_box [[BOX]] : ${ let Int }, 0
// CHECK-NEXT: [[Y:%.*]] = load [[BOX_0]] : $*Int
// CHECK-NEXT: store [[Y]] to [[R]]
// CHECK-NEXT: return
sil private @closure_out_param : $@convention(thin) (Int, Int) -> @out Int {
entry(%r : $*Int, %x : $Int, %y : $Int):
store %y to %r : $*Int
return undef : $()
}
// CHECK-LABEL: sil @closure_out_param_user
// CHECK: bb0([[Y:%.*]] : $Int):
// CHECK: [[F:%.*]] = function_ref @closure_out_param
// CHECK-NEXT: [[BOX:%.*]] = alloc_box [reflection] ${ let Int }
// CHECK-NEXT: [[BOX_0:%.*]] = project_box [[BOX]] : ${ let Int }, 0
// CHECK-NEXT: store [[Y]] to [[BOX_0]]
// CHECK-NEXT: [[C:%.*]] = partial_apply [callee_guaranteed] [[F]]([[BOX]])
sil @closure_out_param_user : $@convention(thin) (Int) -> @owned @callee_guaranteed (Int) -> @out Int {
entry(%y : $Int):
%f = function_ref @closure_out_param : $@convention(thin) (Int, Int) -> @out Int
%c = partial_apply [callee_guaranteed] %f(%y) : $@convention(thin) (Int, Int) -> @out Int
return %c : $@callee_guaranteed (Int) -> @out Int
}
sil @add : $@convention(thin) (Int, Int) -> Int
// CHECK-LABEL: sil private @closure_multi_capture
// CHECK-SAME: : $@convention(method) (Int, @guaranteed { let (Int, Int) }) -> Int
// CHECK: bb0([[X:%.*]] : $Int, [[YZ:%.*]] : ${ let (Int, Int) }):
// CHECK-NEXT: [[BOX_PROJ:%.*]] = project_box [[YZ]] :
// CHECK-NEXT: [[BOX_0:%.*]] = tuple_element_addr [[BOX_PROJ]] : {{.*}}, 0
// CHECK-NEXT: [[Y:%.*]] = load [[BOX_0]] : $*Int
// CHECK-NEXT: [[BOX_PROJ:%.*]] = project_box [[YZ]] :
// CHECK-NEXT: [[BOX_1:%.*]] = tuple_element_addr [[BOX_PROJ]] : {{.*}}, 1
// CHECK-NEXT: [[Z:%.*]] = load [[BOX_1]] : $*Int
// CHECK: [[ADD:%.*]] = function_ref @add
// CHECK-NEXT: apply [[ADD]]([[Y]], [[Z]])
sil private @closure_multi_capture : $@convention(thin) (Int, Int, Int) -> Int {
entry(%x : $Int, %y : $Int, %z : $Int):
%f = function_ref @add : $@convention(thin) (Int, Int) -> Int
%r = apply %f(%y, %z) : $@convention(thin) (Int, Int) -> Int
return %r : $Int
}
// CHECK-LABEL: sil @closure_multi_capture_user
// CHECK: bb0([[Y:%.*]] : $Int, [[Z:%.*]] : $Int):
// CHECK: [[BOX:%.*]] = alloc_box [reflection] ${ let (Int, Int) }
// CHECK: [[BOX_PROJ:%.*]] = project_box [[BOX]]
// CHECK: [[BOX_0:%.*]] = tuple_element_addr [[BOX_PROJ]] : {{.*}}, 0
// CHECK: store [[Y]] to [[BOX_0]]
// CHECK: [[BOX_1:%.*]] = tuple_element_addr [[BOX_PROJ]] : {{.*}}, 1
// CHECK: store [[Z]] to [[BOX_1]]
// CHECK: [[RESULT:%.*]] = partial_apply [callee_guaranteed] {{%.*}}([[BOX]])
// CHECK: return [[RESULT]]
sil @closure_multi_capture_user : $@convention(thin) (Int, Int) -> @owned @callee_guaranteed (Int) -> Int {
entry(%y : $Int, %z : $Int):
%f = function_ref @closure_multi_capture : $@convention(thin) (Int, Int, Int) -> Int
%c = partial_apply [callee_guaranteed] %f(%y, %z) : $@convention(thin) (Int, Int, Int) -> Int
return %c : $@callee_guaranteed (Int) -> Int
}
// CHECK-LABEL: sil private @closure_nonescaping
// CHECK-SAME: : $@convention(method) (Int, @in_guaranteed (Int, Int)) -> Int
// CHECK: bb0([[X:%.*]] : $Int, [[YZ:%.*]] : $*(Int, Int)):
// CHECK: [[BOX_0:%.*]] = tuple_element_addr [[YZ]] : {{.*}}, 0
// CHECK-NEXT: [[Y:%.*]] = load [[BOX_0]] : $*Int
// CHECK-NEXT: [[BOX_1:%.*]] = tuple_element_addr [[YZ]] : {{.*}}, 1
// CHECK-NEXT: [[Z:%.*]] = load [[BOX_1]] : $*Int
// CHECK: [[ADD:%.*]] = function_ref @add
// CHECK-NEXT: apply [[ADD]]([[Y]], [[Z]])
sil private @closure_nonescaping : $@convention(thin) (Int, Int, Int) -> Int {
entry(%x : $Int, %y : $Int, %z : $Int):
%f = function_ref @add : $@convention(thin) (Int, Int) -> Int
%r = apply %f(%y, %z) : $@convention(thin) (Int, Int) -> Int
return %r : $Int
}
sil @closure_nonescaping_consumer : $@convention(thin) (@noescape @callee_guaranteed (Int) -> Int, Int) -> Int {
entry(%f : $@noescape @callee_guaranteed (Int) -> Int, %x : $Int):
%y = apply %f(%x) : $@noescape @callee_guaranteed (Int) -> Int
return %y : $Int
}
// CHECK-LABEL: sil @closure_nonescaping_user
// CHECK: bb0([[X:%.*]] : $Int, [[Y:%.*]] : $Int, [[Z:%.*]] : $Int):
// CHECK: [[F:%.*]] = function_ref @closure_nonescaping
// CHECK: [[CONTEXT:%.*]] = alloc_stack $(Int, Int)
// CHECK: [[CONTEXT_Y:%.*]] = tuple_element_addr [[CONTEXT]] {{.*}}, 0
// CHECK: store [[Y]] to [[CONTEXT_Y]]
// CHECK: [[CONTEXT_Z:%.*]] = tuple_element_addr [[CONTEXT]] {{.*}}, 1
// CHECK: store [[Z]] to [[CONTEXT_Z]]
// CHECK: [[CLOSURE:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[F]]([[CONTEXT]])
// CHECK: [[CONSUMER:%.*]] = function_ref @closure_nonescaping_consumer
// CHECK: apply [[CONSUMER]]([[CLOSURE]], [[X]])
sil @closure_nonescaping_user : $@convention(thin) (Int, Int, Int) -> Int {
entry(%x : $Int, %y : $Int, %z : $Int):
%f = function_ref @closure_nonescaping : $@convention(thin) (Int, Int, Int) -> Int
%c = partial_apply [callee_guaranteed] [on_stack] %f(%y, %z) : $@convention(thin) (Int, Int, Int) -> Int
%g = function_ref @closure_nonescaping_consumer : $@convention(thin) (@noescape @callee_guaranteed (Int) -> Int, Int) -> Int
%r = apply %g(%c, %x) : $@convention(thin) (@noescape @callee_guaranteed (Int) -> Int, Int) -> Int
dealloc_stack %c : $@noescape @callee_guaranteed (Int) -> Int
return %r : $Int
}
// CHECK-LABEL: sil @closure_nonescaping_full_apply
// CHECK: bb0([[X:%.*]] : $Int, [[Y:%.*]] : $Int, [[Z:%.*]] : $Int):
// CHECK: [[F:%.*]] = function_ref @closure_nonescaping
// CHECK: [[CONTEXT:%.*]] = alloc_stack $(Int, Int)
// CHECK: [[CONTEXT_Y:%.*]] = tuple_element_addr [[CONTEXT]] {{.*}}, 0
// CHECK: store [[Y]] to [[CONTEXT_Y]]
// CHECK: [[CONTEXT_Z:%.*]] = tuple_element_addr [[CONTEXT]] {{.*}}, 1
// CHECK: store [[Z]] to [[CONTEXT_Z]]
// CHECK: [[CLOSURE:%.*]] = apply [[F]]([[X]], [[CONTEXT]])
sil @closure_nonescaping_full_apply : $@convention(thin) (Int, Int, Int) -> Int {
entry(%x : $Int, %y : $Int, %z : $Int):
%f = function_ref @closure_nonescaping : $@convention(thin) (Int, Int, Int) -> Int
%r = apply %f(%x, %y, %z) : $@convention(thin) (Int, Int, Int) -> Int
return %r : $Int
}
// CHECK-LABEL: sil private @closure_nonescaping_convention_change
// CHECK-SAME: : $@convention(method) (Int, @in_guaranteed Int) -> Int {
sil private @closure_nonescaping_convention_change : $@convention(thin) (Int, @in_guaranteed Int) -> Int {
entry(%x : $Int, %y : $*Int):
%f = function_ref @add : $@convention(thin) (Int, Int) -> Int
%z = load %y : $*Int
%r = apply %f(%x, %z) : $@convention(thin) (Int, Int) -> Int
return %r : $Int
}
sil @closure_nonescaping_convention_change_user : $@convention(thin) (Int, @in_guaranteed Int) -> Int {
entry(%x : $Int, %y : $*Int):
%f = function_ref @closure_nonescaping_convention_change : $@convention(thin) (Int, @in_guaranteed Int) -> Int
%c = partial_apply [callee_guaranteed] [on_stack] %f(%y) : $@convention(thin) (Int, @in_guaranteed Int) -> Int
%g = function_ref @closure_nonescaping_consumer : $@convention(thin) (@noescape @callee_guaranteed (Int) -> Int, Int) -> Int
%r = apply %g(%c, %x) : $@convention(thin) (@noescape @callee_guaranteed (Int) -> Int, Int) -> Int
dealloc_stack %c : $@noescape @callee_guaranteed (Int) -> Int
return %r : $Int
}