[llvm] [RISCV] Expand constant multiplication for targets without M extension (PR #137195)

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Wed May 14 10:50:25 PDT 2025


================
@@ -15407,6 +15408,105 @@ static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG,
   return combineSelectAndUseCommutative(N, DAG, /*AllOnes*/ false, Subtarget);
 }
 
+static SDValue expandMulToNAFSequence(SDNode *N, SelectionDAG &DAG,
+                                      const SDLoc &DL, uint64_t MulAmt) {
+  EVT VT = N->getValueType(0);
+  const uint64_t BitWidth = VT.getFixedSizeInBits();
+
+  // Find the Non-adjacent form of the multiplier.
+  llvm::SmallVector<std::pair<bool, uint64_t>> Sequence; // {isAdd, shamt}
+  for (uint64_t E = MulAmt, I = 0; E && I < BitWidth; ++I, E >>= 1) {
+    if (E & 1) {
+      bool IsAdd = (E & 3) == 1;
+      Sequence.push_back({IsAdd, I});
+      E -= IsAdd ? 1 : -1;
+    }
+  }
+
+  SDValue Result = DAG.getConstant(0, DL, N->getValueType(0));
+  SDValue N0 = N->getOperand(0);
+
+  for (const auto &Op : Sequence) {
+    SDValue ShiftVal;
+    if (Op.second > 0)
+      ShiftVal =
+          DAG.getNode(ISD::SHL, DL, VT, N0, DAG.getConstant(Op.second, DL, VT));
+    else
+      ShiftVal = N0;
+
+    ISD::NodeType AddSubOp = Op.first ? ISD::ADD : ISD::SUB;
+    Result = DAG.getNode(AddSubOp, DL, VT, Result, ShiftVal);
+  }
+  return Result;
+}
+// Try to expand a multiply to a sequence of shifts and add/subs,
+// for a machine without native mul instruction.
+static SDValue expandMulToBasicOps(SDNode *N, SelectionDAG &DAG,
----------------
preames wrote:

Would you mind dropping this from the current patch, and using only the expandMulToNAFSequence scheme?  You can add back the second option in a second review, I just want to focus review time.  

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


More information about the llvm-commits mailing list