[llvm] [LegalizeTypes] Expand UDIV/UREM by constant via chunk summation (PR #146238)

Shivam Gupta via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 17 04:50:03 PDT 2026


================
@@ -8233,6 +8231,68 @@ bool TargetLowering::expandDIVREMByConstant(SDNode *N,
                               DAG.getConstant(0, dl, HiLoVT));
       Sum = DAG.getNode(ISD::ADD, dl, HiLoVT, Sum, Carry);
     }
+  } else {
+    // If we cannot split in two halves, look for a smaller chunk width W
+    // such that (1 << W) % Divisor == 1.
+    const APInt &Divisor = CN->getAPIntValue();
+    unsigned BitWidth = VT.getScalarSizeInBits();
+    unsigned BestChunkWidth = 0;
+
+    // Determine the legal scalar integer type for chunk operations.
+    EVT LegalVT = getTypeToTransformTo(*DAG.getContext(), VT);
+    unsigned LegalWidth = LegalVT.getScalarSizeInBits();
+    unsigned MaxChunk = std::min<unsigned>(LegalWidth, BitWidth);
+
+    // Precompute 2^MaxChunk mod Divisor
+    APInt Mod(Divisor.getBitWidth(), 1);
+    for (unsigned K = 0; K != MaxChunk; ++K)
+      Mod = Mod.shl(1).urem(Divisor);
----------------
xgupta wrote:

It is because doing 2^I is expensive for each I inside the loop so computed 2^MaxChunk once and did backward search from MaxChunk with inverse multiply operation to find BestChunkWidth.


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


More information about the llvm-commits mailing list