[llvm] [RISCV] Expand constant multiplication for targets without M extension (PR #137195)
Max Graey via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 26 09:54:42 PDT 2025
================
@@ -15436,6 +15439,134 @@ 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,
+ uint64_t MulAmt) {
+ EVT VT = N->getValueType(0);
+ const uint64_t BitWidth = VT.getFixedSizeInBits();
+ SDLoc DL(N);
+
+ if (MulAmt == 0)
+ return DAG.getConstant(0, DL, N->getValueType(0));
+
+ // Try to factorize into (2^N) * (2^M_1 +/- 1) * (2^M_2 +/- 1) * ...
+ uint64_t E = MulAmt;
+ uint64_t TrailingZeros = 0;
+
+ while (E > 0 && (E & 1) == 0) {
+ E >>= 1;
+ TrailingZeros++;
+ }
----------------
MaxGraey wrote:
```suggestion
uint64_t TrailingZeros = llvm::countTrailingZeros(E);
```
https://github.com/llvm/llvm-project/pull/137195
More information about the llvm-commits
mailing list