100 lines · plain
1# In certain cases CodeGenPrepare folds a return instruction into2# the return block's predecessor blocks and subsequently deletes the return block.3# The purpose of this is to enable tail call optimization in the predecessor blocks.4# Removal of the return block also removes fake use instructions that were present5# in the return block, potentially causing debug information to be lost.6#7# The fix is to clone any fake use instructions that are not dominated by definitions8# in the return block itself into the predecessor blocks. This test enures that we do so.9#10# Generated from the following source with11# clang -fextend-variable-liveness -S -emit-llvm -O2 -mllvm -stop-before=codegenprepare -o test.mir test.c12#13# extern int f0();14# extern int f1();15#16# int foo(int i) {17# int temp = i;18# if (temp == 0)19# temp = f0();20# else21# temp = f1();22# return temp;23# }24#25# RUN: llc -run-pass=codegenprepare -mtriple=x86_64-unknown-linux -o - %s | FileCheck %s26#27# CHECK: define{{.*}}foo28# CHECK: if.then:29# CHECK-NEXT: call{{.*}}fake.use(i32 %i)30# CHECK-NEXT: tail call i32{{.*}}@f031# CHECK-NEXT: ret32# CHECK: if.else:33# CHECK-NEXT: call{{.*}}fake.use(i32 %i)34# CHECK-NEXT: tail call i32{{.*}}@f135# CHECK-NEXT: ret36 37--- |38 define hidden i32 @foo(i32 %i) local_unnamed_addr optdebug {39 entry:40 %cmp = icmp eq i32 %i, 041 br i1 %cmp, label %if.then, label %if.else42 43 if.then:44 %call = tail call i32 (...) @f0()45 br label %if.end46 47 if.else:48 %call1 = tail call i32 (...) @f1()49 br label %if.end50 51 if.end:52 %temp.0 = phi i32 [ %call, %if.then ], [ %call1, %if.else ]53 notail call void (...) @llvm.fake.use(i32 %temp.0)54 notail call void (...) @llvm.fake.use(i32 %i)55 ret i32 %temp.056 }57 declare i32 @f0(...) local_unnamed_addr58 declare i32 @f1(...) local_unnamed_addr59 60...61---62name: foo63alignment: 1664exposesReturnsTwice: false65legalized: false66regBankSelected: false67selected: false68failedISel: false69tracksRegLiveness: true70hasWinCFI: false71registers: []72liveins: []73frameInfo:74 isFrameAddressTaken: false75 isReturnAddressTaken: false76 hasStackMap: false77 hasPatchPoint: false78 stackSize: 079 offsetAdjustment: 080 maxAlignment: 181 adjustsStack: false82 hasCalls: false83 stackProtector: ''84 maxCallFrameSize: 429496729585 cvBytesOfCalleeSavedRegisters: 086 hasOpaqueSPAdjustment: false87 hasVAStart: false88 hasMustTailInVarArgFunc: false89 localFrameSize: 090 savePoint: []91 restorePoint: []92fixedStack: []93stack: []94callSites: []95constants: []96machineFunctionInfo: {}97body: |98 99...100