diff --git a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp --- a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp +++ b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp @@ -897,6 +897,8 @@ bool Is64Bit = (MI.getOpcode() == PPC::RLWINM8 || MI.getOpcode() == PPC::RLWINM8_rec); + Simplified = true; + LLVM_DEBUG(dbgs() << "Replace Instr: "); LLVM_DEBUG(MI.dump()); @@ -913,9 +915,14 @@ MI.RemoveOperand(3); MI.getOperand(2).setImm(0); MI.setDesc(TII->get(Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec)); + MI.getOperand(1).setReg(SrcMI->getOperand(1).getReg()); + if (SrcMI->getOperand(1).isKill()) { + MI.getOperand(1).setIsKill(true); + SrcMI->getOperand(1).setIsKill(false); + } else + // About to replace MI.getOperand(1), clear its kill flag. + MI.getOperand(1).setIsKill(false); } - Simplified = true; - NumRotatesCollapsed++; LLVM_DEBUG(dbgs() << "With: "); LLVM_DEBUG(MI.dump()); @@ -925,16 +932,7 @@ // than NewME. Otherwise we get a 64 bit value after folding, but MI // return a 32 bit value. - // If FoldingReg has only one use and it it not RLWINM_rec and - // RLWINM8_rec, safe to delete its def SrcMI. Otherwise keep it. - if (MRI->hasOneNonDBGUse(FoldingReg) && - (SrcMI->getOpcode() == PPC::RLWINM || - SrcMI->getOpcode() == PPC::RLWINM8)) { - ToErase = SrcMI; - LLVM_DEBUG(dbgs() << "Delete dead instruction: "); - LLVM_DEBUG(SrcMI->dump()); - } - + Simplified = true; LLVM_DEBUG(dbgs() << "Converting Instr: "); LLVM_DEBUG(MI.dump()); @@ -953,12 +951,20 @@ // About to replace MI.getOperand(1), clear its kill flag. MI.getOperand(1).setIsKill(false); - Simplified = true; - NumRotatesCollapsed++; - LLVM_DEBUG(dbgs() << "To: "); LLVM_DEBUG(MI.dump()); } + if (Simplified) { + // If FoldingReg has no non-debug use and it has no implicit def (it + // is not RLWINMO or RLWINM8o), it's safe to delete its def SrcMI. + // Otherwise keep it. + ++NumRotatesCollapsed; + if (MRI->use_nodbg_empty(FoldingReg) && !SrcMI->hasImplicitDef()) { + ToErase = SrcMI; + LLVM_DEBUG(dbgs() << "Delete dead instruction: "); + LLVM_DEBUG(SrcMI->dump()); + } + } break; } } diff --git a/llvm/test/CodeGen/PowerPC/fold-rlwinm.mir b/llvm/test/CodeGen/PowerPC/fold-rlwinm.mir --- a/llvm/test/CodeGen/PowerPC/fold-rlwinm.mir +++ b/llvm/test/CodeGen/PowerPC/fold-rlwinm.mir @@ -118,7 +118,7 @@ %0:g8rc = COPY $x3 %1:gprc = COPY %0.sub_32:g8rc %2:gprc = RLWINM %1:gprc, 27, 5, 10 - ; CHECK: %2:gprc = RLWINM %1, 27, 5, 10 + ; CHECK-NOT: RLWINM %1, %3:gprc = RLWINM %2:gprc, 8, 5, 10 ; CHECK: %3:gprc = LI 0 BLR8 implicit $lr8, implicit $rm @@ -133,9 +133,24 @@ %0:g8rc = COPY $x3 %1:gprc = COPY %0.sub_32:g8rc %2:gprc = RLWINM %1:gprc, 27, 5, 10 - ; CHECK: %2:gprc = RLWINM %1, 27, 5, 10 + ; CHECK-NOT: RLWINM %1, %3:gprc = RLWINM_rec %2:gprc, 8, 5, 10, implicit-def $cr0 - ; CHECK: %3:gprc = ANDI_rec %2, 0, implicit-def $cr0 + ; CHECK: %3:gprc = ANDI_rec %1, 0, implicit-def $cr0 + BLR8 implicit $lr8, implicit $rm +... +--- +name: testFoldRLWINMoToZeroSrcCanNotBeDeleted +#CHECK : name : testFoldRLWINMoToZeroSrcCanNotBeDeleted +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x3 + %0:g8rc = COPY $x3 + %1:gprc = COPY %0.sub_32:g8rc + %2:gprc = RLWINM_rec %1:gprc, 27, 5, 10, implicit-def $cr0 + ; CHECK: %2:gprc = RLWINM_rec %1, 27, 5, 10, implicit-def $cr0 + %3:gprc = RLWINM_rec %2:gprc, 8, 5, 10, implicit-def $cr0 + ; CHECK: %3:gprc = ANDI_rec %1, 0, implicit-def $cr0 BLR8 implicit $lr8, implicit $rm ... ---