1 # RUN: llc -run-pass=branch-folder %s -o - | FileCheck %s 2 3 # PR33980 4 5 # Don't form conditional tail calls when the original conditional branch has 6 # the same true and false destination. Otherwise, when we remove the tail call 7 # successor we will also remove the fallthrough successor from the CFG. 8 9 # CHECK: body: | 10 # CHECK: bb.0.entry: 11 # CHECK: successors: %bb.1(0x40000000) 12 # CHECK: liveins: $edi 13 # CHECK: CMP32ri8 killed $edi, 2, implicit-def $eflags 14 # CHECK: TCRETURNdi64cc @mergeable_conditional_tailcall 15 16 # This was the unconditional branch to a dead MBB that we left behind before 17 # this bug was fixed. 18 # CHECK-NOT: JMP_1 %bb.-1 19 20 --- | 21 ; ModuleID = 't.ll' 22 source_filename = "t.ll" 23 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 24 target triple = "x86_64--linux" 25 26 @static_local_guard = external global i64, align 8 27 28 ; Function Attrs: optsize 29 define void @f(i32 %arg) #0 { 30 entry: 31 switch i32 %arg, label %sw.epilog [ 32 i32 0, label %sw.bb 33 i32 1, label %sw.bb 34 i32 2, label %sw.bb2 35 ] 36 37 sw.bb: ; preds = %entry, %entry 38 %tmp = load atomic i8, i8* bitcast (i64* @static_local_guard to i8*) acquire, align 8 39 %guard.uninitialized.i = icmp eq i8 %tmp, 0 40 br i1 %guard.uninitialized.i, label %init.check.i, label %return, !prof !0 41 42 init.check.i: ; preds = %sw.bb 43 tail call void @initialize_static_local(i64* nonnull @static_local_guard) 44 ret void 45 46 sw.bb2: ; preds = %entry 47 tail call void @mergeable_conditional_tailcall() 48 ret void 49 50 sw.epilog: ; preds = %entry 51 tail call void @mergeable_conditional_tailcall() 52 ret void 53 54 return: ; preds = %sw.bb 55 ret void 56 } 57 58 declare void @mergeable_conditional_tailcall() 59 60 declare void @initialize_static_local(i64*) 61 62 ; Function Attrs: nounwind 63 declare void @llvm.stackprotector(i8*, i8**) #1 64 65 attributes #0 = { optsize } 66 attributes #1 = { nounwind } 67 68 !0 = !{!"branch_weights", i32 1, i32 1048575} 69 70 ... 71 --- 72 name: f 73 alignment: 0 74 exposesReturnsTwice: false 75 legalized: false 76 regBankSelected: false 77 selected: false 78 tracksRegLiveness: true 79 registers: 80 liveins: 81 - { reg: '$edi', virtual-reg: '' } 82 frameInfo: 83 isFrameAddressTaken: false 84 isReturnAddressTaken: false 85 hasStackMap: false 86 hasPatchPoint: false 87 stackSize: 0 88 offsetAdjustment: 0 89 maxAlignment: 0 90 adjustsStack: false 91 hasCalls: false 92 stackProtector: '' 93 maxCallFrameSize: 0 94 hasOpaqueSPAdjustment: false 95 hasVAStart: false 96 hasMustTailInVarArgFunc: false 97 savePoint: '' 98 restorePoint: '' 99 fixedStack: 100 stack: 101 constants: 102 body: | 103 bb.0.entry: 104 successors: %bb.2(0x40000000), %bb.1(0x40000000) 105 liveins: $edi 106 107 CMP32ri8 killed $edi, 2, implicit-def $eflags 108 JB_1 %bb.2, implicit $eflags 109 JMP_1 %bb.1 110 111 bb.1.entry: 112 successors: %bb.4(0x40000000), %bb.5(0x40000000) 113 liveins: $eflags 114 115 JE_1 %bb.4, implicit killed $eflags 116 JMP_1 %bb.5 117 118 bb.2.sw.bb: 119 successors: %bb.3(0x00000800), %bb.6(0x7ffff800) 120 121 $al = ACQUIRE_MOV8rm $rip, 1, $noreg, @static_local_guard, $noreg :: (volatile load acquire 1 from `i8* bitcast (i64* @static_local_guard to i8*)`, align 8) 122 TEST8rr killed $al, $al, implicit-def $eflags 123 JNE_1 %bb.6, implicit killed $eflags 124 JMP_1 %bb.3 125 126 bb.3.init.check.i: 127 dead $edi = MOV32ri64 @static_local_guard, implicit-def $rdi 128 TCRETURNdi64 @initialize_static_local, 0, csr_64, implicit $rsp, implicit $rdi 129 130 bb.4.sw.bb2: 131 TCRETURNdi64 @mergeable_conditional_tailcall, 0, csr_64, implicit $rsp 132 133 bb.5.sw.epilog: 134 TCRETURNdi64 @mergeable_conditional_tailcall, 0, csr_64, implicit $rsp 135 136 bb.6.return: 137 RET 0 138 139 ... 140