Skip to content

Commit 523845f

Browse files
bjopeyuxuanchen1997
authored andcommitted
[ValueTracking] Let ComputeKnownSignBits handle (shl (zext X), C) (#97693)
Summary: Add simple support for looking through a zext when doing ComputeKnownSignBits for shl. This is valid for the case when all extended bits are shifted out, because then the number of sign bits can be found by analysing the zext operand. The solution here is simple as it only handle a single zext (not passing remaining left shift amount during recursion). It could be possible to generalize this in the future by for example passing an 'OffsetFromMSB' parameter to ComputeNumSignBitsImpl, telling it to calculate number of sign bits starting at some offset from the most significant bit. Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60251376
1 parent ab493a9 commit 523845f

File tree

2 files changed

+25
-22
lines changed

2 files changed

+25
-22
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3866,11 +3866,22 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
38663866
}
38673867
case Instruction::Shl: {
38683868
const APInt *ShAmt;
3869+
Value *X = nullptr;
38693870
if (match(U->getOperand(1), m_APInt(ShAmt))) {
38703871
// shl destroys sign bits.
3871-
Tmp = ComputeNumSignBits(U->getOperand(0), DemandedElts, Depth + 1, Q);
3872-
if (ShAmt->uge(TyBits) || // Bad shift.
3873-
ShAmt->uge(Tmp)) break; // Shifted all sign bits out.
3872+
if (ShAmt->uge(TyBits))
3873+
break; // Bad shift.
3874+
// We can look through a zext (more or less treating it as a sext) if
3875+
// all extended bits are shifted out.
3876+
if (match(U->getOperand(0), m_ZExt(m_Value(X))) &&
3877+
ShAmt->uge(TyBits - X->getType()->getScalarSizeInBits())) {
3878+
Tmp = ComputeNumSignBits(X, DemandedElts, Depth + 1, Q);
3879+
Tmp += TyBits - X->getType()->getScalarSizeInBits();
3880+
} else
3881+
Tmp =
3882+
ComputeNumSignBits(U->getOperand(0), DemandedElts, Depth + 1, Q);
3883+
if (ShAmt->uge(Tmp))
3884+
break; // Shifted all sign bits out.
38743885
Tmp2 = ShAmt->getZExtValue();
38753886
return Tmp - Tmp2;
38763887
}

llvm/test/Analysis/ValueTracking/numsignbits-shl.ll

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,14 @@ define void @numsignbits_shl_zext(i8 %x) {
1010
; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X]], 5
1111
; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[ASHR]] to i16
1212
; CHECK-NEXT: [[NSB4:%.*]] = shl i16 [[ZEXT]], 10
13-
; CHECK-NEXT: [[AND14:%.*]] = and i16 [[NSB4]], 16384
14-
; CHECK-NEXT: [[ADD14:%.*]] = add i16 [[AND14]], [[NSB4]]
13+
; CHECK-NEXT: [[ADD14:%.*]] = and i16 [[NSB4]], 15360
1514
; CHECK-NEXT: call void @escape(i16 [[ADD14]])
16-
; CHECK-NEXT: [[AND13:%.*]] = and i16 [[NSB4]], 8192
17-
; CHECK-NEXT: [[ADD13:%.*]] = add i16 [[AND13]], [[NSB4]]
15+
; CHECK-NEXT: [[ADD13:%.*]] = and i16 [[NSB4]], 7168
1816
; CHECK-NEXT: call void @escape(i16 [[ADD13]])
19-
; CHECK-NEXT: [[AND12:%.*]] = and i16 [[NSB4]], 4096
20-
; CHECK-NEXT: [[ADD12:%.*]] = add i16 [[AND12]], [[NSB4]]
17+
; CHECK-NEXT: [[ADD12:%.*]] = and i16 [[NSB4]], 3072
2118
; CHECK-NEXT: call void @escape(i16 [[ADD12]])
2219
; CHECK-NEXT: [[AND11:%.*]] = and i16 [[NSB4]], 2048
23-
; CHECK-NEXT: [[ADD11:%.*]] = add i16 [[AND11]], [[NSB4]]
20+
; CHECK-NEXT: [[ADD11:%.*]] = add nsw i16 [[AND11]], [[NSB4]]
2421
; CHECK-NEXT: call void @escape(i16 [[ADD11]])
2522
; CHECK-NEXT: ret void
2623
;
@@ -51,14 +48,12 @@ define void @numsignbits_shl_zext_shift_amounr_matches_extend(i8 %x) {
5148
; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X]], 2
5249
; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[ASHR]] to i16
5350
; CHECK-NEXT: [[NSB3:%.*]] = shl nuw i16 [[ZEXT]], 8
54-
; CHECK-NEXT: [[AND14:%.*]] = and i16 [[NSB3]], 16384
55-
; CHECK-NEXT: [[ADD14:%.*]] = add i16 [[AND14]], [[NSB3]]
51+
; CHECK-NEXT: [[ADD14:%.*]] = and i16 [[NSB3]], 16128
5652
; CHECK-NEXT: call void @escape(i16 [[ADD14]])
57-
; CHECK-NEXT: [[AND13:%.*]] = and i16 [[NSB3]], 8192
58-
; CHECK-NEXT: [[ADD13:%.*]] = add i16 [[AND13]], [[NSB3]]
53+
; CHECK-NEXT: [[ADD13:%.*]] = and i16 [[NSB3]], 7936
5954
; CHECK-NEXT: call void @escape(i16 [[ADD13]])
6055
; CHECK-NEXT: [[AND12:%.*]] = and i16 [[NSB3]], 4096
61-
; CHECK-NEXT: [[ADD12:%.*]] = add i16 [[AND12]], [[NSB3]]
56+
; CHECK-NEXT: [[ADD12:%.*]] = add nsw i16 [[AND12]], [[NSB3]]
6257
; CHECK-NEXT: call void @escape(i16 [[ADD12]])
6358
; CHECK-NEXT: ret void
6459
;
@@ -132,17 +127,14 @@ define void @numsignbits_shl_zext_vector(<2 x i8> %x) {
132127
; CHECK-NEXT: [[ASHR:%.*]] = ashr <2 x i8> [[X]], <i8 5, i8 5>
133128
; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[ASHR]] to <2 x i16>
134129
; CHECK-NEXT: [[NSB4:%.*]] = shl <2 x i16> [[ZEXT]], <i16 10, i16 10>
135-
; CHECK-NEXT: [[AND14:%.*]] = and <2 x i16> [[NSB4]], <i16 16384, i16 16384>
136-
; CHECK-NEXT: [[ADD14:%.*]] = add <2 x i16> [[AND14]], [[NSB4]]
130+
; CHECK-NEXT: [[ADD14:%.*]] = and <2 x i16> [[NSB4]], <i16 15360, i16 15360>
137131
; CHECK-NEXT: call void @escape2(<2 x i16> [[ADD14]])
138-
; CHECK-NEXT: [[AND13:%.*]] = and <2 x i16> [[NSB4]], <i16 8192, i16 8192>
139-
; CHECK-NEXT: [[ADD13:%.*]] = add <2 x i16> [[AND13]], [[NSB4]]
132+
; CHECK-NEXT: [[ADD13:%.*]] = and <2 x i16> [[NSB4]], <i16 7168, i16 7168>
140133
; CHECK-NEXT: call void @escape2(<2 x i16> [[ADD13]])
141-
; CHECK-NEXT: [[AND12:%.*]] = and <2 x i16> [[NSB4]], <i16 4096, i16 4096>
142-
; CHECK-NEXT: [[ADD12:%.*]] = add <2 x i16> [[AND12]], [[NSB4]]
134+
; CHECK-NEXT: [[ADD12:%.*]] = and <2 x i16> [[NSB4]], <i16 3072, i16 3072>
143135
; CHECK-NEXT: call void @escape2(<2 x i16> [[ADD12]])
144136
; CHECK-NEXT: [[AND11:%.*]] = and <2 x i16> [[NSB4]], <i16 2048, i16 2048>
145-
; CHECK-NEXT: [[ADD11:%.*]] = add <2 x i16> [[AND11]], [[NSB4]]
137+
; CHECK-NEXT: [[ADD11:%.*]] = add nsw <2 x i16> [[AND11]], [[NSB4]]
146138
; CHECK-NEXT: call void @escape2(<2 x i16> [[ADD11]])
147139
; CHECK-NEXT: ret void
148140
;

0 commit comments

Comments
 (0)