// RUN: %target-sil-opt -sil-print-types -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' }