Skip to content

[ValueTracking] Let ComputeKnownSignBits handle (shl (zext X), C) #97693

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions llvm/lib/Analysis/ValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3866,11 +3866,22 @@ 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), DemandedElts, 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, DemandedElts, Depth + 1, Q);
Tmp += TyBits - X->getType()->getScalarSizeInBits();
} else
Tmp =
ComputeNumSignBits(U->getOperand(0), DemandedElts, Depth + 1, Q);
if (ShAmt->uge(Tmp))
break; // Shifted all sign bits out.
Tmp2 = ShAmt->getZExtValue();
return Tmp - Tmp2;
}
Expand Down
30 changes: 11 additions & 19 deletions llvm/test/Analysis/ValueTracking/numsignbits-shl.ll
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,14 @@ define void @numsignbits_shl_zext(i8 %x) {
; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X]], 5
; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[ASHR]] to i16
; CHECK-NEXT: [[NSB4:%.*]] = shl i16 [[ZEXT]], 10
; CHECK-NEXT: [[AND14:%.*]] = and i16 [[NSB4]], 16384
; CHECK-NEXT: [[ADD14:%.*]] = add i16 [[AND14]], [[NSB4]]
; CHECK-NEXT: [[ADD14:%.*]] = and i16 [[NSB4]], 15360
; CHECK-NEXT: call void @escape(i16 [[ADD14]])
; CHECK-NEXT: [[AND13:%.*]] = and i16 [[NSB4]], 8192
; CHECK-NEXT: [[ADD13:%.*]] = add i16 [[AND13]], [[NSB4]]
; CHECK-NEXT: [[ADD13:%.*]] = and i16 [[NSB4]], 7168
; CHECK-NEXT: call void @escape(i16 [[ADD13]])
; CHECK-NEXT: [[AND12:%.*]] = and i16 [[NSB4]], 4096
; CHECK-NEXT: [[ADD12:%.*]] = add i16 [[AND12]], [[NSB4]]
; CHECK-NEXT: [[ADD12:%.*]] = and i16 [[NSB4]], 3072
; CHECK-NEXT: call void @escape(i16 [[ADD12]])
; CHECK-NEXT: [[AND11:%.*]] = and i16 [[NSB4]], 2048
; CHECK-NEXT: [[ADD11:%.*]] = add i16 [[AND11]], [[NSB4]]
; CHECK-NEXT: [[ADD11:%.*]] = add nsw i16 [[AND11]], [[NSB4]]
; CHECK-NEXT: call void @escape(i16 [[ADD11]])
; CHECK-NEXT: ret void
;
Expand Down Expand Up @@ -51,14 +48,12 @@ define void @numsignbits_shl_zext_shift_amounr_matches_extend(i8 %x) {
; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X]], 2
; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[ASHR]] to i16
; CHECK-NEXT: [[NSB3:%.*]] = shl nuw i16 [[ZEXT]], 8
; CHECK-NEXT: [[AND14:%.*]] = and i16 [[NSB3]], 16384
; CHECK-NEXT: [[ADD14:%.*]] = add i16 [[AND14]], [[NSB3]]
; CHECK-NEXT: [[ADD14:%.*]] = and i16 [[NSB3]], 16128
; CHECK-NEXT: call void @escape(i16 [[ADD14]])
; CHECK-NEXT: [[AND13:%.*]] = and i16 [[NSB3]], 8192
; CHECK-NEXT: [[ADD13:%.*]] = add i16 [[AND13]], [[NSB3]]
; CHECK-NEXT: [[ADD13:%.*]] = and i16 [[NSB3]], 7936
; CHECK-NEXT: call void @escape(i16 [[ADD13]])
; CHECK-NEXT: [[AND12:%.*]] = and i16 [[NSB3]], 4096
; CHECK-NEXT: [[ADD12:%.*]] = add i16 [[AND12]], [[NSB3]]
; CHECK-NEXT: [[ADD12:%.*]] = add nsw i16 [[AND12]], [[NSB3]]
; CHECK-NEXT: call void @escape(i16 [[ADD12]])
; CHECK-NEXT: ret void
;
Expand Down Expand Up @@ -132,17 +127,14 @@ define void @numsignbits_shl_zext_vector(<2 x i8> %x) {
; CHECK-NEXT: [[ASHR:%.*]] = ashr <2 x i8> [[X]], <i8 5, i8 5>
; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[ASHR]] to <2 x i16>
; CHECK-NEXT: [[NSB4:%.*]] = shl <2 x i16> [[ZEXT]], <i16 10, i16 10>
; CHECK-NEXT: [[AND14:%.*]] = and <2 x i16> [[NSB4]], <i16 16384, i16 16384>
; CHECK-NEXT: [[ADD14:%.*]] = add <2 x i16> [[AND14]], [[NSB4]]
; CHECK-NEXT: [[ADD14:%.*]] = and <2 x i16> [[NSB4]], <i16 15360, i16 15360>
; CHECK-NEXT: call void @escape2(<2 x i16> [[ADD14]])
; CHECK-NEXT: [[AND13:%.*]] = and <2 x i16> [[NSB4]], <i16 8192, i16 8192>
; CHECK-NEXT: [[ADD13:%.*]] = add <2 x i16> [[AND13]], [[NSB4]]
; CHECK-NEXT: [[ADD13:%.*]] = and <2 x i16> [[NSB4]], <i16 7168, i16 7168>
; CHECK-NEXT: call void @escape2(<2 x i16> [[ADD13]])
; CHECK-NEXT: [[AND12:%.*]] = and <2 x i16> [[NSB4]], <i16 4096, i16 4096>
; CHECK-NEXT: [[ADD12:%.*]] = add <2 x i16> [[AND12]], [[NSB4]]
; CHECK-NEXT: [[ADD12:%.*]] = and <2 x i16> [[NSB4]], <i16 3072, i16 3072>
; CHECK-NEXT: call void @escape2(<2 x i16> [[ADD12]])
; CHECK-NEXT: [[AND11:%.*]] = and <2 x i16> [[NSB4]], <i16 2048, i16 2048>
; CHECK-NEXT: [[ADD11:%.*]] = add <2 x i16> [[AND11]], [[NSB4]]
; CHECK-NEXT: [[ADD11:%.*]] = add nsw <2 x i16> [[AND11]], [[NSB4]]
; CHECK-NEXT: call void @escape2(<2 x i16> [[ADD11]])
; CHECK-NEXT: ret void
;
Expand Down
Loading