[llvm] ValueTracking: generalize isNonEqualPHIs (PR #108820)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 16 06:21:16 PDT 2024
https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/108820
>From e1309e4b7568bd7c50b0e56223f1ca1506d25241 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Mon, 16 Sep 2024 13:20:19 +0100
Subject: [PATCH 1/2] 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.
---
llvm/lib/Analysis/ValueTracking.cpp | 21 +++++----------
.../Analysis/ValueTracking/known-non-equal.ll | 26 +++++++++++++++++++
2 files changed, 32 insertions(+), 15 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index ba3ba7cc98136d..c46152f60aab32 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -2696,11 +2696,6 @@ static bool isNonZeroSub(const APInt &DemandedElts, unsigned Depth,
if (matchOpWithOpEqZero(X, Y))
return true;
- // TODO: Move this case into isKnownNonEqual().
- if (auto *C = dyn_cast<Constant>(X))
- if (C->isNullValue() && isKnownNonZero(Y, DemandedElts, Q, Depth))
- return true;
-
return ::isKnownNonEqual(X, Y, DemandedElts, Depth, Q);
}
@@ -3536,25 +3531,15 @@ static bool isNonEqualPHIs(const PHINode *PN1, const PHINode *PN2,
return false;
SmallPtrSet<const BasicBlock *, 8> VisitedBBs;
- bool UsedFullRecursion = false;
for (const BasicBlock *IncomBB : PN1->blocks()) {
if (!VisitedBBs.insert(IncomBB).second)
continue; // Don't reprocess blocks that we have dealt with already.
const Value *IV1 = PN1->getIncomingValueForBlock(IncomBB);
const Value *IV2 = PN2->getIncomingValueForBlock(IncomBB);
- const APInt *C1, *C2;
- if (match(IV1, m_APInt(C1)) && match(IV2, m_APInt(C2)) && *C1 != *C2)
- continue;
-
- // Only one pair of phi operands is allowed for full recursion.
- if (UsedFullRecursion)
- return false;
-
SimplifyQuery RecQ = Q.getWithoutCondContext();
RecQ.CxtI = IncomBB->getTerminator();
if (!isKnownNonEqual(IV1, IV2, DemandedElts, Depth + 1, RecQ))
return false;
- UsedFullRecursion = true;
}
return true;
}
@@ -3641,6 +3626,12 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2,
// We can't look through casts yet.
return false;
+ if (isa<Constant>(V2))
+ std::swap(V1, V2);
+ if (auto *C = dyn_cast<Constant>(V1))
+ if (C->isNullValue() && isKnownNonZero(V2, DemandedElts, Q, Depth))
+ return true;
+
if (Depth >= MaxAnalysisRecursionDepth)
return false;
diff --git a/llvm/test/Analysis/ValueTracking/known-non-equal.ll b/llvm/test/Analysis/ValueTracking/known-non-equal.ll
index d67f1b56621476..824a62b618d983 100644
--- a/llvm/test/Analysis/ValueTracking/known-non-equal.ll
+++ b/llvm/test/Analysis/ValueTracking/known-non-equal.ll
@@ -316,6 +316,32 @@ exit:
ret i1 %cmp
}
+define i1 @known_non_equal_phis2(i8 %p, i8 %n) {
+; CHECK-LABEL: @known_non_equal_phis2(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[A:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[NEXT]] = add nsw i8 [[A]], 2
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[A]], [[N:%.*]]
+; CHECK-NEXT: br i1 [[CMP1]], label [[EXIT:%.*]], label [[LOOP]]
+; CHECK: exit:
+; CHECK-NEXT: ret i1 true
+;
+entry:
+ %known.nonzero = add nuw i8 %p, 1
+ br label %loop
+loop:
+ %A = phi i8 [ 0, %entry ], [ %next, %loop ]
+ %B = phi i8 [ %known.nonzero, %entry ], [ %A, %loop ]
+ %next = add nsw i8 %A, 2
+ %cmp1 = icmp eq i8 %A, %n
+ br i1 %cmp1, label %exit, label %loop
+exit:
+ %cmp = icmp ne i8 %A, %B
+ ret i1 %cmp
+}
+
define i1 @known_non_equal_phis_fail(i8 %p, ptr %pq, i8 %n, i8 %r) {
; CHECK-LABEL: @known_non_equal_phis_fail(
; CHECK-NEXT: entry:
>From 045d3b0cc0febf65d530b4786d307580cfdf4a51 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Mon, 16 Sep 2024 14:05:34 +0100
Subject: [PATCH 2/2] ValueTracking: avoid compile-time blowup
---
llvm/lib/Analysis/ValueTracking.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index c46152f60aab32..4377dd789f3b34 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3536,9 +3536,11 @@ static bool isNonEqualPHIs(const PHINode *PN1, const PHINode *PN2,
continue; // Don't reprocess blocks that we have dealt with already.
const Value *IV1 = PN1->getIncomingValueForBlock(IncomBB);
const Value *IV2 = PN2->getIncomingValueForBlock(IncomBB);
+ const unsigned PhiRecursionLimit =
+ std::max(Depth, MaxAnalysisRecursionDepth - 2);
SimplifyQuery RecQ = Q.getWithoutCondContext();
RecQ.CxtI = IncomBB->getTerminator();
- if (!isKnownNonEqual(IV1, IV2, DemandedElts, Depth + 1, RecQ))
+ if (!isKnownNonEqual(IV1, IV2, DemandedElts, PhiRecursionLimit, RecQ))
return false;
}
return true;
More information about the llvm-commits
mailing list