[llvm] [InstCombine] Support division of numbers that can be converted to a shift (PR #88220)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 10 14:26:44 PDT 2024
================
@@ -1149,6 +1149,35 @@ Instruction *InstCombinerImpl::commonIDivTransforms(BinaryOperator &I) {
Mul->setHasNoSignedWrap(OBO->hasNoSignedWrap());
return Mul;
}
+
+ // If we can reduce these functions so they can factor out to a shift or
+ // something similar Why not? i.e Reduce (X * 150/100) -> (X * 3) >> 1
+
+ // (X * C1)/C2 -> X * (C1/C3) >> log2(C2/C3) where C3 divides exactly C1
+ // and C2 and C2/C3 is a power of 2.
+ // This WILL require NUW, and if it is sdiv then it also requires NSW
+ if (Op0->hasOneUse() && C1->isStrictlyPositive() &&
+ C2->isStrictlyPositive()) {
+ APInt C3 = APIntOps::GreatestCommonDivisor(*C1, *C2);
+ APInt Q(C2->getBitWidth(), /*val=*/0ULL, IsSigned);
+
+ // Returns false if division by 0
+ if (isMultiple(*C2, C3, Q, IsSigned) && Q.isPowerOf2()) {
+ auto *OBO = cast<OverflowingBinaryOperator>(Op0);
+ if (OBO->hasNoUnsignedWrap() &&
+ (!IsSigned || OBO->hasNoSignedWrap())) {
+
+ APInt C4 = IsSigned ? C1->sdiv(C3) : C1->udiv(C3);
+ auto *Mul =
+ Builder.CreateMul(X, ConstantInt::get(Ty, C4), "", true, true);
----------------
goldsteinn wrote:
comment the `true, true`.
https://github.com/llvm/llvm-project/pull/88220
More information about the llvm-commits
mailing list