mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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.
391 lines
8.3 KiB
Plaintext
391 lines
8.3 KiB
Plaintext
// RUN: %target-sil-opt -sil-print-types -sil-print-debuginfo -enable-sil-verify-all %s -condition-forwarding | %FileCheck %s
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
sil_stage canonical
|
|
|
|
enum E { case A, B }
|
|
|
|
enum E3 { case A, B, C }
|
|
|
|
class C {
|
|
@_hasStorage var x : Builtin.Int64
|
|
init()
|
|
}
|
|
|
|
sil @callee : $@convention(thin) () -> ()
|
|
sil @use_enum : $@convention(thin) (E) -> ()
|
|
sil @use_int : $@convention(thin) (Builtin.Int64) -> ()
|
|
|
|
// CHECK-LABEL: sil @simple_forwarding
|
|
// CHECK: bb0({{.*}}):
|
|
// CHECK-NEXT: br bb3
|
|
// CHECK: bb1:
|
|
// CHECK: br bb4,
|
|
// CHECK: bb2:
|
|
// CHECK: br bb5,
|
|
// CHECK: bb3:
|
|
// CHECK: apply
|
|
// CHECK: cond_br %0, bb1, bb2
|
|
// CHECK: bb4:
|
|
// CHECK: br bb6
|
|
// CHECK: bb5:
|
|
// CHECK: br bb6
|
|
// CHECK: bb6:
|
|
// CHECK: return
|
|
sil @simple_forwarding : $@convention(thin) (Builtin.Int1) -> () {
|
|
bb0(%0 : $Builtin.Int1):
|
|
cond_br %0, bb1, bb2
|
|
|
|
bb1:
|
|
%1 = enum $E, #E.A!enumelt
|
|
br bb3(%1 : $E)
|
|
|
|
bb2:
|
|
%2 = enum $E, #E.B!enumelt
|
|
br bb3(%2 : $E)
|
|
|
|
bb3(%14 : $E):
|
|
%15 = function_ref @callee : $@convention(thin) () -> ()
|
|
%16 = apply %15() : $@convention(thin) () -> ()
|
|
switch_enum %14 : $E, case #E.A!enumelt: bb4, case #E.B!enumelt: bb5
|
|
|
|
bb4:
|
|
br bb6
|
|
|
|
bb5:
|
|
br bb6
|
|
|
|
bb6:
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @closed_range_iterator_example
|
|
// CHECK: bb0({{.*}}):
|
|
// CHECK-NEXT: br bb3
|
|
// CHECK: bb1:
|
|
// CHECK: [[PL:%[0-9]+]] = struct $Int64
|
|
// CHECK: br bb4([[PL]] : $Int64)
|
|
// CHECK: bb2:
|
|
// CHECK: [[O:%[0-9]+]] = enum $Optional<Int64>
|
|
// CHECK: br bb5([[O]] : $Optional<Int64>)
|
|
// CHECK: bb3:
|
|
// CHECK: apply
|
|
// CHECK: cond_br %0, bb1, bb2
|
|
// CHECK: bb4({{%[0-9]+}} : $Int64):
|
|
// CHECK: br bb6
|
|
// CHECK: bb5([[O2:%[0-9]+]] : $Optional<Int64>):
|
|
// CHECK: br bb6([[O2]] : $Optional<Int64>)
|
|
// CHECK: bb6
|
|
// CHECK: return
|
|
sil @closed_range_iterator_example : $@convention(thin) (Builtin.Int1, Builtin.Int64) -> Optional<Int64> {
|
|
bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int64):
|
|
cond_br %0, bb1, bb2
|
|
|
|
bb1:
|
|
%3 = integer_literal $Builtin.Int64, 1
|
|
%4 = integer_literal $Builtin.Int1, -1
|
|
%5 = builtin "sadd_with_overflow_Int64"(%1 : $Builtin.Int64, %3 : $Builtin.Int64, %4 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1)
|
|
%6 = tuple_extract %5 : $(Builtin.Int64, Builtin.Int1), 0
|
|
%7 = tuple_extract %5 : $(Builtin.Int64, Builtin.Int1), 1
|
|
cond_fail %7 : $Builtin.Int1
|
|
%9 = struct $Int64 (%6 : $Builtin.Int64)
|
|
%10 = enum $Optional<Int64>, #Optional.some!enumelt, %9 : $Int64
|
|
br bb3(%10 : $Optional<Int64>)
|
|
|
|
bb2:
|
|
%12 = enum $Optional<Int64>, #Optional.none!enumelt
|
|
br bb3(%12 : $Optional<Int64>)
|
|
|
|
|
|
bb3(%14 : $Optional<Int64>):
|
|
debug_value %14 : $Optional<Int64>
|
|
%15 = function_ref @callee : $@convention(thin) () -> ()
|
|
%16 = apply %15() : $@convention(thin) () -> ()
|
|
switch_enum %14 : $Optional<Int64>, case #Optional.some!enumelt: bb4, case #Optional.none!enumelt: bb5
|
|
|
|
|
|
bb4(%18 : $Int64):
|
|
%19 = enum $Optional<Int64>, #Optional.some!enumelt, %18 : $Int64
|
|
br bb6(%19 : $Optional<Int64>)
|
|
|
|
bb5:
|
|
br bb6(%14 : $Optional<Int64>)
|
|
|
|
|
|
bb6(%22 : $Optional<Int64>):
|
|
return %22 : $Optional<Int64>
|
|
}
|
|
|
|
// CHECK-LABEL: sil @simple_switch_enum_forwarding
|
|
// CHECK: bb0({{.*}}):
|
|
// CHECK-NEXT: br bb3
|
|
// CHECK: bb1:
|
|
// CHECK: br bb4,
|
|
// CHECK: bb2:
|
|
// CHECK: br bb5,
|
|
// CHECK: bb3:
|
|
// CHECK: apply
|
|
// CHECK: switch_enum %0 : $E3, case #E3.A!enumelt: bb1, default bb2
|
|
// CHECK: bb4:
|
|
// CHECK: br bb6
|
|
// CHECK: bb5:
|
|
// CHECK: br bb6
|
|
// CHECK: bb6:
|
|
// CHECK: return
|
|
sil @simple_switch_enum_forwarding : $@convention(thin) (E3) -> () {
|
|
bb0(%0 : $E3):
|
|
switch_enum %0 : $E3, case #E3.A!enumelt: bb1, default bb2
|
|
|
|
bb1:
|
|
%1 = enum $E, #E.A!enumelt
|
|
br bb3(%1 : $E)
|
|
|
|
bb2:
|
|
%2 = enum $E, #E.B!enumelt
|
|
br bb3(%2 : $E)
|
|
|
|
bb3(%14 : $E):
|
|
%15 = function_ref @callee : $@convention(thin) () -> ()
|
|
%16 = apply %15() : $@convention(thin) () -> ()
|
|
switch_enum %14 : $E, case #E.A!enumelt: bb4, case #E.B!enumelt: bb5
|
|
|
|
bb4:
|
|
br bb6
|
|
|
|
bb5:
|
|
br bb6
|
|
|
|
bb6:
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @no_forwarding_side_effect_inst
|
|
// CHECK: bb0({{.*}}):
|
|
// CHECK: cond_br %0
|
|
// CHECK: bb3({{.*}}):
|
|
// CHECK: switch_enum
|
|
// CHECK: bb6
|
|
// CHECK: return
|
|
sil @no_forwarding_side_effect_inst : $@convention(thin) (Builtin.Int1, C) -> () {
|
|
bb0(%0 : $Builtin.Int1, %1 : $C):
|
|
%e = ref_element_addr %1 : $C, #C.x
|
|
cond_br %0, bb1, bb2
|
|
|
|
bb1:
|
|
%2 = enum $E, #E.A!enumelt
|
|
br bb3(%2 : $E)
|
|
|
|
bb2:
|
|
%3 = enum $E, #E.B!enumelt
|
|
%4 = load %e : $*Builtin.Int64
|
|
br bb3(%3 : $E)
|
|
|
|
bb3(%14 : $E):
|
|
%15 = function_ref @callee : $@convention(thin) () -> ()
|
|
%16 = apply %15() : $@convention(thin) () -> ()
|
|
switch_enum %14 : $E, case #E.A!enumelt: bb4, case #E.B!enumelt: bb5
|
|
|
|
bb4:
|
|
br bb6
|
|
|
|
bb5:
|
|
br bb6
|
|
|
|
bb6:
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @no_forwarding_second_enum_use
|
|
// CHECK: bb0({{.*}}):
|
|
// CHECK: cond_br %0
|
|
// CHECK: bb3({{.*}}):
|
|
// CHECK: switch_enum
|
|
// CHECK: bb6
|
|
// CHECK: return
|
|
sil @no_forwarding_second_enum_use : $@convention(thin) (Builtin.Int1) -> () {
|
|
bb0(%0 : $Builtin.Int1):
|
|
cond_br %0, bb1, bb2
|
|
|
|
bb1:
|
|
%1 = enum $E, #E.A!enumelt
|
|
br bb3(%1 : $E)
|
|
|
|
bb2:
|
|
%2 = enum $E, #E.B!enumelt
|
|
br bb3(%2 : $E)
|
|
|
|
bb3(%14 : $E):
|
|
%15 = function_ref @use_enum : $@convention(thin) (E) -> ()
|
|
%16 = apply %15(%14) : $@convention(thin) (E) -> ()
|
|
switch_enum %14 : $E, case #E.A!enumelt: bb4, case #E.B!enumelt: bb5
|
|
|
|
bb4:
|
|
br bb6
|
|
|
|
bb5:
|
|
br bb6
|
|
|
|
bb6:
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @no_forwarding_bad_control_flow
|
|
// CHECK: bb0({{.*}}):
|
|
// CHECK: cond_br %0
|
|
// CHECK: bb3({{.*}}):
|
|
// CHECK: switch_enum
|
|
// CHECK: bb6
|
|
// CHECK: return
|
|
sil @no_forwarding_bad_control_flow : $@convention(thin) (Builtin.Int1) -> () {
|
|
bb0(%0 : $Builtin.Int1):
|
|
cond_br %0, bb9, bb2
|
|
|
|
bb1:
|
|
%1 = enum $E, #E.A!enumelt
|
|
br bb3(%1 : $E)
|
|
|
|
bb2:
|
|
%2 = enum $E, #E.B!enumelt
|
|
br bb3(%2 : $E)
|
|
|
|
bb3(%14 : $E):
|
|
%15 = function_ref @callee : $@convention(thin) () -> ()
|
|
%16 = apply %15() : $@convention(thin) () -> ()
|
|
switch_enum %14 : $E, case #E.A!enumelt: bb4, case #E.B!enumelt: bb5
|
|
|
|
bb4:
|
|
br bb7
|
|
|
|
bb5:
|
|
cond_br undef, bb6, bb10
|
|
|
|
bb6:
|
|
br bb1
|
|
|
|
bb7:
|
|
br bb8
|
|
|
|
bb8:
|
|
%r = tuple ()
|
|
return %r : $()
|
|
|
|
bb9:
|
|
br bb1
|
|
|
|
bb10:
|
|
br bb7
|
|
}
|
|
|
|
// CHECK-LABEL: sil @no_forwarding_multiple_block_args
|
|
// CHECK: bb0({{.*}}):
|
|
// CHECK: cond_br %0
|
|
// CHECK: bb3({{.*}}):
|
|
// CHECK: switch_enum
|
|
// CHECK: bb6
|
|
// CHECK: return
|
|
sil @no_forwarding_multiple_block_args : $@convention(thin) (Builtin.Int1) -> () {
|
|
bb0(%0 : $Builtin.Int1):
|
|
cond_br %0, bb1, bb2
|
|
|
|
bb1:
|
|
%i1 = integer_literal $Builtin.Int64, 1
|
|
%1 = enum $E, #E.A!enumelt
|
|
br bb3(%1 : $E, %i1 : $Builtin.Int64)
|
|
|
|
bb2:
|
|
%i2 = integer_literal $Builtin.Int64, 2
|
|
%2 = enum $E, #E.B!enumelt
|
|
br bb3(%2 : $E, %i2 : $Builtin.Int64)
|
|
|
|
bb3(%14 : $E, %i3 : $Builtin.Int64):
|
|
%15 = function_ref @use_int : $@convention(thin) (Builtin.Int64) -> ()
|
|
%16 = apply %15(%i3) : $@convention(thin) (Builtin.Int64) -> ()
|
|
switch_enum %14 : $E, case #E.A!enumelt: bb4, case #E.B!enumelt: bb5
|
|
|
|
bb4:
|
|
br bb6
|
|
|
|
bb5:
|
|
br bb6
|
|
|
|
bb6:
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @no_forwarding_additional_successor
|
|
// CHECK: bb0({{.*}}):
|
|
// CHECK: switch_enum %0
|
|
// CHECK: bb3({{.*}}):
|
|
// CHECK: switch_enum
|
|
// CHECK: bb6
|
|
// CHECK: return
|
|
sil @no_forwarding_additional_successor : $@convention(thin) (E3) -> () {
|
|
bb0(%0 : $E3):
|
|
switch_enum %0 : $E3, case #E3.A!enumelt: bb1, case #E3.B!enumelt: bb2, case #E3.C!enumelt: bb6
|
|
|
|
bb1:
|
|
%1 = enum $E, #E.A!enumelt
|
|
br bb3(%1 : $E)
|
|
|
|
bb2:
|
|
%2 = enum $E, #E.B!enumelt
|
|
br bb3(%2 : $E)
|
|
|
|
bb3(%14 : $E):
|
|
%15 = function_ref @callee : $@convention(thin) () -> ()
|
|
%16 = apply %15() : $@convention(thin) () -> ()
|
|
switch_enum %14 : $E, case #E.A!enumelt: bb4, case #E.B!enumelt: bb5
|
|
|
|
bb4:
|
|
br bb7
|
|
|
|
bb5:
|
|
br bb7
|
|
|
|
bb6:
|
|
br bb7
|
|
|
|
bb7:
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @forwarding_second_enum_use :
|
|
// CHECK-NOT: switch_enum
|
|
// CHECK-LABEL:} // end sil function 'forwarding_second_enum_use'
|
|
sil @forwarding_second_enum_use : $@convention(thin) (Builtin.Int1) -> () {
|
|
bb0(%0 : $Builtin.Int1):
|
|
cond_br %0, bb1, bb2
|
|
|
|
bb1:
|
|
%1 = enum $E, #E.A!enumelt
|
|
br bb3(%1 : $E)
|
|
|
|
bb2:
|
|
%2 = enum $E, #E.B!enumelt
|
|
br bb3(%2 : $E)
|
|
|
|
bb3(%14 : $E):
|
|
switch_enum %14 : $E, case #E.A!enumelt: bb4, case #E.B!enumelt: bb5
|
|
|
|
bb4:
|
|
%15 = function_ref @use_enum : $@convention(thin) (E) -> ()
|
|
%16 = apply %15(%14) : $@convention(thin) (E) -> ()
|
|
br bb6
|
|
|
|
bb5:
|
|
br bb6
|
|
|
|
bb6:
|
|
%r = tuple ()
|
|
return %r : $()
|
|
}
|
|
|