[llvm] [InstCombine] Add test for freeze of PHI with noundef start value (NFC) (PR #157112)

Cullen Rhodes via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 5 08:09:37 PDT 2025


https://github.com/c-rhodes updated https://github.com/llvm/llvm-project/pull/157112

>From 9de955a4471d708dde9173e638fa4a52752e4e8b Mon Sep 17 00:00:00 2001
From: Cullen Rhodes <cullen.rhodes at arm.com>
Date: Fri, 5 Sep 2025 14:05:35 +0000
Subject: [PATCH 1/3] [InstCombine] Add test for freeze of PHI with noundef
 start value (NFC)

We should be able to remove this freeze as the incoming values to the
PHI have the same well-defined start value and the GEP can't produce
poison, but this is currently unsupported.

If the freeze is pushed to the incoming values we can remove it:
https://godbolt.org/z/8dE4o1bKf
---
 llvm/test/Transforms/InstCombine/freeze.ll | 49 ++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
index b29421a655fa8..7eac456bcca1e 100644
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -1135,6 +1135,55 @@ exit:
   ret void
 }
 
+; We can remove this freeze as the incoming values to the PHI have the same
+; well-defined start value and the GEP can't produce poison, but this is
+; currently unsupported.
+define void @fold_phi_noundef_start_value(ptr noundef %init, i1 %cond.0, i1 %cond.1, i1 %cond.2) {
+; CHECK-LABEL: define void @fold_phi_noundef_start_value(
+; CHECK-SAME: ptr noundef [[INIT:%.*]], i1 [[COND_0:%.*]], i1 [[COND_1:%.*]], i1 [[COND_2:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[LOOP_PH_0:.*]]
+; CHECK:       [[LOOP_PH_0]]:
+; CHECK-NEXT:    [[IV_0:%.*]] = phi ptr [ [[INIT]], %[[ENTRY]] ], [ [[IV_0_NEXT:%.*]], %[[LOOP:.*]] ]
+; CHECK-NEXT:    br i1 [[COND_0]], label %[[LOOP]], label %[[LOOP_PH_1:.*]]
+; CHECK:       [[LOOP_PH_1]]:
+; CHECK-NEXT:    [[IV_1:%.*]] = getelementptr i8, ptr [[IV_0]], i64 -8
+; CHECK-NEXT:    br label %[[LOOP]]
+; CHECK:       [[LOOP]]:
+; CHECK-NEXT:    [[IV_2:%.*]] = phi ptr [ [[IV_0]], %[[LOOP_PH_0]] ], [ [[IV_1]], %[[LOOP_PH_1]] ]
+; CHECK-NEXT:    [[IV_2_FR:%.*]] = freeze ptr [[IV_2]]
+; CHECK-NEXT:    [[IV_2_FR_INT:%.*]] = ptrtoint ptr [[IV_2_FR]] to i64
+; CHECK-NEXT:    [[IV_0_INT:%.*]] = ptrtoint ptr [[IV_0]] to i64
+; CHECK-NEXT:    [[IDX:%.*]] = sub i64 [[IV_0_INT]], [[IV_2_FR_INT]]
+; CHECK-NEXT:    [[IV_0_NEXT]] = getelementptr i8, ptr [[IV_0]], i64 [[IDX]]
+; CHECK-NEXT:    br i1 [[COND_2]], label %[[EXIT:.*]], label %[[LOOP_PH_0]]
+; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %loop.ph.0
+
+loop.ph.0:
+  %iv.0 = phi ptr [ %init, %entry ], [ %iv.0.next, %loop ]
+  br i1 %cond.0, label %loop, label %loop.ph.1
+
+loop.ph.1:
+  %iv.1 = getelementptr i8, ptr %iv.0, i64 -8
+  br label %loop
+
+loop:
+  %iv.2 = phi ptr [ %iv.0, %loop.ph.0 ], [ %iv.1, %loop.ph.1 ]
+  %iv.2.fr = freeze ptr %iv.2
+  %iv.2.fr.int = ptrtoint ptr %iv.2.fr to i64
+  %iv.0.int = ptrtoint ptr %iv.0 to i64
+  %idx = sub i64 %iv.0.int, %iv.2.fr.int
+  %iv.0.next = getelementptr i8, ptr %iv.0, i64 %idx
+  br i1 %cond.2, label %exit, label %loop.ph.0
+
+exit:
+  ret void
+}
+
 define void @fold_phi_invoke_start_value(i32 %n) personality ptr undef {
 ; CHECK-LABEL: define void @fold_phi_invoke_start_value(
 ; CHECK-SAME: i32 [[N:%.*]]) personality ptr undef {

>From 41dfb5eeefb3708ddbdf14cfb3cc277c8b3c7c7b Mon Sep 17 00:00:00 2001
From: Cullen Rhodes <cullen.rhodes at arm.com>
Date: Fri, 5 Sep 2025 15:01:36 +0000
Subject: [PATCH 2/3] update label names

---
 llvm/test/Transforms/InstCombine/freeze.ll | 36 +++++++++++-----------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
index 7eac456bcca1e..d1052aebb22d1 100644
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -1142,43 +1142,43 @@ define void @fold_phi_noundef_start_value(ptr noundef %init, i1 %cond.0, i1 %con
 ; CHECK-LABEL: define void @fold_phi_noundef_start_value(
 ; CHECK-SAME: ptr noundef [[INIT:%.*]], i1 [[COND_0:%.*]], i1 [[COND_1:%.*]], i1 [[COND_2:%.*]]) {
 ; CHECK-NEXT:  [[ENTRY:.*]]:
-; CHECK-NEXT:    br label %[[LOOP_PH_0:.*]]
-; CHECK:       [[LOOP_PH_0]]:
-; CHECK-NEXT:    [[IV_0:%.*]] = phi ptr [ [[INIT]], %[[ENTRY]] ], [ [[IV_0_NEXT:%.*]], %[[LOOP:.*]] ]
-; CHECK-NEXT:    br i1 [[COND_0]], label %[[LOOP]], label %[[LOOP_PH_1:.*]]
-; CHECK:       [[LOOP_PH_1]]:
+; CHECK-NEXT:    br label %[[LOOP_HEADER:.*]]
+; CHECK:       [[LOOP_HEADER]]:
+; CHECK-NEXT:    [[IV_0:%.*]] = phi ptr [ [[INIT]], %[[ENTRY]] ], [ [[IV_0_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
+; CHECK-NEXT:    br i1 [[COND_0]], label %[[LOOP_LATCH]], label %[[IF_ELSE:.*]]
+; CHECK:       [[IF_ELSE]]:
 ; CHECK-NEXT:    [[IV_1:%.*]] = getelementptr i8, ptr [[IV_0]], i64 -8
-; CHECK-NEXT:    br label %[[LOOP]]
-; CHECK:       [[LOOP]]:
-; CHECK-NEXT:    [[IV_2:%.*]] = phi ptr [ [[IV_0]], %[[LOOP_PH_0]] ], [ [[IV_1]], %[[LOOP_PH_1]] ]
+; CHECK-NEXT:    br label %[[LOOP_LATCH]]
+; CHECK:       [[LOOP_LATCH]]:
+; CHECK-NEXT:    [[IV_2:%.*]] = phi ptr [ [[IV_0]], %[[LOOP_HEADER]] ], [ [[IV_1]], %[[IF_ELSE]] ]
 ; CHECK-NEXT:    [[IV_2_FR:%.*]] = freeze ptr [[IV_2]]
 ; CHECK-NEXT:    [[IV_2_FR_INT:%.*]] = ptrtoint ptr [[IV_2_FR]] to i64
 ; CHECK-NEXT:    [[IV_0_INT:%.*]] = ptrtoint ptr [[IV_0]] to i64
 ; CHECK-NEXT:    [[IDX:%.*]] = sub i64 [[IV_0_INT]], [[IV_2_FR_INT]]
 ; CHECK-NEXT:    [[IV_0_NEXT]] = getelementptr i8, ptr [[IV_0]], i64 [[IDX]]
-; CHECK-NEXT:    br i1 [[COND_2]], label %[[EXIT:.*]], label %[[LOOP_PH_0]]
+; CHECK-NEXT:    br i1 [[COND_2]], label %[[EXIT:.*]], label %[[LOOP_HEADER]]
 ; CHECK:       [[EXIT]]:
 ; CHECK-NEXT:    ret void
 ;
 entry:
-  br label %loop.ph.0
+  br label %loop.header
 
-loop.ph.0:
-  %iv.0 = phi ptr [ %init, %entry ], [ %iv.0.next, %loop ]
-  br i1 %cond.0, label %loop, label %loop.ph.1
+loop.header:
+  %iv.0 = phi ptr [ %init, %entry ], [ %iv.0.next, %loop.latch ]
+  br i1 %cond.0, label %loop.latch, label %if.else
 
-loop.ph.1:
+if.else:
   %iv.1 = getelementptr i8, ptr %iv.0, i64 -8
-  br label %loop
+  br label %loop.latch
 
-loop:
-  %iv.2 = phi ptr [ %iv.0, %loop.ph.0 ], [ %iv.1, %loop.ph.1 ]
+loop.latch:
+  %iv.2 = phi ptr [ %iv.0, %loop.header ], [ %iv.1, %if.else ]
   %iv.2.fr = freeze ptr %iv.2
   %iv.2.fr.int = ptrtoint ptr %iv.2.fr to i64
   %iv.0.int = ptrtoint ptr %iv.0 to i64
   %idx = sub i64 %iv.0.int, %iv.2.fr.int
   %iv.0.next = getelementptr i8, ptr %iv.0, i64 %idx
-  br i1 %cond.2, label %exit, label %loop.ph.0
+  br i1 %cond.2, label %exit, label %loop.header
 
 exit:
   ret void

>From 22337b8e58440a8343a0862ae0dd6ec972d50622 Mon Sep 17 00:00:00 2001
From: Cullen Rhodes <cullen.rhodes at arm.com>
Date: Fri, 5 Sep 2025 15:08:14 +0000
Subject: [PATCH 3/3] update label names

---
 llvm/test/Transforms/InstCombine/freeze.ll | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
index d1052aebb22d1..f63489bbab4c0 100644
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -1142,28 +1142,28 @@ define void @fold_phi_noundef_start_value(ptr noundef %init, i1 %cond.0, i1 %con
 ; CHECK-LABEL: define void @fold_phi_noundef_start_value(
 ; CHECK-SAME: ptr noundef [[INIT:%.*]], i1 [[COND_0:%.*]], i1 [[COND_1:%.*]], i1 [[COND_2:%.*]]) {
 ; CHECK-NEXT:  [[ENTRY:.*]]:
-; CHECK-NEXT:    br label %[[LOOP_HEADER:.*]]
-; CHECK:       [[LOOP_HEADER]]:
+; CHECK-NEXT:    br label %[[LOOP:.*]]
+; CHECK:       [[LOOP]]:
 ; CHECK-NEXT:    [[IV_0:%.*]] = phi ptr [ [[INIT]], %[[ENTRY]] ], [ [[IV_0_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
 ; CHECK-NEXT:    br i1 [[COND_0]], label %[[LOOP_LATCH]], label %[[IF_ELSE:.*]]
 ; CHECK:       [[IF_ELSE]]:
 ; CHECK-NEXT:    [[IV_1:%.*]] = getelementptr i8, ptr [[IV_0]], i64 -8
 ; CHECK-NEXT:    br label %[[LOOP_LATCH]]
 ; CHECK:       [[LOOP_LATCH]]:
-; CHECK-NEXT:    [[IV_2:%.*]] = phi ptr [ [[IV_0]], %[[LOOP_HEADER]] ], [ [[IV_1]], %[[IF_ELSE]] ]
+; CHECK-NEXT:    [[IV_2:%.*]] = phi ptr [ [[IV_0]], %[[LOOP]] ], [ [[IV_1]], %[[IF_ELSE]] ]
 ; CHECK-NEXT:    [[IV_2_FR:%.*]] = freeze ptr [[IV_2]]
 ; CHECK-NEXT:    [[IV_2_FR_INT:%.*]] = ptrtoint ptr [[IV_2_FR]] to i64
 ; CHECK-NEXT:    [[IV_0_INT:%.*]] = ptrtoint ptr [[IV_0]] to i64
 ; CHECK-NEXT:    [[IDX:%.*]] = sub i64 [[IV_0_INT]], [[IV_2_FR_INT]]
 ; CHECK-NEXT:    [[IV_0_NEXT]] = getelementptr i8, ptr [[IV_0]], i64 [[IDX]]
-; CHECK-NEXT:    br i1 [[COND_2]], label %[[EXIT:.*]], label %[[LOOP_HEADER]]
+; CHECK-NEXT:    br i1 [[COND_2]], label %[[EXIT:.*]], label %[[LOOP]]
 ; CHECK:       [[EXIT]]:
 ; CHECK-NEXT:    ret void
 ;
 entry:
-  br label %loop.header
+  br label %loop
 
-loop.header:
+loop:
   %iv.0 = phi ptr [ %init, %entry ], [ %iv.0.next, %loop.latch ]
   br i1 %cond.0, label %loop.latch, label %if.else
 
@@ -1172,13 +1172,13 @@ if.else:
   br label %loop.latch
 
 loop.latch:
-  %iv.2 = phi ptr [ %iv.0, %loop.header ], [ %iv.1, %if.else ]
+  %iv.2 = phi ptr [ %iv.0, %loop ], [ %iv.1, %if.else ]
   %iv.2.fr = freeze ptr %iv.2
   %iv.2.fr.int = ptrtoint ptr %iv.2.fr to i64
   %iv.0.int = ptrtoint ptr %iv.0 to i64
   %idx = sub i64 %iv.0.int, %iv.2.fr.int
   %iv.0.next = getelementptr i8, ptr %iv.0, i64 %idx
-  br i1 %cond.2, label %exit, label %loop.header
+  br i1 %cond.2, label %exit, label %loop
 
 exit:
   ret void



More information about the llvm-commits mailing list