[llvm] [InstCombine] Fold `lshr -> zext -> shl` patterns (PR #147737)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 11 11:19:17 PDT 2025
================
@@ -978,6 +1025,50 @@ Instruction *InstCombinerImpl::foldLShrOverflowBit(BinaryOperator &I) {
return new ZExtInst(Overflow, Ty);
}
+/// If the operand \p Op of a zext-ed left shift \p I is a logically
+/// right-shifted value, try to fold the opposing shifts.
+static Instruction *foldShrThroughZExtedShl(BinaryOperator &I, Value *Op,
+ unsigned ShlAmt,
+ InstCombinerImpl &IC,
+ const DataLayout &DL) {
+ Type *DestTy = I.getType();
+ const unsigned InnerBitWidth = Op->getType()->getScalarSizeInBits();
+
+ // Determine if the operand is effectively right-shifted by counting the
+ // known leading zero bits.
+ KnownBits Known = IC.computeKnownBits(Op, nullptr);
+ const unsigned MaxInnerShrAmt = Known.countMinLeadingZeros();
+ if (MaxInnerShrAmt == 0)
+ return nullptr;
+ APInt ShrMask =
+ APInt::getLowBitsSet(InnerBitWidth, std::min(MaxInnerShrAmt, ShlAmt) + 1);
+
+ // Undo the maximal inner right shift amount that simplifies the overall
+ // computation.
+ if (!refineEvaluableShiftMask(Op, ShrMask, /*IsLeftShift=*/true, IC, nullptr))
+ return nullptr;
+
----------------
dtcxzyw wrote:
I added an `if (!ShrMask.isPowerOf2()) return nullptr` check here, and all tests were still passed. I guess it may be helpful to avoid introducing new shifts in `getShiftedValue`. Not sure if it can avoid the regression in https://github.com/dtcxzyw/llvm-opt-benchmark/pull/2662/commits/876efdaecd0a0b9b8b03b3aa83ed1568274ea511#r2267345986.
https://github.com/llvm/llvm-project/pull/147737
More information about the llvm-commits
mailing list