[llvm] r339346 - [TargetLowering] Add BuildSDIVPattern helper to BuildExactSDIV (NFCI).
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 9 06:56:04 PDT 2018
Author: rksimon
Date: Thu Aug 9 06:56:04 2018
New Revision: 339346
URL: http://llvm.org/viewvc/llvm-project?rev=339346&view=rev
Log:
[TargetLowering] Add BuildSDIVPattern helper to BuildExactSDIV (NFCI).
As requested in D50392, pull the magic constant calculations out into a helper function.
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=339346&r1=339345&r2=339346&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Thu Aug 9 06:56:04 2018
@@ -3440,34 +3440,43 @@ static SDValue BuildExactSDIV(const Targ
EVT VT = N->getValueType(0);
EVT ShVT = TLI.getShiftAmountTy(VT, DAG.getDataLayout());
+ auto BuildSDIVPattern = [](APInt Divisor, unsigned &Shift, APInt &Factor) {
+ bool UseSRA = false;
+ Shift = Divisor.countTrailingZeros();
+ if (Shift) {
+ Divisor.ashrInPlace(Shift);
+ UseSRA = true;
+ }
+ // Calculate the multiplicative inverse, using Newton's method.
+ APInt t;
+ Factor = Divisor;
+ while ((t = Divisor * Factor) != 1)
+ Factor *= APInt(Divisor.getBitWidth(), 2) - t;
+ return UseSRA;
+ };
+
ConstantSDNode *C = isConstOrConstSplat(Op1);
if (!C || C->isNullValue())
return SDValue();
- APInt d = C->getAPIntValue();
- assert(d != 0 && "Division by zero!");
+ APInt FactorVal;
+ unsigned ShiftVal;
+ bool UseSRA = BuildSDIVPattern(C->getAPIntValue(), ShiftVal, FactorVal);
+ SDValue Shift = DAG.getConstant(ShiftVal, dl, ShVT);
+ SDValue Factor = DAG.getConstant(FactorVal, dl, VT);
SDValue Res = Op0;
// Shift the value upfront if it is even, so the LSB is one.
- unsigned ShAmt = d.countTrailingZeros();
- if (ShAmt) {
+ if (UseSRA) {
// TODO: For UDIV use SRL instead of SRA.
- SDValue Amt = DAG.getConstant(ShAmt, dl, ShVT);
SDNodeFlags Flags;
Flags.setExact(true);
- Res = DAG.getNode(ISD::SRA, dl, VT, Res, Amt, Flags);
+ Res = DAG.getNode(ISD::SRA, dl, VT, Res, Shift, Flags);
Created.push_back(Res.getNode());
- d.ashrInPlace(ShAmt);
}
- // Calculate the multiplicative inverse, using Newton's method.
- APInt t, xn = d;
- while ((t = d*xn) != 1)
- xn *= APInt(d.getBitWidth(), 2) - t;
-
- SDValue Mul = DAG.getConstant(xn, dl, VT);
- return DAG.getNode(ISD::MUL, dl, VT, Res, Mul);
+ return DAG.getNode(ISD::MUL, dl, VT, Res, Factor);
}
SDValue TargetLowering::BuildSDIVPow2(SDNode *N, const APInt &Divisor,
More information about the llvm-commits
mailing list