[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