blob: a61a35af226f7f61681c66b6abcbae06ce687e60 [file] [log] [blame]
// RUN: %target-sil-opt -enable-sil-verify-all %s -jumpthread-simplify-cfg | %FileCheck %s
// RUN: %target-sil-opt -enable-sil-verify-all %s -late-codemotion -jumpthread-simplify-cfg | %FileCheck %s --check-prefix=CHECK_WITH_CODEMOTION
sil_stage raw
import Builtin
import Swift
sil_global private @globalinit_token11 : $Builtin.Word
sil_global private @globalinit_token120 : $Builtin.Word
sil @globalinit_func11 : $@convention(thin) () -> ()
// CHECK: sil @a_method_to_simplify
sil @a_method_to_simplify : $@convention(thin) (Builtin.RawPointer, @owned Builtin.NativeObject, Builtin.Int32) -> Builtin.RawPointer {
bb0(%0 : $Builtin.RawPointer, %1 : $Builtin.NativeObject, %2 : $Builtin.Int32):
%4 = struct $UnsafeMutablePointer<UInt8> (%0 : $Builtin.RawPointer) // user: %37
strong_retain %1 : $Builtin.NativeObject // id: %5
strong_retain %1 : $Builtin.NativeObject // id: %6
strong_release %1 : $Builtin.NativeObject // id: %7
%8 = integer_literal $Builtin.Int1, 0 // user: %23
%10 = global_addr @globalinit_token11 : $*Builtin.Word // user: %11
%11 = address_to_pointer %10 : $*Builtin.Word to $Builtin.RawPointer // user: %14
%12 = function_ref @globalinit_func11 : $@convention(thin) () -> () // users: %26, %13
%14 = builtin "once"(%11 : $Builtin.RawPointer, %12 : $@convention(thin) () -> ()) : $()
%15 = alloc_stack $Int32 // users: %38, %40, %41
%16 = struct_element_addr %15 : $*Int32, #Int32._value // users: %28, %17
%17 = load %16 : $*Builtin.Int32 // user: %20
%18 = integer_literal $Builtin.Int32, -1 // user: %20
%20 = builtin "xor_Int32"(%17 : $Builtin.Int32, %18 : $Builtin.Int32) : $Builtin.Int32 // user: %22
%22 = builtin "and_Int32"(%2 : $Builtin.Int32, %20 : $Builtin.Int32) : $Builtin.Int32 // users: %30, %23
// CHECK-NOT: cond_br
cond_br %8, bb1, bb2(%22 : $Builtin.Int32) // id: %23
bb1: // Preds: bb0
%24 = global_addr @globalinit_token11 : $*Builtin.Word // user: %25
%25 = address_to_pointer %24 : $*Builtin.Word to $Builtin.RawPointer // user: %27
%27 = builtin "once"(%25 : $Builtin.RawPointer, %12 : $@convention(thin) () -> ()) : $()
%28 = load %16 : $*Builtin.Int32 // user: %30
// CHECK: [[VAR_21:%[0-9]+]] = builtin "and_Int32"
%30 = builtin "or_Int32"(%22 : $Builtin.Int32, %28 : $Builtin.Int32) : $Builtin.Int32 // user: %31
br bb2(%30 : $Builtin.Int32) // id: %31
bb2(%32 : $Builtin.Int32): // Preds: bb0 bb1
// CHECK-NOT: tuple
%33 = tuple () // user: %34
br bb3(%33 : $()) // id: %34
bb3(%35 : $()): // Preds: bb2
// CHECK-NEXT: struct $Int32 ([[VAR_21]] : $Builtin.Int32)
%36 = struct $Int32 (%32 : $Builtin.Int32) // user: %37
strong_retain %1 : $Builtin.NativeObject // id: %38
strong_release %1 : $Builtin.NativeObject // id: %39
strong_release %1 : $Builtin.NativeObject // id: %40
dealloc_stack %15 : $*Int32 // id: %41
// CHECK: return
return %0 : $Builtin.RawPointer
}
//CHECK-LABEL: remove_dead_args
//CHECK-NOT: br bb2([[VAR_21:%[0-9]+]] : $Bool)
//CHECK: bb2:
//CHECK-NEXT: tuple ()
//CHECK-NEXT: return
sil @remove_dead_args: $@convention(thin) (Int32) -> () {
bb0(%0 : $Int32):
%1 = integer_literal $Builtin.Int32, 37
%3 = struct_extract %0 : $Int32, #Int32._value
%4 = builtin "cmp_ne_Int32"(%3 : $Builtin.Int32, %1 : $Builtin.Int32) : $Builtin.Int1
%5 = struct $Bool (%4 : $Builtin.Int1)
cond_br %4, bb1, bb3
bb1:
%7 = integer_literal $Builtin.Int32, 42
%8 = builtin "cmp_ne_Int32"(%3 : $Builtin.Int32, %7 : $Builtin.Int32) : $Builtin.Int1
%9 = struct $Bool (%8 : $Builtin.Int1)
br bb2(%9 : $Bool)
bb3: // Preds: bb0
%13 = tuple()
br bb2(%5 : $Bool) // id: %14
// Remove this ARG.
bb2(%11 : $Bool): // Preds: bb1 bb3
%12 = tuple () // user: %13
return %12 : $() // id: %13
}
class A {}
//CHECK-LABEL: no_remove_mandatory_dead_args
//CHECK: checked_cast_br {{%.*}} : $AnyObject to $A, bb1
//CHECK-NOT: bb1
//CHECK: bb1([[VAR:%[0-9]+]] : $A)
//CHECK-NOT: [[VAR]]
//CHECK: return
sil @no_remove_mandatory_dead_args : $@convention(thin) (@owned AnyObject) -> Int32 {
bb0(%0 : $AnyObject):
checked_cast_br %0 : $AnyObject to $A, bb1, bb2 // id: %3
bb1(%1 : $A):
%2 = integer_literal $Builtin.Int32, 1
br bb3(%2 : $Builtin.Int32)
bb2:
%3 = integer_literal $Builtin.Int32, 0
br bb3(%3 : $Builtin.Int32)
bb3(%4 : $Builtin.Int32):
%5 = struct $Int32 (%4 : $Builtin.Int32)
strong_release %0 : $AnyObject
return %5 : $Int32
}
enum X {
case A
case B((Int32, Int32))
case C(Int32)
}
// CHECK-LABEL: simplify_switch_include_args
sil @simplify_switch_include_args : $@convention(thin) (Int32, Int32) -> Int32 {
bb0(%0 : $Int32, %1 : $Int32):
// CHECK: return %0 : $Int32
%2 = tuple (%0 : $Int32, %1 : $Int32) // user: %3
%3 = enum $X, #X.B!enumelt.1, %2 : $(Int32, Int32) // user: %4
switch_enum %3 : $X, case #X.A!enumelt: bb1, case #X.B!enumelt.1: bb3, case #X.C!enumelt.1: bb5 // id: %4
bb1: // Preds: bb0
br bb2 // id: %5
bb2: // Preds: bb1
%6 = integer_literal $Builtin.Int32, 0 // user: %7
%7 = struct $Int32 (%6 : $Builtin.Int32) // user: %8
br bb7(%7 : $Int32) // id: %8
bb3(%9 : $(Int32, Int32)): // Preds: bb0
%10 = tuple_extract %9 : $(Int32, Int32), 0 // user: %12
br bb4 // id: %11
bb4: // Preds: bb3
br bb7(%10 : $Int32) // id: %12
bb5(%13 : $Int32): // Preds: bb0
br bb6 // id: %14
bb6: // Preds: bb5
br bb7(%13 : $Int32) // id: %15
bb7(%16 : $Int32): // Preds: bb2 bb4 bb6
return %16 : $Int32 // id: %17
}
// CHECK-LABEL: simplify_switch_dont_include_args
sil @simplify_switch_dont_include_args : $@convention(thin) (Int32, Int32) -> Int32 {
bb0(%0 : $Int32, %1 : $Int32):
%2 = tuple (%0 : $Int32, %1 : $Int32) // user: %3
%3 = enum $X, #X.B!enumelt.1, %2 : $(Int32, Int32) // user: %4
switch_enum %3 : $X, case #X.A!enumelt: bb1, case #X.B!enumelt.1: bb3, case #X.C!enumelt.1: bb5 // id: %4
bb1: // Preds: bb0
br bb2 // id: %5
bb2: // Preds: bb1
%6 = integer_literal $Builtin.Int32, 0 // user: %7
%7 = struct $Int32 (%6 : $Builtin.Int32) // user: %8
br bb6
bb3(%9 : $(Int32, Int32)): // Preds: bb0
%10 = tuple_extract %9 : $(Int32, Int32), 0 // user: %12
br bb4 // id: %11
bb4: // Preds: bb3
br bb6 // id: %12
bb5:
br bb6
bb6:
return %0 : $Int32
}
// CHECK-LABEL: simplify_switch_dont_include_args_nested
sil @simplify_switch_dont_include_args_nested : $@convention(thin) (Int32, Int32, X) -> Int32 {
// CHECK: bb0
// CHECK: switch_enum %2
bb0(%0 : $Int32, %1 : $Int32, %2 : $X):
switch_enum %2 : $X, case #X.A!enumelt: bb3, case #X.B!enumelt.1: bb1, case #X.C!enumelt.1: bb5
// CHECK: bb1
// CHECK-NOT: switch_enum
bb1(%12: $(Int32, Int32)):
switch_enum %2 : $X, case #X.A!enumelt: bb6, case #X.B!enumelt.1: bb7, case #X.C!enumelt.1: bb8
bb2:
%6 = integer_literal $Builtin.Int32, 0
%7 = struct $Int32 (%6 : $Builtin.Int32)
br bb9(%7 : $Int32)
bb3:
%9 = integer_literal $Builtin.Int32, 1
%10 = struct $Int32 (%9 : $Builtin.Int32)
br bb4(%10 : $Int32)
bb4(%16 : $Int32):
br bb9(%16 : $Int32)
bb5(%18 : $Int32):
br bb9(%18 : $Int32)
bb6:
%20 = integer_literal $Builtin.Int32, 2
%21 = struct $Int32 (%20 : $Builtin.Int32)
br bb9(%21 : $Int32)
bb7:
%22 = integer_literal $Builtin.Int32, 3
%23 = struct $Int32 (%22 : $Builtin.Int32)
br bb9(%23 : $Int32)
bb8(%25 : $Int32):
br bb9(%25 : $Int32)
bb9(%27 : $Int32):
return %27 : $Int32
}
// CHECK-LABEL: simplify_switch_wrong_args
sil @simplify_switch_wrong_args : $@convention(thin) (Int32, Int32, X, Builtin.Int1) -> Int32 {
// CHECK: bb0
// CHECK: switch_enum %2
bb0(%0 : $Int32, %1 : $Int32, %2 : $X, %24 : $Builtin.Int1):
switch_enum %2 : $X, case #X.A!enumelt: bb3, case #X.B!enumelt.1: bb9, case #X.C!enumelt.1: bb10
bb9(%21 : $(Int32, Int32)):
%22 = tuple_extract %21 : $(Int32, Int32), 1
cond_br %24, bb1(%22 : $Int32), bb5(%22 : $Int32)
// CHECK: bb1
// CHECK-NOT: switch_enum
bb1(%12: $Int32):
switch_enum %2 : $X, case #X.A!enumelt: bb6, case #X.B!enumelt.1: bb7, case #X.C!enumelt.1: bb8
bb2:
%6 = integer_literal $Builtin.Int32, 0
%7 = struct $Int32 (%6 : $Builtin.Int32)
br bb5(%7 : $Int32)
bb3:
%9 = integer_literal $Builtin.Int32, 1
%10 = struct $Int32 (%9 : $Builtin.Int32)
br bb4(%10 : $Int32)
bb4(%16 : $Int32):
br bb5(%16 : $Int32)
bb10(%18 : $Int32):
br bb5(%18 : $Int32)
bb5(%19 : $Int32):
return %19 : $Int32
bb6:
%14 = integer_literal $Builtin.Int32, 2
%15 = struct $Int32 (%14 : $Builtin.Int32)
br bb5(%15 : $Int32)
bb7(%23 : $(Int32, Int32)):
%17 = tuple_extract %21 : $(Int32, Int32), 0
br bb5(%17 : $Int32)
bb8(%20 : $Int32):
br bb5(%20 : $Int32)
}
enum EA {
case cA
case cB(Int32)
case cC(Float)
}
// CHECK-LABEL: fold_unreachable_terminators1
sil @fold_unreachable_terminators1 : $@convention(thin) (EA) -> () {
// CHECK: bb0
// CHECK-NEXT: [[VAL:%[a-zA-Z0-9]+]] = tuple ()
// CHECK-NEXT: return [[VAL]]
bb0(%0 : $EA):
switch_enum %0 : $EA, case #EA.cA!enumelt: bb1, case #EA.cB!enumelt.1: bb3, case #EA.cC!enumelt.1: bb5
bb1:
br bb2
bb2:
br bb7
bb3(%6 : $Int32):
br bb4
bb4:
unreachable
bb5(%10 : $Float):
br bb6
bb6:
unreachable
bb7:
%14 = tuple ()
return %14 : $()
}
// CHECK-LABEL: fold_unreachable_terminators2
sil @fold_unreachable_terminators2 : $@convention(thin) (EA) -> Int32 {
// CHECK: bb0
bb0(%0 : $EA):
// CHECK-NEXT: [[VAL:%[a-zA-Z0-9]+]] = unchecked_enum_data %0 : $EA, #EA.cB!enumelt.1{{.*}} // user: %2
// CHECK-NEXT: return [[VAL]] : $Int32
switch_enum %0 : $EA, case #EA.cA!enumelt: bb1, case #EA.cB!enumelt.1: bb3, case #EA.cC!enumelt.1: bb5
bb1:
br bb2
bb2:
unreachable
bb3(%6 : $Int32):
br bb4
bb4:
return %6 : $Int32
bb5(%10 : $Float):
br bb6
bb6:
unreachable
}
// CHECK-LABEL: simplify_switch_to_select_enum
sil @simplify_switch_to_select_enum : $@convention(thin) (X) -> Bool {
bb0(%0 : $X):
// CHECK: bb0
// CHECK: [[TRUE:%.*]] = integer_literal {{.*}} -1
// CHECK: integer_literal {{.*}} 0
// CHECK: [[FALSE:%.*]] = integer_literal {{.*}} 0
// CHECK: [[VAL:%[a-zA-Z0-9]+]] = select_enum %0 : $X, case #X.A!enumelt: [[TRUE]], default [[FALSE]]
// CHECK-NOT: switch_enum
// CHECK-NOT: bb2
// CHECK: [[RETVAL:%[a-zA-Z0-9]+]] = struct $Bool ([[VAL]] : $Builtin.Int1)
// CHECK-NEXT: return [[RETVAL]] : $Bool
%2 = integer_literal $Builtin.Int1, 0
switch_enum %0 : $X, case #X.A!enumelt: bb1, case #X.B!enumelt.1: bb2, case #X.C!enumelt.1: bb3
bb1: // Preds: bb0
%10 = integer_literal $Builtin.Int1, -1
br bb4(%10 : $Builtin.Int1)
bb2: // Preds: bb0
br bb4(%2 : $Builtin.Int1)
bb3: // Preds: bb0
br bb4(%2 : $Builtin.Int1)
bb4(%20 : $Builtin.Int1): // Preds: bb1 bb2 bb3
%11 = struct $Bool (%20 : $Builtin.Int1)
return %11 : $Bool
}
sil @external_f : $@convention(thin) () -> ()
// Check that switch_enum to select_enum conversion does not
// take place in a presence of side-effects.
// CHECK-LABEL: simplify_switch_to_select_enum_with_side_effects
sil @simplify_switch_to_select_enum_with_side_effects : $@convention(thin) (X) -> Int32 {
bb0(%0 : $X):
// CHECK: bb0
// CHECK-NOT: select_enum
// CHECK: switch_enum
switch_enum %0 : $X, case #X.A!enumelt: bb1, case #X.B!enumelt.1: bb2, case #X.C!enumelt.1: bb3
// CHECK: bb1:
bb1: // Preds: bb0
%10 = integer_literal $Builtin.Int32, 1
br bb4(%10 : $Builtin.Int32)
bb2: // Preds: bb0
// This BB contains a side-effect. Therefore switch_enum cannot be eliminated.
%11 = function_ref @external_f : $@convention(thin) () -> ()
%12 = apply %11() : $@convention(thin) () -> ()
%13 = integer_literal $Builtin.Int32, 2
br bb4(%13 : $Builtin.Int32)
// CHECK: bb3:
// CHECK: br bb4
bb3: // Preds: bb0
%14 = integer_literal $Builtin.Int32, 3
br bb4(%14 : $Builtin.Int32)
bb4(%20 : $Builtin.Int32): // Preds: bb1 bb2 bb3
// CHECK: bb4([[VAL:%[a-zA-Z0-9]+]]{{.*}}):
// CHECK: [[RETVAL:%[a-zA-Z0-9]+]] = struct $Int32 ([[VAL]] : $Builtin.Int32)
// CHECK-NEXT: return [[RETVAL]] : $Int32
%21 = struct $Int32 (%20 : $Builtin.Int32)
return %21 : $Int32
}
enum E {
case Nope, Yup(Builtin.Int1)
}
// CHECK-LABEL: sil @simplify_switch_enum_pred_no_arg
sil @simplify_switch_enum_pred_no_arg : $@convention(thin) (E) -> Builtin.Int1 {
bb0(%0 : $E):
// CHECK-LABEL: bb0
// CHECK: switch_enum %0 : $E, case #E.Nope!enumelt: bb1, case #E.Yup!enumelt.1: bb2
switch_enum %0 : $E, case #E.Nope!enumelt: bb1, case #E.Yup!enumelt.1: bb2
bb1:
%1 = integer_literal $Builtin.Int1, -1
br bb5(%1 : $Builtin.Int1)
bb2:
// CHECK: unchecked_enum_data %0 : $E, #E.Yup!enumelt.1
// CHECK-NOT: switch_enum
// CHECK: return
switch_enum %0 : $E, case #E.Yup!enumelt.1: bb4, case #E.Nope!enumelt: bb3
bb3:
%2 = integer_literal $Builtin.Int1, 0
br bb5(%2 : $Builtin.Int1)
bb4(%3 : $Builtin.Int1):
br bb5(%3 : $Builtin.Int1)
bb5(%4 : $Builtin.Int1):
return %4 : $Builtin.Int1
}
// CHECK-LABEL: sil @same_destination_unused_arg
sil @same_destination_unused_arg : $@convention(thin) (Optional<Int32>) -> Optional<Int32> {
bb0(%0 : $Optional<Int32>):
%t = integer_literal $Builtin.Int1, 1
%f = integer_literal $Builtin.Int1, 0
// CHECK: select_enum
// CHECK-NEXT: return
%1 = select_enum %0 : $Optional<Int32>, case #Optional.some!enumelt.1: %t, default %f : $Builtin.Int1
cond_br %1, bb1(%0 : $Optional<Int32>), bb2(%0 : $Optional<Int32>)
bb1(%2 : $Optional<Int32>):
br bb2(%2 : $Optional<Int32>)
bb2(%3 : $Optional<Int32>):
return %0 : $Optional<Int32>
}
public enum Numbers {
case First, Second, Third, Fourth, Fifth
//var hashValue: Int32 { get }
}
// Check that one of the switch_enum instructions can be
// converted into select_enum instructions, even though
// the destination block is used as a target also by
// another switch_enum instruction
// CHECK_WITH_CODEMOTION-LABEL: sil @FormSelectEnumFromTwoSelectSwitches
// CHECK_WITH_CODEMOTION: switch_enum %0 : $Numbers
// CHECK_WITH_CODEMOTION-NOT: switch_enum
// CHECK_WITH_CODEMOTION: select_enum
// CHECK_WITH_CODEMOTION: return
sil @FormSelectEnumFromTwoSelectSwitches : $@convention(thin) (Numbers) -> Int32 {
bb0(%0 : $Numbers):
debug_value %0 : $Numbers, let, name "e" // id: %1
switch_enum %0 : $Numbers, case #Numbers.First!enumelt: bb1, case #Numbers.Second!enumelt: bb3, case #Numbers.Third!enumelt: bb4, default bb6 // id: %2
bb1: // Preds: bb0
br bb2 // id: %3
bb2: // Preds: bb1
%4 = integer_literal $Builtin.Int32, 42 // user: %5
br bb20(%4 : $Builtin.Int32) // id: %6
bb3: // Preds: bb0
br bb5 // id: %7
bb4: // Preds: bb0
br bb5 // id: %8
bb5: // Preds: bb3 bb4
%9 = integer_literal $Builtin.Int32, 24 // user: %10
br bb20(%9 : $Builtin.Int32) // id: %11
bb6: // Preds: bb0
br bb7 // id: %12
bb7: // Preds: bb6
br bb8 // id: %13
bb8: // Preds: bb7
br bb9 // id: %14
bb9: // Preds: bb8
switch_enum %0 : $Numbers, case #Numbers.First!enumelt: bb10, case #Numbers.Second!enumelt: bb12, case #Numbers.Third!enumelt: bb13, case #Numbers.Fourth!enumelt: bb15, default bb17 // id: %15
bb10: // Preds: bb9
br bb11 // id: %16
bb11: // Preds: bb10
%17 = integer_literal $Builtin.Int32, 42 // user: %18
br bb20(%17 : $Builtin.Int32) // id: %19
bb12: // Preds: bb9
br bb14 // id: %20
bb13: // Preds: bb9
br bb14 // id: %21
bb14: // Preds: bb12 bb13
%22 = integer_literal $Builtin.Int32, 24 // user: %23
br bb20(%22 : $Builtin.Int32) // id: %24
bb15: // Preds: bb9
br bb16 // id: %25
bb16: // Preds: bb15
%26 = integer_literal $Builtin.Int32, 100 // user: %27
br bb20(%26 : $Builtin.Int32) // id: %28
bb17: // Preds: bb9
br bb18 // id: %29
bb18: // Preds: bb17
br bb19 // id: %30
bb19: // Preds: bb18
%31 = integer_literal $Builtin.Int32, 100 // user: %32
br bb20(%31 : $Builtin.Int32) // id: %33
bb20(%34 : $Builtin.Int32): // Preds: bb2 bb5 bb11 bb14 bb16 bb19
%35 = struct $Int32 (%34 : $Builtin.Int32) // user: %36
return %35 : $Int32 // id: %36
}
// CHECK_WITH_CODEMOTION-LABEL: sil @FormSelectEnumIntResult
// CHECK_WITH_CODEMOTION-NOT: switch_enum
// CHECK_WITH_CODEMOTION: select_enum
// CHECK_WITH_CODEMOTION: return
sil @FormSelectEnumIntResult : $@convention(thin) (Numbers) -> Int32 {
bb0(%0 : $Numbers):
debug_value %0 : $Numbers, let, name "e" // id: %1
switch_enum %0 : $Numbers, case #Numbers.First!enumelt: bb1, case #Numbers.Second!enumelt: bb3, case #Numbers.Third!enumelt: bb4, case #Numbers.Fourth!enumelt: bb6, default bb8 // id: %2
bb1: // Preds: bb0
br bb2 // id: %3
bb2: // Preds: bb1
%4 = integer_literal $Builtin.Int32, 42 // user: %5
br bb11(%4 : $Builtin.Int32) // id: %6
bb3: // Preds: bb0
br bb5 // id: %7
bb4: // Preds: bb0
br bb5 // id: %8
bb5: // Preds: bb3 bb4
%9 = integer_literal $Builtin.Int32, 24 // user: %10
br bb11(%9 : $Builtin.Int32) // id: %11
bb6: // Preds: bb0
br bb7 // id: %12
bb7: // Preds: bb6
%13 = integer_literal $Builtin.Int32, 100 // user: %14
br bb11(%13 : $Builtin.Int32) // id: %15
bb8: // Preds: bb0
br bb9 // id: %16
bb9: // Preds: bb8
br bb10 // id: %17
bb10: // Preds: bb9
%18 = integer_literal $Builtin.Int32, 100 // user: %19
br bb11(%18 : $Builtin.Int32) // id: %20
bb11(%21 : $Builtin.Int32): // Preds: bb2 bb5 bb7 bb10
%22 = struct $Int32 (%21: $Builtin.Int32)
return %22 : $Int32 // id: %22
}
// CHECK_WITH_CODEMOTION-LABEL: sil @FormSelectEnumBoolResult
// CHECK_WITH_CODEMOTION-NOT: switch_enum
// CHECK_WITH_CODEMOTION: select_enum
// CHECK_WITH_CODEMOTION: return
sil @FormSelectEnumBoolResult : $@convention(thin) (Numbers) -> Bool {
bb0(%0 : $Numbers):
debug_value %0 : $Numbers, let, name "e" // id: %1
switch_enum %0 : $Numbers, case #Numbers.First!enumelt: bb1, case #Numbers.Second!enumelt: bb3, case #Numbers.Third!enumelt: bb4, default bb6 // id: %2
bb1: // Preds: bb0
br bb2 // id: %3
bb2: // Preds: bb1
%4 = integer_literal $Builtin.Int1, -1 // user: %5
br bb9(%4 : $Builtin.Int1) // id: %6
bb3: // Preds: bb0
br bb5 // id: %7
bb4: // Preds: bb0
br bb5 // id: %8
bb5: // Preds: bb3 bb4
%9 = integer_literal $Builtin.Int1, 0 // user: %10
br bb9(%9 : $Builtin.Int1) // id: %11
bb6: // Preds: bb0
br bb7 // id: %12
bb7: // Preds: bb6
br bb8 // id: %13
bb8: // Preds: bb7
%14 = integer_literal $Builtin.Int1, -1 // user: %15
br bb9(%14 : $Builtin.Int1) // id: %16
bb9(%17 : $Builtin.Int1): // Preds: bb2 bb5 bb8
%18 = struct $Bool (%17 : $Builtin.Int1)
return %18 : $Bool // id: %19
}
// CHECK_WITH_CODEMOTION-LABEL: sil @DontFormSelectEnumBoolResult
// CHECK_WITH_CODEMOTION: switch_enum
// CHECK_WITH_CODEMOTION-NOT: select_enum
// CHECK_WITH_CODEMOTION: return
sil @DontFormSelectEnumBoolResult : $@convention(thin) (Numbers, Bool) -> Bool {
bb0(%0 : $Numbers, %1 : $Bool):
debug_value %0 : $Numbers, let, name "e" // id: %2
%2 = struct_extract %1 : $Bool, #Bool._value
switch_enum %0 : $Numbers, case #Numbers.First!enumelt: bb1, case #Numbers.Second!enumelt: bb3, case #Numbers.Third!enumelt: bb4, default bb6 // id: %4
bb1: // Preds: bb0
br bb2 // id: %5
bb2: // Preds: bb1
%6 = integer_literal $Builtin.Int1, -1 // user: %7
br bb10(%6 : $Builtin.Int1) // id: %8
bb3: // Preds: bb0
br bb5 // id: %9
bb4: // Preds: bb0
br bb5 // id: %10
bb5: // Preds: bb3 bb4
%11 = integer_literal $Builtin.Int1, 0 // user: %12
br bb10(%11 : $Builtin.Int1) // id: %13
bb6: // Preds: bb0
br bb7 // id: %14
bb7: // Preds: bb6
br bb8 // id: %15
bb8: // Preds: bb7
br bb9 // id: %16
bb9: // Preds: bb8
br bb10(%2 : $Builtin.Int1) // id: %17
bb10(%18 : $Builtin.Int1): // Preds: bb2 bb5 bb9
%19 = struct $Bool (%18 : $Builtin.Int1)
return %19 : $Bool // id: %19
}