[llvm] [LegalizeTypes] Expand 128-bit UDIV/UREM by constant via Chunk Addition (PR #146238)

Marius Kamp via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 26 01:53:36 PDT 2025


================
@@ -8030,6 +8028,80 @@ 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. Let's look for a smaller chunk
+    // width where (1 << ChunkWidth) mod Divisor == 1.
+    // This ensures that the sum of all such chunks modulo Divisor
+    // is equivalent to the original value modulo Divisor.
+    const APInt &Divisor = CN->getAPIntValue();
+    unsigned BitWidth = VT.getScalarSizeInBits();
+    unsigned BestChunkWidth = 0;
+
+    // We restrict to small chunk sizes (e.g., ≤ 32 bits) to ensure that all
+    // operations remain legal on most targets.
+    unsigned MaxChunk = 32;
+    for (int i = MaxChunk; i >= 1; --i) {
----------------
mskamp wrote:

It is not necessary to check all values in [1; MaxChunk]. It suffices to check the range (MaxChunk/2; MaxChunk] because non-existence of a suitable chunk width in this range implies non-existence in the whole range. [Proof](https://github.com/mskamp/proofs/blob/2f6c33b9e32169c5993c82dc20d1466a8de92706/programming/llvm/URemChunks.thy#L62).

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


More information about the llvm-commits mailing list