[llvm] [PredicateInfo] Reserve adjacent LN_Last defs for the same phi use (PR #164577)
Kunqiu Chen via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 22 03:44:59 PDT 2025
https://github.com/Camsyn updated https://github.com/llvm/llvm-project/pull/164577
>From f2b6b234c83413818809d877d85cfdc0d5744cc3 Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Wed, 22 Oct 2025 15:52:19 +0800
Subject: [PATCH 1/4] Add a new test before patch
---
.../Util/PredicateInfo/testandor.ll | 26 +++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/llvm/test/Transforms/Util/PredicateInfo/testandor.ll b/llvm/test/Transforms/Util/PredicateInfo/testandor.ll
index 2e96a92dd37d4..740a404b6c07a 100644
--- a/llvm/test/Transforms/Util/PredicateInfo/testandor.ll
+++ b/llvm/test/Transforms/Util/PredicateInfo/testandor.ll
@@ -994,3 +994,29 @@ define void @test_assume_deep_and_tree(i1 %a1) {
call void @foo(i1 %a15)
ret void
}
+
+define i32 @test_and_with_phinode(i32 %x) {
+; CHECK-LABEL: @test_and_with_phinode(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[XGT0:%.*]] = icmp uge i32 [[X:%.*]], 1
+; CHECK-NEXT: [[XLT1:%.*]] = icmp ult i32 [[X]], 2
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[XGT0]], [[XLT1]]
+; CHECK: [[X_0_1:%.*]] = bitcast i32 [[X]] to i32
+; CHECK-NEXT: br i1 [[AND]], label [[PHI:%.*]], label [[NOPE:%.*]]
+; CHECK: nope:
+; CHECK-NEXT: br label [[PHI]]
+; CHECK: phi:
+; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[X_0_1]], [[ENTRY:%.*]] ], [ 1, [[NOPE]] ]
+; CHECK-NEXT: ret i32 [[RES]]
+;
+entry:
+ %xgt0 = icmp uge i32 %x, 1
+ %xlt1 = icmp ult i32 %x, 2
+ %and = and i1 %xgt0, %xlt1
+ br i1 %and, label %phi, label %nope
+nope:
+ br label %phi
+phi:
+ %res = phi i32 [ %x, %entry ], [ 1, %nope ]
+ ret i32 %res
+}
>From fb8e0ec66d56d023fdb9207a2fc9a91e166c963e Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Wed, 22 Oct 2025 15:00:56 +0800
Subject: [PATCH 2/4] [PredicateInfo] Let phi use associate multi-LN_Last-defs
---
llvm/lib/Transforms/Utils/PredicateInfo.cpp | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/PredicateInfo.cpp b/llvm/lib/Transforms/Utils/PredicateInfo.cpp
index 978d5a25a57c8..8f835e136278c 100644
--- a/llvm/lib/Transforms/Utils/PredicateInfo.cpp
+++ b/llvm/lib/Transforms/Utils/PredicateInfo.cpp
@@ -261,8 +261,14 @@ bool PredicateInfoBuilder::stackIsInScope(const ValueDFSStack &Stack,
// the stack when we hit the end of the phi uses for a given def.
const ValueDFS &Top = *Stack.back().V;
if (Top.LocalNum == LN_Last && Top.PInfo) {
- if (!VDUse.U)
- return false;
+ if (!VDUse.U) {
+ assert(VDUse.PInfo && "A non-use VDUse should have a predicate info");
+ // We should reserve adjacent LN_Last defs for the same phi use.
+ return VDUse.LocalNum == LN_Last &&
+ // If the two phi defs have the same edge, they must be designated
+ // for the same succ BB.
+ getBlockEdge(Top.PInfo) == getBlockEdge(VDUse.PInfo);
+ }
auto *PHI = dyn_cast<PHINode>(VDUse.U->getUser());
if (!PHI)
return false;
>From 4835c17861edf2b427177c2b019f43a3df241246 Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Wed, 22 Oct 2025 15:55:03 +0800
Subject: [PATCH 3/4] Regenerate the test after patch
---
llvm/test/Transforms/Util/PredicateInfo/testandor.ll | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/test/Transforms/Util/PredicateInfo/testandor.ll b/llvm/test/Transforms/Util/PredicateInfo/testandor.ll
index 740a404b6c07a..0020d81dcda3f 100644
--- a/llvm/test/Transforms/Util/PredicateInfo/testandor.ll
+++ b/llvm/test/Transforms/Util/PredicateInfo/testandor.ll
@@ -1002,11 +1002,12 @@ define i32 @test_and_with_phinode(i32 %x) {
; CHECK-NEXT: [[XLT1:%.*]] = icmp ult i32 [[X]], 2
; CHECK-NEXT: [[AND:%.*]] = and i1 [[XGT0]], [[XLT1]]
; CHECK: [[X_0_1:%.*]] = bitcast i32 [[X]] to i32
+; CHECK: [[X_0_2:%.*]] = bitcast i32 [[X_0_1]] to i32
; CHECK-NEXT: br i1 [[AND]], label [[PHI:%.*]], label [[NOPE:%.*]]
; CHECK: nope:
; CHECK-NEXT: br label [[PHI]]
; CHECK: phi:
-; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[X_0_1]], [[ENTRY:%.*]] ], [ 1, [[NOPE]] ]
+; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[X_0_2]], [[ENTRY:%.*]] ], [ 1, [[NOPE]] ]
; CHECK-NEXT: ret i32 [[RES]]
;
entry:
>From 5608bdcc6843202ffd32d0112728b15f284c3a0f Mon Sep 17 00:00:00 2001
From: Camsyn <camsyn at foxmail.com>
Date: Wed, 22 Oct 2025 18:44:32 +0800
Subject: [PATCH 4/4] Follow the review
---
llvm/lib/Transforms/Utils/PredicateInfo.cpp | 3 ++-
.../test/Transforms/SCCP/conditions-ranges.ll | 25 +++++++++++++++++++
.../Util/PredicateInfo/testandor.ll | 12 ++++-----
3 files changed, 33 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Transforms/Utils/PredicateInfo.cpp b/llvm/lib/Transforms/Utils/PredicateInfo.cpp
index 8f835e136278c..371d9e6c83163 100644
--- a/llvm/lib/Transforms/Utils/PredicateInfo.cpp
+++ b/llvm/lib/Transforms/Utils/PredicateInfo.cpp
@@ -260,7 +260,8 @@ bool PredicateInfoBuilder::stackIsInScope(const ValueDFSStack &Stack,
// next to the defs they must go with so that we can know it's time to pop
// the stack when we hit the end of the phi uses for a given def.
const ValueDFS &Top = *Stack.back().V;
- if (Top.LocalNum == LN_Last && Top.PInfo) {
+ assert(Top.PInfo && "RenameStack should only contain predicate infos (defs)");
+ if (Top.LocalNum == LN_Last) {
if (!VDUse.U) {
assert(VDUse.PInfo && "A non-use VDUse should have a predicate info");
// We should reserve adjacent LN_Last defs for the same phi use.
diff --git a/llvm/test/Transforms/SCCP/conditions-ranges.ll b/llvm/test/Transforms/SCCP/conditions-ranges.ll
index a3cf23bd3ae9a..f793814e445f8 100644
--- a/llvm/test/Transforms/SCCP/conditions-ranges.ll
+++ b/llvm/test/Transforms/SCCP/conditions-ranges.ll
@@ -1547,3 +1547,28 @@ bb2:
call void @use(i1 %c4)
ret void
}
+
+define i1 @and_predicate_dominating_phi(i32 %x) {
+; CHECK-LABEL: @and_predicate_dominating_phi(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[XGE1:%.*]] = icmp uge i32 [[X:%.*]], 1
+; CHECK-NEXT: [[XLT2:%.*]] = icmp ult i32 [[X]], 2
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[XGE1]], [[XLT2]]
+; CHECK-NEXT: br i1 [[AND]], label [[PHI:%.*]], label [[NOPE:%.*]]
+; CHECK: nope:
+; CHECK-NEXT: br label [[PHI]]
+; CHECK: phi:
+; CHECK-NEXT: ret i1 true
+;
+entry:
+ %xge1 = icmp uge i32 %x, 1
+ %xlt2 = icmp ult i32 %x, 2
+ %and = and i1 %xge1, %xlt2
+ br i1 %and, label %phi, label %nope
+nope:
+ br label %phi
+phi:
+ %res = phi i32 [ %x, %entry ], [ 1, %nope ]
+ %ret = icmp uge i32 %res, 1
+ ret i1 %ret
+}
diff --git a/llvm/test/Transforms/Util/PredicateInfo/testandor.ll b/llvm/test/Transforms/Util/PredicateInfo/testandor.ll
index 0020d81dcda3f..cc1dc4e6989a1 100644
--- a/llvm/test/Transforms/Util/PredicateInfo/testandor.ll
+++ b/llvm/test/Transforms/Util/PredicateInfo/testandor.ll
@@ -998,9 +998,9 @@ define void @test_assume_deep_and_tree(i1 %a1) {
define i32 @test_and_with_phinode(i32 %x) {
; CHECK-LABEL: @test_and_with_phinode(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[XGT0:%.*]] = icmp uge i32 [[X:%.*]], 1
-; CHECK-NEXT: [[XLT1:%.*]] = icmp ult i32 [[X]], 2
-; CHECK-NEXT: [[AND:%.*]] = and i1 [[XGT0]], [[XLT1]]
+; CHECK-NEXT: [[XGE1:%.*]] = icmp uge i32 [[X:%.*]], 1
+; CHECK-NEXT: [[XLT2:%.*]] = icmp ult i32 [[X]], 2
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[XGE1]], [[XLT2]]
; CHECK: [[X_0_1:%.*]] = bitcast i32 [[X]] to i32
; CHECK: [[X_0_2:%.*]] = bitcast i32 [[X_0_1]] to i32
; CHECK-NEXT: br i1 [[AND]], label [[PHI:%.*]], label [[NOPE:%.*]]
@@ -1011,9 +1011,9 @@ define i32 @test_and_with_phinode(i32 %x) {
; CHECK-NEXT: ret i32 [[RES]]
;
entry:
- %xgt0 = icmp uge i32 %x, 1
- %xlt1 = icmp ult i32 %x, 2
- %and = and i1 %xgt0, %xlt1
+ %xge1 = icmp uge i32 %x, 1
+ %xlt2 = icmp ult i32 %x, 2
+ %and = and i1 %xge1, %xlt2
br i1 %and, label %phi, label %nope
nope:
br label %phi
More information about the llvm-commits
mailing list