1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
// RUN: %target-sil-opt -enable-sil-verify-all %s -jumpthread-simplify-cfg -cse | %FileCheck %s
// Test if jump-threading is done to combine two enum instructions
// into a single block.
sil_stage canonical
import Builtin
enum E {
case A
case B
}
enum E2 {
case X
case Y(E)
}
// CHECK-LABEL: sil @testfunc
sil @testfunc : $@convention(thin) (Builtin.Int1, Builtin.Int1) -> E2 {
bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int1):
cond_br %0, bb1, bb4
bb1:
%2 = enum $E, #E.A!enumelt
cond_br %1, bb2, bb3(%2 : $E)
// CHECK: [[ENUM1:%[0-9]+]] = enum $E, #E.B
// CHECK-NEXT: [[ENUM2:%[0-9]+]] = enum $E2, #E2.Y!enumelt, [[ENUM1]]
// CHECK-NEXT: br [[RETBB:bb[0-9]+]]([[ENUM2]] : $E2)
bb2:
// This block should be jump-threaded
%3 = enum $E, #E.B!enumelt
br bb3(%3 : $E)
bb3(%4 : $E):
%5 = enum $E2, #E2.Y!enumelt, %4 : $E
br bb5(%5 : $E2)
bb4:
%6 = enum $E2, #E2.X!enumelt
br bb5(%6 : $E2)
// CHECK: [[RETBB]]({{.*}}):
// CHECK-NEXT: return
bb5(%7 : $E2):
return %7 : $E2
}
// CHECK-LABEL: sil @test_enum_addr
sil @test_enum_addr : $@convention(thin) () -> Builtin.Int32 {
bb0:
%2 = alloc_stack $E
cond_br undef, bb1, bb2
// CHECK: bb1:
// CHECK-NEXT: inject_enum_addr
// CHECK-NEXT: switch_enum_addr
bb1:
inject_enum_addr %2 : $*E, #E.A!enumelt
br bb3
// CHECK: bb2:
// CHECK-NEXT: inject_enum_addr
// CHECK-NEXT: switch_enum_addr
bb2:
inject_enum_addr %2 : $*E, #E.B!enumelt
br bb3
bb3:
switch_enum_addr %2 : $*E, case #E.A!enumelt: bb4, case #E.B!enumelt: bb5
bb4:
%10 = integer_literal $Builtin.Int32, 1
br bb6(%10 : $Builtin.Int32)
bb5:
%11 = integer_literal $Builtin.Int32, 2
br bb6(%11 : $Builtin.Int32)
bb6(%12 : $Builtin.Int32):
dealloc_stack %2 : $*E
return %12 : $Builtin.Int32
// CHECK: } // end sil function 'test_enum_addr'
}
// CHECK-LABEL: sil @dont_jumpthread_enum_addr
sil @dont_jumpthread_enum_addr : $@convention(thin) (E) -> Builtin.Int32 {
bb0(%0 : $E):
%2 = alloc_stack $E
%3 = alloc_stack $E
cond_br undef, bb1, bb2
// CHECK: bb1:
// CHECK-NEXT: inject_enum_addr
// CHECK-NEXT: store
// CHECK-NEXT: br bb3
bb1:
inject_enum_addr %2 : $*E, #E.A!enumelt
store %0 to %2 : $*E
br bb3
// CHECK: bb2:
// CHECK-NEXT: inject_enum_addr
// CHECK-NEXT: br bb3
bb2:
inject_enum_addr %3 : $*E, #E.A!enumelt
br bb3
// CHECK: bb3:
// CHECK-NEXT: switch_enum_addr
bb3:
switch_enum_addr %2 : $*E, case #E.A!enumelt: bb4, case #E.B!enumelt: bb5
bb4:
%10 = integer_literal $Builtin.Int32, 1
br bb6(%10 : $Builtin.Int32)
bb5:
%11 = integer_literal $Builtin.Int32, 2
br bb6(%11 : $Builtin.Int32)
bb6(%12 : $Builtin.Int32):
dealloc_stack %3 : $*E
dealloc_stack %2 : $*E
return %12 : $Builtin.Int32
// CHECK: } // end sil function 'dont_jumpthread_enum_addr'
}
|