[llvm] fix a bug of PPCMIPeepholes which description in issue 71030 (PR #85451)
Amy Kwan via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 19 21:50:07 PDT 2024
================
@@ -5219,6 +5219,190 @@ bool PPCInstrInfo::isTOCSaveMI(const MachineInstr &MI) const {
// We limit the max depth to track incoming values of PHIs or binary ops
// (e.g. AND) to avoid excessive cost.
const unsigned MAX_BINOP_DEPTH = 1;
+
+void PPCInstrInfo::replaceInstrAfterElimExt32To64(const Register &Reg,
+ MachineRegisterInfo *MRI,
+ unsigned BinOpDepth,
+ LiveVariables *LV) const {
+ MachineInstr *MI = MRI->getVRegDef(Reg);
+ if (!MI)
+ return;
+
+ unsigned Opcode = MI->getOpcode();
+ bool IsRelplaceIntr = false;
+ switch (Opcode) {
+ case PPC::OR:
+ case PPC::OR8:
+ case PPC::PHI:
+ case PPC::ISEL:
+ if (BinOpDepth < MAX_BINOP_DEPTH) {
+ unsigned OperandEnd = 3, OperandStride = 1;
+ if (Opcode == PPC::PHI) {
+ OperandEnd = MI->getNumOperands();
+ OperandStride = 2;
+ }
+
+ for (unsigned I = 1; I != OperandEnd; I += OperandStride) {
+ assert(MI->getOperand(I).isReg() && "Operand must be register");
+ Register SrcReg = MI->getOperand(I).getReg();
+ replaceInstrAfterElimExt32To64(SrcReg, MRI, BinOpDepth + 1, LV);
+ }
+
+ if (Opcode == PPC::OR || Opcode == PPC::ISEL)
+ IsRelplaceIntr = true;
+ else
+ return;
+ }
+ break;
+ case PPC::COPY: {
+ Register SrcReg = MI->getOperand(1).getReg();
+ const MachineFunction *MF = MI->getMF();
+ if (!MF->getSubtarget<PPCSubtarget>().isSVR4ABI()) {
+ replaceInstrAfterElimExt32To64(SrcReg, MRI, BinOpDepth, LV);
+ return;
+ }
+ // From here on everything is SVR4ABI
+ if (MI->getParent()->getBasicBlock() == &MF->getFunction().getEntryBlock())
+ return;
+
+ if (SrcReg != PPC::X3) {
+ replaceInstrAfterElimExt32To64(SrcReg, MRI, BinOpDepth, LV);
+ return;
+ }
+ }
+ return;
+ case PPC::ORI:
+ case PPC::XORI:
+ case PPC::ORI8:
+ case PPC::XORI8:
+ case PPC::ORIS:
+ case PPC::XORIS:
+ case PPC::ORIS8:
+ case PPC::XORIS8: {
+ Register SrcReg = MI->getOperand(1).getReg();
+ replaceInstrAfterElimExt32To64(SrcReg, MRI, BinOpDepth, LV);
+
+ if (Opcode == PPC::ORI || Opcode == PPC::XORI || Opcode == PPC::ORIS ||
+ Opcode == PPC::ORIS || Opcode == PPC::XORIS)
+ IsRelplaceIntr = true;
+ else
+ return;
+ break;
+ }
+ case PPC::AND:
+ case PPC::AND8: {
+ if (BinOpDepth < MAX_BINOP_DEPTH) {
+ Register SrcReg1 = MI->getOperand(1).getReg();
+ replaceInstrAfterElimExt32To64(SrcReg1, MRI, BinOpDepth, LV);
+ Register SrcReg2 = MI->getOperand(2).getReg();
+ replaceInstrAfterElimExt32To64(SrcReg2, MRI, BinOpDepth, LV);
+ if (Opcode == PPC::AND)
+ IsRelplaceIntr = true;
+ else
+ return;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ const PPCInstrInfo *TII =
+ MI->getMF()->getSubtarget<PPCSubtarget>().getInstrInfo();
+ if ((definedBySignExtendingOp(Reg, MRI) && !TII->isZExt32To64(Opcode) &&
+ !isOpZeroOfSubwordPreincLoad(Opcode)) ||
+ IsRelplaceIntr) {
+
+ const TargetRegisterClass *RC = MRI->getRegClass(Reg);
+ assert(RC != &PPC::G8RCRegClass && RC != &PPC::G8RC_and_G8RC_NOX0RegClass &&
+ "Must be 32-bit Register!");
+
+ // Fix Me: Most of the pseudo-opcode of 64-bit instruction are equal to
+ // the pseudo-opcode of the 32-bit version of the same instruction plus
+ // one. However, there are some exceptions: PPC::ANDC_rec,
+ // PPC::ANDI_rec, PPC::ANDIS_rec.
+ unsigned NewOpcode = Opcode + 1;
+
+ if (Opcode == PPC::ANDC_rec)
+ NewOpcode = PPC::ANDC8_rec;
+ if (Opcode == PPC::ANDI_rec)
+ NewOpcode = PPC::ANDI8_rec;
+ if (Opcode == PPC::ANDIS_rec)
+ NewOpcode = PPC::ANDIS8_rec;
+
+ const TargetRegisterInfo *TRI = MRI->getTargetRegisterInfo();
+ const MCInstrDesc &MCID = TII->get(NewOpcode);
+
+ Register SrcReg = MI->getOperand(0).getReg();
+ const TargetRegisterClass *NewRC =
+ TRI->getRegClass(MCID.operands()[0].RegClass);
+ const TargetRegisterClass *SrcRC = MRI->getRegClass(SrcReg);
+
+ if (NewRC == SrcRC)
+ return;
+
+ DebugLoc DL = MI->getDebugLoc();
+ auto MBB = MI->getParent();
+
+ // Since the pseudo-opcode of the instruction is promoted from 32-bit to
+ // 64-bit, if the operand of the original instruction belongs to
+ // PPC::GRCRegClass or PPC::GPRC_and_GPRC_NOR0RegClass, we need to promote
+ // the operand to PPC::G8CRegClass or PPC::G8RC_and_G8RC_NOR0RegClass,
+ // respectively.
+ DenseMap<unsigned, Register> PromoteRegs;
+ DenseMap<unsigned, Register> ReCalRegs;
+ for (unsigned i = 1; i < MI->getNumOperands(); i++) {
+ MachineOperand &Oprand = MI->getOperand(i);
----------------
amy-kwan wrote:
```suggestion
MachineOperand &Operand = MI->getOperand(i);
```
I think we can use `Operand` instead of `Oprand` here and below.
https://github.com/llvm/llvm-project/pull/85451
More information about the llvm-commits
mailing list