# RUN: llc -run-pass=branch-folder %s -o - | FileCheck %s # PR33980 # Don't form conditional tail calls when the original conditional branch has # the same true and false destination. Otherwise, when we remove the tail call # successor we will also remove the fallthrough successor from the CFG. # CHECK: body: | # CHECK: bb.0.entry: # CHECK: successors: %bb.1(0x40000000) # CHECK: liveins: $edi # CHECK: CMP32ri8 killed $edi, 2, implicit-def $eflags # CHECK: TCRETURNdi64cc @mergeable_conditional_tailcall # This was the unconditional branch to a dead MBB that we left behind before # this bug was fixed. # CHECK-NOT: JMP_1 %bb.-1 --- | ; ModuleID = 't.ll' source_filename = "t.ll" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64--linux" @static_local_guard = external global i64, align 8 ; Function Attrs: optsize define void @f(i32 %arg) #0 { entry: switch i32 %arg, label %sw.epilog [ i32 0, label %sw.bb i32 1, label %sw.bb i32 2, label %sw.bb2 ] sw.bb: ; preds = %entry, %entry %tmp = load atomic i8, i8* bitcast (i64* @static_local_guard to i8*) acquire, align 8 %guard.uninitialized.i = icmp eq i8 %tmp, 0 br i1 %guard.uninitialized.i, label %init.check.i, label %return, !prof !0 init.check.i: ; preds = %sw.bb tail call void @initialize_static_local(i64* nonnull @static_local_guard) ret void sw.bb2: ; preds = %entry tail call void @mergeable_conditional_tailcall() ret void sw.epilog: ; preds = %entry tail call void @mergeable_conditional_tailcall() ret void return: ; preds = %sw.bb ret void } declare void @mergeable_conditional_tailcall() declare void @initialize_static_local(i64*) ; Function Attrs: nounwind declare void @llvm.stackprotector(i8*, i8**) #1 attributes #0 = { optsize } attributes #1 = { nounwind } !0 = !{!"branch_weights", i32 1, i32 1048575} ... --- name: f alignment: 1 exposesReturnsTwice: false legalized: false regBankSelected: false selected: false tracksRegLiveness: true registers: liveins: - { reg: '$edi', virtual-reg: '' } frameInfo: isFrameAddressTaken: false isReturnAddressTaken: false hasStackMap: false hasPatchPoint: false stackSize: 0 offsetAdjustment: 0 maxAlignment: 0 adjustsStack: false hasCalls: false stackProtector: '' maxCallFrameSize: 0 hasOpaqueSPAdjustment: false hasVAStart: false hasMustTailInVarArgFunc: false savePoint: '' restorePoint: '' fixedStack: stack: constants: body: | bb.0.entry: successors: %bb.2(0x40000000), %bb.1(0x40000000) liveins: $edi CMP32ri8 killed $edi, 2, implicit-def $eflags JCC_1 %bb.2, 2, implicit $eflags JMP_1 %bb.1 bb.1.entry: successors: %bb.4(0x40000000), %bb.5(0x40000000) liveins: $eflags JCC_1 %bb.4, 4, implicit killed $eflags JMP_1 %bb.5 bb.2.sw.bb: successors: %bb.3(0x00000800), %bb.6(0x7ffff800) $al = MOV8rm $rip, 1, $noreg, @static_local_guard, $noreg :: (volatile load acquire 1 from `i8* bitcast (i64* @static_local_guard to i8*)`, align 8) TEST8rr killed $al, $al, implicit-def $eflags JCC_1 %bb.6, 5, implicit killed $eflags JMP_1 %bb.3 bb.3.init.check.i: dead $edi = MOV32ri @static_local_guard, implicit-def $rdi TCRETURNdi64 @initialize_static_local, 0, csr_64, implicit $rsp, implicit $rdi bb.4.sw.bb2: TCRETURNdi64 @mergeable_conditional_tailcall, 0, csr_64, implicit $rsp bb.5.sw.epilog: TCRETURNdi64 @mergeable_conditional_tailcall, 0, csr_64, implicit $rsp bb.6.return: RET 0 ...