diff --git a/llvm/lib/Target/PowerPC/PPCEarlyReturn.cpp b/llvm/lib/Target/PowerPC/PPCEarlyReturn.cpp --- a/llvm/lib/Target/PowerPC/PPCEarlyReturn.cpp +++ b/llvm/lib/Target/PowerPC/PPCEarlyReturn.cpp @@ -140,8 +140,19 @@ PredToRemove.push_back(*PI); } - if (BlockChanged) + if (BlockChanged) { + // Update the liveins for *PI. + for (const MachineOperand &MO : I->operands()) { + if (!MO.isReg()) + continue; + Register Reg = MO.getReg(); + if (!Reg || !ReturnMBB.isLiveIn(Reg) || (*PI)->isLiveIn(Reg)) + continue; + (*PI)->addLiveIn(Reg); + } + Changed = true; + } } for (unsigned i = 0, ie = PredToRemove.size(); i != ie; ++i) @@ -153,6 +164,16 @@ if (ReturnMBB.pred_size() == 1) { MachineBasicBlock &PrevMBB = **ReturnMBB.pred_begin(); if (PrevMBB.isLayoutSuccessor(&ReturnMBB) && PrevMBB.canFallThrough()) { + // Update the liveins for PrevMBB. + for (const MachineOperand &MO : I->operands()) { + if (!MO.isReg()) + continue; + Register Reg = MO.getReg(); + if (!Reg || !ReturnMBB.isLiveIn(Reg) || PrevMBB.isLiveIn(Reg)) + continue; + PrevMBB.addLiveIn(Reg); + } + // Move the blr into the preceding block. PrevMBB.splice(PrevMBB.end(), &ReturnMBB, I); PrevMBB.removeSuccessor(&ReturnMBB, true); diff --git a/llvm/test/CodeGen/PowerPC/early-ret-liveness.mir b/llvm/test/CodeGen/PowerPC/early-ret-liveness.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/early-ret-liveness.mir @@ -0,0 +1,67 @@ +# RUN: llc -mtriple powerpc64le-unknown-linux-gnu -run-pass=ppc-early-ret -o \ +# RUN: - %s -verify-machineinstrs | FileCheck %s + +--- +name: early-ret-liveness +tracksRegLiveness: true +hasWinCFI: false +registers: [] +liveins: + - { reg: '$x3', virtual-reg: '' } + - { reg: '$x4', virtual-reg: '' } + - { reg: '$x5', virtual-reg: '' } + - { reg: '$x6', virtual-reg: '' } +body: | + bb.0: + successors: %bb.2(0x40000000), %bb.1(0x40000000) + liveins: $x3, $x4, $x5, $x6 + + renamable $x8 = MULLD renamable $x5, renamable $x4 + renamable $cr5 = CMPDI renamable $x3, 0 + dead renamable $x9 = MULHDU_rec renamable $x3, renamable $x6, implicit-def $cr0 + renamable $x3 = MULLD killed renamable $x3, renamable $x6 + $cr1 = MCRF killed $cr0 + renamable $x3 = ADD8 killed renamable $x3, killed renamable $x8 + renamable $cr0 = CMPDI renamable $x5, 0 + renamable $cr5lt = CRNOR killed renamable $cr0eq, killed renamable $cr5eq, implicit $cr5, implicit $cr0 + renamable $cr0 = CMPLDI renamable $x3, 0 + renamable $x8 = MULHDU renamable $x4, renamable $x6 + renamable $x3 = ADD8 renamable $x8, killed renamable $x3 + renamable $cr6 = CMPLD renamable $x3, killed renamable $x8 + renamable $cr5gt = CRANDC killed renamable $cr6lt, killed renamable $cr0eq, implicit $cr0, implicit $cr6 + renamable $cr5lt = CRORC killed renamable $cr5lt, killed renamable $cr1eq, implicit $cr1 + renamable $x7 = LI8 1 + dead renamable $x5 = MULHDU_rec killed renamable $x5, renamable $x4, implicit-def $cr0 + renamable $cr5lt = CRORC killed renamable $cr5lt, killed renamable $cr0eq, implicit $cr0 + renamable $cr5lt = CRNOR killed renamable $cr5lt, killed renamable $cr5gt + renamable $x4 = MULLD killed renamable $x4, killed renamable $x6 + BC killed renamable $cr5lt, %bb.2 + + bb.1: + successors: %bb.3(0x80000000) + liveins: $x7 + + renamable $x5 = ORI8 killed renamable $x7, 0 + B %bb.3 + + bb.2: + successors: %bb.3(0x80000000) + liveins: $zero8 + + renamable $x5 = ADDI8 $zero8, 0 + + bb.3: + liveins: $x3, $x4, $x5 + + BLR8 implicit $lr8, implicit $rm, implicit killed $x3, implicit killed $x4, implicit killed $x5 + + ; CHECK-LABEL: early-ret-liveness + ; CHECK: bb.1: + ; CHECK: liveins: $x7, $x3, $x4, $x5 + ; CHECK: renamable $x5 = ORI8 killed renamable $x7, 0 + ; CHECK: BLR8 implicit $lr8, implicit $rm, implicit $lr8, implicit $rm, implicit killed $x3, implicit killed $x4, implicit killed $x5 + ; CHECK: bb.2: + ; CHECK: liveins: $zero8, $x3, $x4, $x5 + ; CHECK: renamable $x5 = ADDI8 $zero8, 0 + ; CHECK: BLR8 implicit $lr8, implicit $rm, implicit killed $x3, implicit killed $x4, implicit killed $x5 +...