[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 01:21:16 PDT 2025


https://github.com/Camsyn created https://github.com/llvm/llvm-project/pull/164577

Due to the existence of and-chains, a phi-use might be associated with multiple LN_Last predicate infos.
E.g.,
```cpp
// TWO LN_Last Predicate Info defs:
// 1. a >= 1
// 2. a < 2
if ( a < 1 || a >= 2) {
  a = 1;
}  
// PHI use of `a`
use(a)
```
However, previously, `popStackUntilDFSScope` reserved only ONE LN_Last def for a phi use, although there might be multiple LN_Last defs for the same phi use


This patch reserves the adjacent LN_Last defs if they are designated for the same phi use.



>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/3] 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/3] [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/3] 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:



More information about the llvm-commits mailing list