[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