blob: d311bb2458d255bb8d65902ccab2adbb00156822 [file] [log] [blame]
# 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: 0
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
...