Skip to content

Commit abc9d17

Browse files
dtcxzywyuxuanchen1997
authored andcommitted
[ValueTracking] Don't use CondContext in dataflow analysis of phi nodes (#100316)
Summary: See the following case: ``` define i16 @pr100298() { entry: br label %for.inc for.inc: %indvar = phi i32 [ -15, %entry ], [ %mask, %for.inc ] %add = add nsw i32 %indvar, 9 %mask = and i32 %add, 65535 %cmp1 = icmp ugt i32 %mask, 5 br i1 %cmp1, label %for.inc, label %for.end for.end: %conv = trunc i32 %add to i16 %cmp2 = icmp ugt i32 %mask, 3 %shl = shl nuw i16 %conv, 14 %res = select i1 %cmp2, i16 %conv, i16 %shl ret i16 %res } ``` When computing knownbits of `%shl` with `%cmp2=false`, we cannot use this condition in the analysis of `%mask (%for.inc -> %for.inc)`. Fixes #100298. Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60250567
1 parent 72322d5 commit abc9d17

File tree

3 files changed

+56
-11
lines changed

3 files changed

+56
-11
lines changed

llvm/include/llvm/Analysis/SimplifyQuery.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,12 @@ struct SimplifyQuery {
130130
Copy.CC = &CC;
131131
return Copy;
132132
}
133+
134+
SimplifyQuery getWithoutCondContext() const {
135+
SimplifyQuery Copy(*this);
136+
Copy.CC = nullptr;
137+
return Copy;
138+
}
133139
};
134140

135141
} // end namespace llvm

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,7 +1435,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
14351435
// inferred hold at original context instruction. TODO: It may be
14361436
// correct to use the original context. IF warranted, explore and
14371437
// add sufficient tests to cover.
1438-
SimplifyQuery RecQ = Q;
1438+
SimplifyQuery RecQ = Q.getWithoutCondContext();
14391439
RecQ.CxtI = P;
14401440
computeKnownBits(R, DemandedElts, Known2, Depth + 1, RecQ);
14411441
switch (Opcode) {
@@ -1468,7 +1468,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
14681468
// phi. This is important because that is where the value is actually
14691469
// "evaluated" even though it is used later somewhere else. (see also
14701470
// D69571).
1471-
SimplifyQuery RecQ = Q;
1471+
SimplifyQuery RecQ = Q.getWithoutCondContext();
14721472

14731473
unsigned OpNum = P->getOperand(0) == R ? 0 : 1;
14741474
Instruction *RInst = P->getIncomingBlock(OpNum)->getTerminator();
@@ -1546,7 +1546,7 @@ static void computeKnownBitsFromOperator(const Operator *I,
15461546
// phi. This is important because that is where the value is actually
15471547
// "evaluated" even though it is used later somewhere else. (see also
15481548
// D69571).
1549-
SimplifyQuery RecQ = Q;
1549+
SimplifyQuery RecQ = Q.getWithoutCondContext();
15501550
RecQ.CxtI = P->getIncomingBlock(u)->getTerminator();
15511551

15521552
Known2 = KnownBits(BitWidth);
@@ -2329,7 +2329,7 @@ bool isKnownToBeAPowerOfTwo(const Value *V, bool OrZero, unsigned Depth,
23292329
// it is an induction variable where in each step its value is a power of
23302330
// two.
23312331
auto *PN = cast<PHINode>(I);
2332-
SimplifyQuery RecQ = Q;
2332+
SimplifyQuery RecQ = Q.getWithoutCondContext();
23332333

23342334
// Check if it is an induction variable and always power of two.
23352335
if (isPowerOfTwoRecurrence(PN, OrZero, Depth, RecQ))
@@ -2943,7 +2943,7 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
29432943
return true;
29442944

29452945
// Check if all incoming values are non-zero using recursion.
2946-
SimplifyQuery RecQ = Q;
2946+
SimplifyQuery RecQ = Q.getWithoutCondContext();
29472947
unsigned NewDepth = std::max(Depth, MaxAnalysisRecursionDepth - 1);
29482948
return llvm::all_of(PN->operands(), [&](const Use &U) {
29492949
if (U.get() == PN)
@@ -3509,7 +3509,7 @@ static bool isNonEqualPHIs(const PHINode *PN1, const PHINode *PN2,
35093509
if (UsedFullRecursion)
35103510
return false;
35113511

3512-
SimplifyQuery RecQ = Q;
3512+
SimplifyQuery RecQ = Q.getWithoutCondContext();
35133513
RecQ.CxtI = IncomBB->getTerminator();
35143514
if (!isKnownNonEqual(IV1, IV2, DemandedElts, Depth + 1, RecQ))
35153515
return false;
@@ -4001,7 +4001,7 @@ static unsigned ComputeNumSignBitsImpl(const Value *V,
40014001

40024002
// Take the minimum of all incoming values. This can't infinitely loop
40034003
// because of our depth threshold.
4004-
SimplifyQuery RecQ = Q;
4004+
SimplifyQuery RecQ = Q.getWithoutCondContext();
40054005
Tmp = TyBits;
40064006
for (unsigned i = 0, e = NumIncomingValues; i != e; ++i) {
40074007
if (Tmp == 1) return Tmp;
@@ -5909,10 +5909,10 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
59095909
// Recurse, but cap the recursion to two levels, because we don't want
59105910
// to waste time spinning around in loops. We need at least depth 2 to
59115911
// detect known sign bits.
5912-
computeKnownFPClass(
5913-
IncValue, DemandedElts, InterestedClasses, KnownSrc,
5914-
PhiRecursionLimit,
5915-
Q.getWithInstruction(P->getIncomingBlock(U)->getTerminator()));
5912+
computeKnownFPClass(IncValue, DemandedElts, InterestedClasses, KnownSrc,
5913+
PhiRecursionLimit,
5914+
Q.getWithoutCondContext().getWithInstruction(
5915+
P->getIncomingBlock(U)->getTerminator()));
59165916

59175917
if (First) {
59185918
Known = KnownSrc;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -S -passes=instcombine < %s | FileCheck %s
3+
4+
; Make sure that the result of computeKnownBits for %indvar is correct.
5+
6+
define i16 @pr100298() {
7+
; CHECK-LABEL: define i16 @pr100298() {
8+
; CHECK-NEXT: [[ENTRY:.*]]:
9+
; CHECK-NEXT: br label %[[FOR_INC:.*]]
10+
; CHECK: [[FOR_INC]]:
11+
; CHECK-NEXT: [[INDVAR:%.*]] = phi i32 [ -15, %[[ENTRY]] ], [ [[MASK:%.*]], %[[FOR_INC]] ]
12+
; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[INDVAR]], 9
13+
; CHECK-NEXT: [[MASK]] = and i32 [[ADD]], 65535
14+
; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[MASK]], 5
15+
; CHECK-NEXT: br i1 [[CMP1]], label %[[FOR_INC]], label %[[FOR_END:.*]]
16+
; CHECK: [[FOR_END]]:
17+
; CHECK-NEXT: [[CONV:%.*]] = trunc i32 [[ADD]] to i16
18+
; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[MASK]], 3
19+
; CHECK-NEXT: [[SHL:%.*]] = shl nuw i16 [[CONV]], 14
20+
; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP2]], i16 [[CONV]], i16 [[SHL]]
21+
; CHECK-NEXT: ret i16 [[RES]]
22+
;
23+
entry:
24+
br label %for.inc
25+
26+
for.inc:
27+
%indvar = phi i32 [ -15, %entry ], [ %mask, %for.inc ]
28+
%add = add nsw i32 %indvar, 9
29+
%mask = and i32 %add, 65535
30+
%cmp1 = icmp ugt i32 %mask, 5
31+
br i1 %cmp1, label %for.inc, label %for.end
32+
33+
for.end:
34+
%conv = trunc i32 %add to i16
35+
%cmp2 = icmp ugt i32 %mask, 3
36+
%shl = shl nuw i16 %conv, 14
37+
%res = select i1 %cmp2, i16 %conv, i16 %shl
38+
ret i16 %res
39+
}

0 commit comments

Comments
 (0)