llvm.org GIT mirror llvm / testing test / CodeGen / X86 / conditional-tailcall-samedest.mir
testing

Tree @testing (Download .tar.gz)

conditional-tailcall-samedest.mir @testingraw · history · 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.sw.bb(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.sw.bb(0x40000000), %bb.1.entry(0x40000000)
    liveins: %edi
  
    CMP32ri8 killed %edi, 2, implicit-def %eflags
    JB_1 %bb.2.sw.bb, implicit %eflags
    JMP_1 %bb.1.entry
  
  bb.1.entry:
    successors: %bb.4.sw.bb2(0x40000000), %bb.5.sw.epilog(0x40000000)
    liveins: %eflags
  
    JE_1 %bb.4.sw.bb2, implicit killed %eflags
    JMP_1 %bb.5.sw.epilog
  
  bb.2.sw.bb:
    successors: %bb.3.init.check.i(0x00000800), %bb.6.return(0x7ffff800)
  
    %al = ACQUIRE_MOV8rm %rip, 1, _, @static_local_guard, _ :: (volatile load acquire 1 from `i8* bitcast (i64* @static_local_guard to i8*)`, align 8)
    TEST8rr killed %al, %al, implicit-def %eflags
    JNE_1 %bb.6.return, implicit killed %eflags
    JMP_1 %bb.3.init.check.i
  
  bb.3.init.check.i:
    dead %edi = MOV32ri64 @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

...