[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