[llvm] [InstCombine] Fold `X udiv Y` to `X lshr cttz(Y)` if Y is a power of 2 (PR #121386)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 31 10:42:16 PST 2024
================
@@ -1632,6 +1632,16 @@ Instruction *InstCombinerImpl::visitUDiv(BinaryOperator &I) {
I, Builder.CreateLShr(Op0, Res, I.getName(), I.isExact()));
}
+ // Op0 udiv Op1 -> Op0 lshr cttz(Op1), if Op1 is a power of 2.
+ if (isKnownToBeAPowerOfTwo(Op1, /*OrZero*/ true, /*Depth*/ 0, &I)) {
+ // This will increase instruction count but it's okay
+ // since bitwise operations are substantially faster than
+ // division.
+ auto *Cttz =
+ Builder.CreateBinaryIntrinsic(Intrinsic::cttz, Op1, Builder.getTrue());
+ return BinaryOperator::CreateLShr(Op0, Cttz);
+ }
----------------
goldsteinn wrote:
You can preserve exact: https://alive2.llvm.org/ce/z/n8jnNn
Also it might be cleaner to merge this with the above fold using `takeLog2`. Maybe create a lambda like:
```
auto GetLog2Denom = [&](Value * Denom) {
if (auto * R = takeLog2(Denom, ...) {
return R;
}
if (IsKnownPowerOf2(Denom, ....) {
return Builder.CreateBinaryIntrinsic(cttz, ....);
}
return nullptr;
}
```
Then:
```
if(auto * Res = GetLog2Denom(Op1)) {
/// Above fold using `takeLog2`
}
```
https://github.com/llvm/llvm-project/pull/121386
More information about the llvm-commits
mailing list