Skip to content

Commit 9a3f743

Browse files
committed
ValueTracking: generalize isNonEqualPHIs
isNonEqualPHIs was originally added in 3fd64cc ([ValueTracking] Handle two PHIs in isKnownNonEqual()), but as the new test case shows, it is not powerful enough. Generalize it, removing the APInt-specific comparison, and extend isKnownNonEqual to handle the case when one of the operands is a constant.
1 parent 3d34053 commit 9a3f743

File tree

2 files changed

+32
-15
lines changed

2 files changed

+32
-15
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2697,11 +2697,6 @@ static bool isNonZeroSub(const APInt &DemandedElts, unsigned Depth,
26972697
if (matchOpWithOpEqZero(X, Y))
26982698
return true;
26992699

2700-
// TODO: Move this case into isKnownNonEqual().
2701-
if (auto *C = dyn_cast<Constant>(X))
2702-
if (C->isNullValue() && isKnownNonZero(Y, DemandedElts, Q, Depth))
2703-
return true;
2704-
27052700
return ::isKnownNonEqual(X, Y, DemandedElts, Depth, Q);
27062701
}
27072702

@@ -3537,25 +3532,15 @@ static bool isNonEqualPHIs(const PHINode *PN1, const PHINode *PN2,
35373532
return false;
35383533

35393534
SmallPtrSet<const BasicBlock *, 8> VisitedBBs;
3540-
bool UsedFullRecursion = false;
35413535
for (const BasicBlock *IncomBB : PN1->blocks()) {
35423536
if (!VisitedBBs.insert(IncomBB).second)
35433537
continue; // Don't reprocess blocks that we have dealt with already.
35443538
const Value *IV1 = PN1->getIncomingValueForBlock(IncomBB);
35453539
const Value *IV2 = PN2->getIncomingValueForBlock(IncomBB);
3546-
const APInt *C1, *C2;
3547-
if (match(IV1, m_APInt(C1)) && match(IV2, m_APInt(C2)) && *C1 != *C2)
3548-
continue;
3549-
3550-
// Only one pair of phi operands is allowed for full recursion.
3551-
if (UsedFullRecursion)
3552-
return false;
3553-
35543540
SimplifyQuery RecQ = Q.getWithoutCondContext();
35553541
RecQ.CxtI = IncomBB->getTerminator();
35563542
if (!isKnownNonEqual(IV1, IV2, DemandedElts, Depth + 1, RecQ))
35573543
return false;
3558-
UsedFullRecursion = true;
35593544
}
35603545
return true;
35613546
}
@@ -3642,6 +3627,12 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2,
36423627
// We can't look through casts yet.
36433628
return false;
36443629

3630+
if (isa<Constant>(V2))
3631+
std::swap(V1, V2);
3632+
if (auto *C = dyn_cast<Constant>(V1))
3633+
if (C->isNullValue() && isKnownNonZero(V2, DemandedElts, Q, Depth))
3634+
return true;
3635+
36453636
if (Depth >= MaxAnalysisRecursionDepth)
36463637
return false;
36473638

llvm/test/Analysis/ValueTracking/known-non-equal.ll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,32 @@ exit:
316316
ret i1 %cmp
317317
}
318318

319+
define i1 @known_non_equal_phis2(i8 %p, i8 %n) {
320+
; CHECK-LABEL: @known_non_equal_phis2(
321+
; CHECK-NEXT: entry:
322+
; CHECK-NEXT: br label [[LOOP:%.*]]
323+
; CHECK: loop:
324+
; CHECK-NEXT: [[A:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
325+
; CHECK-NEXT: [[NEXT]] = add nsw i8 [[A]], 2
326+
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
327+
; CHECK-NEXT: br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
328+
; CHECK: exit:
329+
; CHECK-NEXT: ret i1 true
330+
;
331+
entry:
332+
%known.nonzero = add nuw i8 %p, 1
333+
br label %loop
334+
loop:
335+
%A = phi i8 [ 0, %entry ], [ %next, %loop ]
336+
%B = phi i8 [ %known.nonzero, %entry ], [ %A, %loop ]
337+
%next = add nsw i8 %A, 2
338+
%cmp1 = icmp eq i8 %A, %n
339+
br i1 %cmp1, label %exit, label %loop
340+
exit:
341+
%cmp = icmp ne i8 %A, %B
342+
ret i1 %cmp
343+
}
344+
319345
define i1 @known_non_equal_phis_fail(i8 %p, ptr %pq, i8 %n, i8 %r) {
320346
; CHECK-LABEL: @known_non_equal_phis_fail(
321347
; CHECK-NEXT: entry:

0 commit comments

Comments
 (0)