[llvm] [ValueTracking] Let ComputeKnownSignBits handle (shl (zext X), C) (PR #97693)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 4 09:55:46 PDT 2024
================
@@ -3757,11 +3757,21 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
}
case Instruction::Shl: {
const APInt *ShAmt;
+ Value *X = nullptr;
if (match(U->getOperand(1), m_APInt(ShAmt))) {
// shl destroys sign bits.
- Tmp = ComputeNumSignBits(U->getOperand(0), Depth + 1, Q);
- if (ShAmt->uge(TyBits) || // Bad shift.
- ShAmt->uge(Tmp)) break; // Shifted all sign bits out.
+ if (ShAmt->uge(TyBits))
+ break; // Bad shift.
+ // We can look through a zext (more or less treating it as a sext) if
+ // all extended bits are shifted out.
+ if (match(U->getOperand(0), m_ZExt(m_Value(X))) &&
+ ShAmt->uge(TyBits - X->getType()->getScalarSizeInBits())) {
+ Tmp = ComputeNumSignBits(X, Depth + 1, Q);
----------------
dtcxzyw wrote:
Regression: https://alive2.llvm.org/ce/z/tcsmgq
Now `src` cannot be folded into `tgt`.
```
define i32 @src(i32 %add.i.i370) {
%shr.i.i = ashr i32 %add.i.i370, 5
%conv.i.i371 = zext i32 %shr.i.i to i64
%shl.i.i = shl i64 %conv.i.i371, 34
%conv6.i = ashr exact i64 %shl.i.i, 32
%conv.i41.i = trunc nsw i64 %conv6.i to i32
ret i32 %conv.i41.i
}
define i32 @tgt(i32 %add.i.i370) {
%121 = ashr i32 %add.i.i370, 3
%122 = and i32 %121, -4
ret i32 %122
}
```
https://github.com/llvm/llvm-project/pull/97693
More information about the llvm-commits
mailing list