[llvm] [SelectionDAG] Optimize 32-bit udiv with 33-bit magic constants on 64-bit targets (PR #181288)

via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 12 22:51:40 PST 2026


github-actions[bot] wrote:

<!--LLVM CODE FORMAT COMMENT: {clang-format}-->


:warning: C/C++ code formatter, clang-format found issues in your code. :warning:

<details>
<summary>
You can test this locally with the following command:
</summary>

``````````bash
git-clang-format --diff origin/main HEAD --extensions cpp -- llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp --diff_from_common_commit
``````````

:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:

</details>

<details>
<summary>
View the diff from clang-format here.
</summary>

``````````diff
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 2d149a10c..34263d667 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -6792,8 +6792,10 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
 
   bool UseNPQ = false, UsePreShift = false, UsePostShift = false;
   EVT WideVT64 = EVT::getIntegerVT(*DAG.getContext(), 64);
-  bool HasWideVT64MULHU = isOperationLegalOrCustom(ISD::MULHU, WideVT64, IsAfterLegalization);
-  bool HasWideVT64UMUL_LOHI = isOperationLegalOrCustom(ISD::UMUL_LOHI, WideVT64, IsAfterLegalization);
+  bool HasWideVT64MULHU =
+      isOperationLegalOrCustom(ISD::MULHU, WideVT64, IsAfterLegalization);
+  bool HasWideVT64UMUL_LOHI =
+      isOperationLegalOrCustom(ISD::UMUL_LOHI, WideVT64, IsAfterLegalization);
   bool Use33BitOptimization = false;
   SmallVector<SDValue, 16> PreShifts, PostShifts, MagicFactors, NPQFactors;
 
@@ -6816,21 +6818,24 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
           UnsignedDivisionByConstantInfo::get(
               Divisor, std::min(KnownLeadingZeros, Divisor.countl_zero()));
 
-      // For 32-bit division with IsAdd (33-bit magic case), use optimized method:
-      // preshift c by (64-a) bits to eliminate runtime shift.
-      // This requires 64x64->128 bit multiplication.
-      // Only apply to scalar types since SIMD lacks 64x64->128 high multiply.
-      // Note: IsAdd=true implies PreShift=0 by algorithm design.
-      // Check if 64-bit MULHU is available before applying this optimization.
-        if (EltBits == 32 && !VT.isVector() && (HasWideVT64MULHU || HasWideVT64UMUL_LOHI) && magics.IsAdd) {
+      // For 32-bit division with IsAdd (33-bit magic case), use optimized
+      // method: preshift c by (64-a) bits to eliminate runtime shift. This
+      // requires 64x64->128 bit multiplication. Only apply to scalar types
+      // since SIMD lacks 64x64->128 high multiply. Note: IsAdd=true implies
+      // PreShift=0 by algorithm design. Check if 64-bit MULHU is available
+      // before applying this optimization.
+      if (EltBits == 32 && !VT.isVector() &&
+          (HasWideVT64MULHU || HasWideVT64UMUL_LOHI) && magics.IsAdd) {
         // For IsAdd case, actual magic constant is 2^32 + Magic (33-bit)
         unsigned OriginalShift = magics.PostShift + 33;
-        APInt RealMagic = APInt(65, 1).shl(32) + magics.Magic.zext(65); // 2^32 + Magic
+        APInt RealMagic =
+            APInt(65, 1).shl(32) + magics.Magic.zext(65); // 2^32 + Magic
         Use33BitOptimization = true;
-        // Shift the constant left by (64 - OriginalShift) to avoid runtime shift
+        // Shift the constant left by (64 - OriginalShift) to avoid runtime
+        // shift
         APInt ShiftedMagic = RealMagic.shl(64 - OriginalShift).trunc(64);
         MagicFactor = DAG.getConstant(ShiftedMagic, dl,
-                                       EVT::getIntegerVT(*DAG.getContext(), 64));
+                                      EVT::getIntegerVT(*DAG.getContext(), 64));
         PreShift = DAG.getConstant(0, dl, ShSVT);
         PostShift = DAG.getConstant(0, dl, ShSVT);
         NPQFactor = DAG.getConstant(APInt::getZero(SVTBits), dl, SVT);
@@ -6897,9 +6902,8 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
     SDValue X64 = DAG.getNode(ISD::ZERO_EXTEND, dl, WideVT64, N0);
 
     // Get the pre-shifted constant (it's already in MagicFactor as i64)
-    SDValue MagicFactor64 = isa<ConstantSDNode>(MagicFactor)
-        ? MagicFactor
-        : MagicFactors[0];
+    SDValue MagicFactor64 =
+        isa<ConstantSDNode>(MagicFactor) ? MagicFactor : MagicFactors[0];
 
     SDValue Result;
     // Perform 64x64 -> 128 multiplication and extract high 64 bits
@@ -6909,16 +6913,17 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
       // Truncate back to i32
       Result = DAG.getNode(ISD::TRUNCATE, dl, VT, High);
     } else if (HasWideVT64UMUL_LOHI) {
-      SDValue LoHi = DAG.getNode(ISD::UMUL_LOHI, dl,
-                                  DAG.getVTList(WideVT64, WideVT64),
-                                  X64, MagicFactor64);
+      SDValue LoHi =
+          DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(WideVT64, WideVT64),
+                      X64, MagicFactor64);
       SDValue High = SDValue(LoHi.getNode(), 1);
       Created.push_back(LoHi.getNode());
       Result = DAG.getNode(ISD::TRUNCATE, dl, VT, High);
     }
 
     // Handle divisor == 1 case with SELECT
-    EVT SetCCVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
+    EVT SetCCVT =
+        getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
     SDValue One = DAG.getConstant(1, dl, VT);
     SDValue IsOne = DAG.getSetCC(dl, SetCCVT, N1, One, ISD::SETEQ);
     return DAG.getSelect(dl, VT, IsOne, N0, Result);

``````````

</details>


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


More information about the llvm-commits mailing list