diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.h b/llvm/lib/Target/PowerPC/PPCInstrInfo.h --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.h +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.h @@ -470,6 +470,11 @@ // Predication support. bool isPredicated(const MachineInstr &MI) const override; + // Add implicit register operands based on MI.getDesc(). If the \p OldMCID is + // not nullptr, it will remove the old implicit registers used by \p OldMCID. + void fixupImplicitDefUseOperands(MachineInstr &MI, + const MCInstrDesc *OldMCID = nullptr) const; + bool PredicateInstruction(MachineInstr &MI, ArrayRef Pred) const override; diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -1667,9 +1667,40 @@ return false; } +// Set implicit register operands based on MI.getDesc(). If \p OldMCID is not +// nullptr, it will remove the old implicit register used by \p OldMCID. +void PPCInstrInfo::fixupImplicitDefUseOperands( + MachineInstr &MI, const MCInstrDesc *OldMCID) const { + + // Remove the implicit register from MI based on the OldMCID. + if (OldMCID && OldMCID->ImplicitDefs) + for (const MCPhysReg *ImpDefs = OldMCID->getImplicitDefs(); *ImpDefs; + ++ImpDefs) + MI.RemoveOperand(MI.findRegisterDefOperandIdx(*ImpDefs)); + + if (OldMCID && OldMCID->ImplicitUses) + for (const MCPhysReg *ImpUses = OldMCID->getImplicitUses(); *ImpUses; + ++ImpUses) + MI.RemoveOperand(MI.findRegisterUseOperandIdx(*ImpUses)); + + // Add implicit register to MI based on the MI.getDesc(). + const MCInstrDesc *MCID = &MI.getDesc(); + if (MCID->ImplicitDefs) + for (const MCPhysReg *ImpDefs = MCID->getImplicitDefs(); *ImpDefs; + ++ImpDefs) + MI.addOperand(MachineOperand::CreateReg(*ImpDefs, true, true)); + + if (MCID->ImplicitUses) + for (const MCPhysReg *ImpUses = MCID->getImplicitUses(); *ImpUses; + ++ImpUses) + MI.addOperand(MachineOperand::CreateReg(*ImpUses, false, true)); +} + bool PPCInstrInfo::PredicateInstruction(MachineInstr &MI, ArrayRef Pred) const { unsigned OpC = MI.getOpcode(); + const MCInstrDesc &OldMCID = MI.getDesc(); + if (OpC == PPC::BLR || OpC == PPC::BLR8) { if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) { bool isPPC64 = Subtarget.isPPC64(); @@ -1688,7 +1719,6 @@ .add(Pred[1]); } - return true; } else if (OpC == PPC::B) { if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) { bool isPPC64 = Subtarget.isPPC64(); @@ -1721,7 +1751,6 @@ .addMBB(MBB); } - return true; } else if (OpC == PPC::BCTR || OpC == PPC::BCTR8 || OpC == PPC::BCTRL || OpC == PPC::BCTRL8) { if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) @@ -1734,19 +1763,24 @@ MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8 : PPC::BCCTR8) : (setLR ? PPC::BCCTRL : PPC::BCCTR))); MachineInstrBuilder(*MI.getParent()->getParent(), MI).add(Pred[1]); - return true; } else if (Pred[0].getImm() == PPC::PRED_BIT_UNSET) { MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8n : PPC::BCCTR8n) : (setLR ? PPC::BCCTRLn : PPC::BCCTRn))); MachineInstrBuilder(*MI.getParent()->getParent(), MI).add(Pred[1]); - return true; + } else { + MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCCTRL8 : PPC::BCCCTR8) + : (setLR ? PPC::BCCCTRL : PPC::BCCCTR))); + MachineInstrBuilder(*MI.getParent()->getParent(), MI) + .addImm(Pred[0].getImm()) + .add(Pred[1]); } + } - MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCCTRL8 : PPC::BCCCTR8) - : (setLR ? PPC::BCCCTRL : PPC::BCCCTR))); - MachineInstrBuilder(*MI.getParent()->getParent(), MI) - .addImm(Pred[0].getImm()) - .add(Pred[1]); + if (MI.getOpcode() != OpC) { + // Because we are changing the Desc of the MI, we need remove the old + // implicit operands used by OldMCId, and set the implicit operands + // based on the new Desc of MI. + fixupImplicitDefUseOperands(MI, &OldMCID); return true; } diff --git a/llvm/test/CodeGen/PowerPC/ifcvt.mir b/llvm/test/CodeGen/PowerPC/ifcvt.mir --- a/llvm/test/CodeGen/PowerPC/ifcvt.mir +++ b/llvm/test/CodeGen/PowerPC/ifcvt.mir @@ -49,5 +49,5 @@ ; CHECK-LABEL: name: testBDZLR - ; CHECK: BDZLR implicit $lr, implicit $rm + ; CHECK: BDZLR implicit-def $ctr, implicit $ctr, implicit $lr, implicit $rm ...