[llvm] [SelectionDAG] Use Magic Algorithm for Splitting UDIV/UREM by Constant (PR #154968)
Marius Kamp via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 26 04:36:09 PDT 2026
================
@@ -8352,6 +8325,157 @@ bool TargetLowering::expandDIVREMByConstant(SDNode *N,
return true;
}
+bool TargetLowering::expandUDIVREMByConstantViaUMulHiMagic(
+ SDNode *N, const APInt &Divisor, SmallVectorImpl<SDValue> &Result,
+ EVT HiLoVT, SelectionDAG &DAG, SDValue LL, SDValue LH) const {
+
+ SDValue N0 = N->getOperand(0);
+ EVT VT = N0->getValueType(0);
+ SDLoc DL{N};
+
+ assert(!Divisor.isOne() && "Magic algorithm does not work for division by 1");
+
+ // This helper creates a MUL_LOHI of the pair (LL, LH) by a constant.
+ auto MakeMUL_LOHIByConst = [&](unsigned Opc, SDValue LL, SDValue LH,
+ const APInt &Const,
+ SmallVectorImpl<SDValue> &Result) {
+ SDValue LHS = DAG.getNode(ISD::BUILD_PAIR, DL, VT, LL, LH);
+ SDValue RHS = DAG.getConstant(Const, DL, VT);
+ auto [RL, RH] = DAG.SplitScalar(RHS, DL, HiLoVT, HiLoVT);
+ return expandMUL_LOHI(Opc, VT, DL, LHS, RHS, Result, HiLoVT, DAG,
+ TargetLowering::MulExpansionKind::OnlyLegalOrCustom,
+ LL, LH, RL, RH);
+ };
+
+ // This helper creates an ADD/SUB of the pairs (LL, LH) and (RL, RH).
+ auto MakeAddSubLong = [&](unsigned Opc, SDValue LL, SDValue LH, SDValue RL,
+ SDValue RH) {
+ SDValue AddSubNode =
+ DAG.getNode(Opc == ISD::ADD ? ISD::UADDO : ISD::USUBO, DL,
+ DAG.getVTList(HiLoVT, MVT::i1), LL, RL);
+ SDValue OutL, OutH, Overflow;
+ expandUADDSUBO(AddSubNode.getNode(), OutL, Overflow, DAG);
----------------
mskamp wrote:
Right, this is not necessary. While at it, I've improved codegen a bit as well.
https://github.com/llvm/llvm-project/pull/154968
More information about the llvm-commits
mailing list