[llvm] ValueTracking: generalize isNonEqualPHIs (PR #108820)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 25 04:28:59 PDT 2024
https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/108820
>From 9a3f743927f8fc441c456306b65d18adab78c987 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/3] 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 56eb3f99b39d2c..37c30bd6dd2ce1 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -2697,11 +2697,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);
}
@@ -3537,25 +3532,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;
}
@@ -3642,6 +3627,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 fb1933c19e530bca7b998e01ef71e67efe62b7c7 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/3] 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 37c30bd6dd2ce1..9d2713d9cc3f40 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3537,9 +3537,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;
>From 62c0f62280868f3c5cf1a4154452c1f2636fc328 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Wed, 25 Sep 2024 11:50:49 +0100
Subject: [PATCH 3/3] ValueTracking: fix thinko, crash; add test
---
llvm/lib/Analysis/ValueTracking.cpp | 2 +-
.../Analysis/ValueTracking/known-non-equal.ll | 50 +++++++++++++++++++
2 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 9d2713d9cc3f40..39872e022f42e5 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3538,7 +3538,7 @@ static bool isNonEqualPHIs(const PHINode *PN1, const PHINode *PN2,
const Value *IV1 = PN1->getIncomingValueForBlock(IncomBB);
const Value *IV2 = PN2->getIncomingValueForBlock(IncomBB);
const unsigned PhiRecursionLimit =
- std::max(Depth, MaxAnalysisRecursionDepth - 2);
+ std::max(Depth + 1, MaxAnalysisRecursionDepth - 2);
SimplifyQuery RecQ = Q.getWithoutCondContext();
RecQ.CxtI = IncomBB->getTerminator();
if (!isKnownNonEqual(IV1, IV2, DemandedElts, PhiRecursionLimit, RecQ))
diff --git a/llvm/test/Analysis/ValueTracking/known-non-equal.ll b/llvm/test/Analysis/ValueTracking/known-non-equal.ll
index 824a62b618d983..c669613afbabf8 100644
--- a/llvm/test/Analysis/ValueTracking/known-non-equal.ll
+++ b/llvm/test/Analysis/ValueTracking/known-non-equal.ll
@@ -342,6 +342,56 @@ exit:
ret i1 %cmp
}
+define i1 @phi_max_recursion_limit(i1 %cond, i32 %switch.cond) {
+; CHECK-LABEL: @phi_max_recursion_limit(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[BB0:%.*]]
+; CHECK: bb0:
+; CHECK-NEXT: [[PHIA_0:%.*]] = phi i32 [ [[PHIA_1:%.*]], [[BB1:%.*]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT: [[PHIB_0:%.*]] = phi i32 [ [[PHIB_1:%.*]], [[BB1]] ], [ 0, [[ENTRY]] ]
+; CHECK-NEXT: br i1 [[COND:%.*]], label [[SWITCH_BLOCK:%.*]], label [[EXIT:%.*]]
+; CHECK: switch.block:
+; CHECK-NEXT: switch i32 [[SWITCH_COND:%.*]], label [[BB1]] [
+; CHECK-NEXT: i32 0, label [[EPILOGUE:%.*]]
+; CHECK-NEXT: i32 1, label [[EPILOGUE]]
+; CHECK-NEXT: ]
+; CHECK: bb1:
+; CHECK-NEXT: [[PHIA_1]] = phi i32 [ [[PHIA_0]], [[SWITCH_BLOCK]] ], [ 0, [[EPILOGUE]] ]
+; CHECK-NEXT: [[PHIB_1]] = phi i32 [ [[PHIB_0]], [[SWITCH_BLOCK]] ], [ 0, [[EPILOGUE]] ]
+; CHECK-NEXT: br label [[BB0]]
+; CHECK: epilogue:
+; CHECK-NEXT: br label [[BB1]]
+; CHECK: exit:
+; CHECK-NEXT: [[RET:%.*]] = icmp eq i32 [[PHIA_0]], [[PHIB_0]]
+; CHECK-NEXT: ret i1 [[RET]]
+;
+entry:
+ br label %bb0
+
+bb0:
+ %phiA.0 = phi i32 [ %phiA.1, %bb1 ], [ 0, %entry ]
+ %phiB.0 = phi i32 [ %phiB.1, %bb1 ], [ 0, %entry ]
+ br i1 %cond, label %switch.block, label %exit
+
+switch.block:
+ switch i32 %switch.cond, label %bb1 [
+ i32 0, label %epilogue
+ i32 1, label %epilogue
+ ]
+
+bb1:
+ %phiA.1 = phi i32 [ %phiA.0, %switch.block ], [ 0, %epilogue ]
+ %phiB.1 = phi i32 [ %phiB.0, %switch.block ], [ 0, %epilogue ]
+ br label %bb0
+
+epilogue:
+ br label %bb1
+
+exit:
+ %ret = icmp eq i32 %phiA.0, %phiB.0
+ ret i1 %ret
+}
+
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:
More information about the llvm-commits
mailing list