[llvm] Promote the Pseudo Opcode of instructions that deduce the sign extension for extsw from 32 bits to 64 bits when eliminating the extsw instruction in PPCMIPeepholes optimization. (PR #85451)

Amy Kwan via llvm-commits llvm-commits at lists.llvm.org
Thu May 23 18:30:02 PDT 2024


================
@@ -5234,6 +5234,219 @@ 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;
+
+// The function will promote the instruction which defines the register `Reg`
+// in the parameter from a 32-bit to a 64-bit instruction if needed. The logic
+// used to check whether an instruction needs to be promoted or not is similar
+// to the logic used to check a defined register whether is isSignOrZeroExtended
+// or not in the function PPCInstrInfo::isSignOrZeroExtended. The
+// `PromoteInstr32To64ForEmliEXTSW` function is recursive. The parameter
+// BinOpDepth does not count all of the recursions. The parameter BinOpDepth is
+// incremented  only when `PromoteInstr32To64ForEmliEXTSW` calls itself more
+// than once. This is done to prevent exponential recursion.
+void PPCInstrInfo::PromoteInstr32To64ForEmliEXTSW(const Register &Reg,
+                                                  MachineRegisterInfo *MRI,
+                                                  unsigned BinOpDepth,
+                                                  LiveVariables *LV) const {
+  MachineInstr *MI = MRI->getVRegDef(Reg);
+  if (!MI)
+    return;
+
+  unsigned Opcode = MI->getOpcode();
+  bool IsNonSignedExtInstrNeedPromoted = false;
+  int NewOpcode = -1;
+
+  auto CheckAndSetNewOpcode = [&](int NewOpc) {
+    if (!IsNonSignedExtInstrNeedPromoted) {
+      NewOpcode = NewOpc;
+      IsNonSignedExtInstrNeedPromoted = true;
+    }
+  };
+
+  switch (Opcode) {
+  case PPC::OR:
+    CheckAndSetNewOpcode(PPC::OR8);
+    [[fallthrough]];
+  case PPC::ISEL:
+    CheckAndSetNewOpcode(PPC::ISEL8);
+    [[fallthrough]];
+  case PPC::OR8:
+  case PPC::PHI:
+    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();
+        PromoteInstr32To64ForEmliEXTSW(SrcReg, MRI, BinOpDepth + 1, LV);
+      }
+    }
+    break;
+  case PPC::COPY: {
+    // Refer to the logic of the `case PPC::COPY` statement in the function
+    // PPCInstrInfo::isSignOrZeroExtended().
+
+    Register SrcReg = MI->getOperand(1).getReg();
+    // In both ELFv1 and v2 ABI, method parameters and the return value
+    // are sign- or zero-extended.
+    const MachineFunction *MF = MI->getMF();
+    if (!MF->getSubtarget<PPCSubtarget>().isSVR4ABI()) {
+      // If this is a copy from another register, we recursively promote source.
----------------
amy-kwan wrote:

```suggestion
      // If this is a copy from another register, we recursively promote the source.
```

https://github.com/llvm/llvm-project/pull/85451


More information about the llvm-commits mailing list