[llvm] [PowerPC] Peephole address calculation in TOC memops (PR #76488)

Stefan Pintilie via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 22 17:50:07 PST 2024


================
@@ -7565,224 +7565,205 @@ static void reduceVSXSwap(SDNode *N, SelectionDAG *DAG) {
   DAG->ReplaceAllUsesOfValueWith(SDValue(N, 0), N->getOperand(0));
 }
 
-void PPCDAGToDAGISel::PeepholePPC64() {
-  SelectionDAG::allnodes_iterator Position = CurDAG->allnodes_end();
+static void peepholeMemOffset(SDNode *N, SelectionDAG *DAG,
+                              const PPCSubtarget *Subtarget) {
+  unsigned StorageOpcode = N->getMachineOpcode();
+  bool IsLoad = false;
+  SDValue MemOffset, MemBase;
 
-  while (Position != CurDAG->allnodes_begin()) {
-    SDNode *N = &*--Position;
-    // Skip dead nodes and any non-machine opcodes.
-    if (N->use_empty() || !N->isMachineOpcode())
-      continue;
-
-    if (isVSXSwap(SDValue(N, 0)))
-      reduceVSXSwap(N, CurDAG);
-
-    unsigned FirstOp;
-    unsigned StorageOpcode = N->getMachineOpcode();
-    bool RequiresMod4Offset = false;
-
-    switch (StorageOpcode) {
-    default: continue;
+  // TODO: Enable for AIX 32-bit
+  if (!Subtarget->isPPC64())
+    return;
 
-    case PPC::LWA:
-    case PPC::LD:
-    case PPC::DFLOADf64:
-    case PPC::DFLOADf32:
-      RequiresMod4Offset = true;
-      [[fallthrough]];
-    case PPC::LBZ:
-    case PPC::LBZ8:
-    case PPC::LFD:
-    case PPC::LFS:
-    case PPC::LHA:
-    case PPC::LHA8:
-    case PPC::LHZ:
-    case PPC::LHZ8:
-    case PPC::LWZ:
-    case PPC::LWZ8:
-      FirstOp = 0;
-      break;
+  // Global must be word-aligned for LD, STD, LWA.
+  unsigned ExtraAlign = 0;
+  switch (StorageOpcode) {
+  default:
+    return;
+  case PPC::LWA:
+  case PPC::LD:
+  case PPC::DFLOADf64:
+  case PPC::DFLOADf32:
+    ExtraAlign = 4;
+    [[fallthrough]];
+  case PPC::LBZ:
+  case PPC::LBZ8:
+  case PPC::LFD:
+  case PPC::LFS:
+  case PPC::LHA:
+  case PPC::LHA8:
+  case PPC::LHZ:
+  case PPC::LHZ8:
+  case PPC::LWZ:
+  case PPC::LWZ8:
+    IsLoad = true;
+    MemOffset = N->getOperand(0);
+    MemBase = N->getOperand(1);
+    break;
+  case PPC::STD:
+  case PPC::DFSTOREf64:
+  case PPC::DFSTOREf32:
+    ExtraAlign = 4;
+    [[fallthrough]];
+  case PPC::STB:
+  case PPC::STB8:
+  case PPC::STFD:
+  case PPC::STFS:
+  case PPC::STH:
+  case PPC::STH8:
+  case PPC::STW:
+  case PPC::STW8:
+    MemOffset = N->getOperand(1);
+    MemBase = N->getOperand(2);
+    break;
+  }
 
-    case PPC::STD:
-    case PPC::DFSTOREf64:
-    case PPC::DFSTOREf32:
-      RequiresMod4Offset = true;
-      [[fallthrough]];
-    case PPC::STB:
-    case PPC::STB8:
-    case PPC::STFD:
-    case PPC::STFS:
-    case PPC::STH:
-    case PPC::STH8:
-    case PPC::STW:
-    case PPC::STW8:
-      FirstOp = 1;
-      break;
+  auto CheckAlign = [DAG](const SDValue &Val, unsigned TargetAlign) {
+    if (TargetAlign == 0)
+      return true;
+    if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(Val)) {
+      const GlobalValue *GV = GA->getGlobal();
+      Align Alignment = GV->getPointerAlignment(DAG->getDataLayout());
+      if (Alignment < TargetAlign)
+        return false;
     }
+    return true;
+  };
 
-    // If this is a load or store with a zero offset, or within the alignment,
-    // we may be able to fold an add-immediate into the memory operation.
-    // The check against alignment is below, as it can't occur until we check
-    // the arguments to N
-    if (!isa<ConstantSDNode>(N->getOperand(FirstOp)))
-      continue;
+  // Only additions with constant offsets will be folded.
+  if (!isa<ConstantSDNode>(MemOffset) || !MemBase.isMachineOpcode())
+    return;
 
-    SDValue Base = N->getOperand(FirstOp + 1);
-    if (!Base.isMachineOpcode())
-      continue;
+  // Some flags in addition needs to be carried to new memop.
+  std::optional<PPCII::TOF> NewOpFlags;
+  SDValue ImmOpnd, RegOpnd;
+  if (MemBase.getNumOperands() == 2) {
+    ImmOpnd = MemBase.getOperand(1);
----------------
stefanp-ibm wrote:

I agree. It seems odd to just grab the operands without knowing what the opcode is.

Also, in the case where `MemBase.getNumOperands() != 2` it looks like `ImmOpnd` and `RegOpnd` are not defined. If we are sure that the number of operands is always 2 I would add an assert instead of this if statement to make it clear. 

Of course, the advantage of knowing the opcode before you get the operands is that you will know the number and order of the operands. 

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


More information about the llvm-commits mailing list