[llvm] [TargetLowering] Pull similar code out of the forceExpandWideMUL into a helper. NFC (PR #124371)
Sergei Barannikov via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 24 16:44:27 PST 2025
================
@@ -10857,6 +10857,64 @@ SDValue TargetLowering::expandShlSat(SDNode *Node, SelectionDAG &DAG) const {
return DAG.getSelect(dl, VT, Cond, SatVal, Result);
}
+void TargetLowering::forceExpandMultiply(SelectionDAG &DAG, const SDLoc &dl,
+ bool Signed, SDValue &Lo, SDValue &Hi,
+ SDValue LHS, SDValue RHS,
+ SDValue HiLHS, SDValue HiRHS) const {
+ EVT VT = LHS.getValueType();
+ assert(RHS.getValueType() == VT && "Mismatching operand types");
+
+ assert((HiLHS && HiRHS) || (!HiLHS && !HiRHS));
+ assert((!Signed || !HiLHS) &&
+ "Signed flag should only be set when HiLHS and RiRHS are null");
+
+ // We'll expand the multiplication by brute force because we have no other
+ // options. This is a trivially-generalized version of the code from
+ // Hacker's Delight (itself derived from Knuth's Algorithm M from section
+ // 4.3.1). If Signed is set, we can use arithmetic right shifts to propagate
+ // sign bits while calculating the Hi half.
+ unsigned Bits = VT.getSizeInBits();
+ unsigned HalfBits = Bits / 2;
+ SDValue Mask = DAG.getConstant(APInt::getLowBitsSet(Bits, HalfBits), dl, VT);
+ SDValue LL = DAG.getNode(ISD::AND, dl, VT, LHS, Mask);
+ SDValue RL = DAG.getNode(ISD::AND, dl, VT, RHS, Mask);
+
+ SDValue T = DAG.getNode(ISD::MUL, dl, VT, LL, RL);
+ SDValue TL = DAG.getNode(ISD::AND, dl, VT, T, Mask);
+
+ SDValue Shift = DAG.getShiftAmountConstant(HalfBits, VT, dl);
+ // This is always an unsigned shift.
+ SDValue TH = DAG.getNode(ISD::SRL, dl, VT, T, Shift);
+
+ unsigned ShiftOpc = Signed ? ISD::SRA : ISD::SRL;
+ SDValue LH = DAG.getNode(ShiftOpc, dl, VT, LHS, Shift);
+ SDValue RH = DAG.getNode(ShiftOpc, dl, VT, RHS, Shift);
+
+ SDValue U =
+ DAG.getNode(ISD::ADD, dl, VT, DAG.getNode(ISD::MUL, dl, VT, LH, RL), TH);
+ SDValue UL = DAG.getNode(ISD::AND, dl, VT, U, Mask);
+ SDValue UH = DAG.getNode(ShiftOpc, dl, VT, U, Shift);
+
+ SDValue V =
+ DAG.getNode(ISD::ADD, dl, VT, DAG.getNode(ISD::MUL, dl, VT, LL, RH), UL);
+ SDValue VH = DAG.getNode(ShiftOpc, dl, VT, V, Shift);
+
+ Lo = DAG.getNode(ISD::ADD, dl, VT, TL,
+ DAG.getNode(ISD::SHL, dl, VT, V, Shift));
+
+ Hi = DAG.getNode(ISD::ADD, dl, VT, DAG.getNode(ISD::MUL, dl, VT, LH, RH),
+ DAG.getNode(ISD::ADD, dl, VT, UH, VH));
+
+ // If HiLHS and HiRHS are set, multiply them by the opposite low part and add
+ // them to products to Hi.
----------------
s-barannikov wrote:
```suggestion
// the products to Hi.
```
https://github.com/llvm/llvm-project/pull/124371
More information about the llvm-commits
mailing list