[llvm] [InstCombine] Add test for freeze of GEP with recurrence offset (NFC) (PR #145541)
Cullen Rhodes via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 25 06:21:21 PDT 2025
https://github.com/c-rhodes updated https://github.com/llvm/llvm-project/pull/145541
>From b32e341e87fe2970acfec273b12500a849601d28 Mon Sep 17 00:00:00 2001
From: Cullen Rhodes <cullen.rhodes at arm.com>
Date: Tue, 24 Jun 2025 15:36:37 +0000
Subject: [PATCH 1/5] [InstCombine] Add test for freeze of GEP with recurrence
offset (NFC)
The freeze should be pushed through the GEP to the ptr like in:
https://godbolt.org/z/jrcozT8rz
---
llvm/test/Transforms/InstCombine/freeze.ll | 33 ++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
index 8875ce1c566f3..50483d8e41ada 100644
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -877,6 +877,39 @@ exit: ; preds = %loop
ret void
}
+; The recurrence for the GEP offset can't produce undef so the freeze should be
+; pushed through to the ptr, but this is not currently supported.
+define void @fold_phi_gep_phi_offset(ptr %init, ptr %end, i64 noundef %n) {
+; CHECK-LABEL: @fold_phi_phi_gep(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT_FR:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N:%.*]], [[ENTRY]] ], [ [[OFF_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[OFF_NEXT]] = shl i64 [[OFF]], 3
+; CHECK-NEXT: [[I_NEXT:%.*]] = getelementptr i8, ptr [[I]], i64 [[OFF_NEXT]]
+; CHECK-NEXT: [[I_NEXT_FR]] = freeze ptr [[I_NEXT]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT_FR]], [[END:%.*]]
+; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %loop
+
+loop: ; preds = %loop, %entry
+ %i = phi ptr [ %init, %entry ], [ %i.next.fr, %loop ]
+ %off = phi i64 [ %n, %entry ], [ %off.next, %loop ]
+ %off.next = shl i64 %off, 3
+ %i.next = getelementptr i8, ptr %i, i64 %off.next
+ %i.next.fr = freeze ptr %i.next
+ %cond = icmp eq ptr %i.next.fr, %end
+ br i1 %cond, label %loop, label %exit
+
+exit: ; preds = %loop
+ ret void
+}
+
define void @fold_phi_multiple_insts(i32 %init, i32 %n) {
; CHECK-LABEL: @fold_phi_multiple_insts(
; CHECK-NEXT: entry:
>From ded4097cb781af3a272f6e3ff45a3421ce164cf0 Mon Sep 17 00:00:00 2001
From: Cullen Rhodes <cullen.rhodes at arm.com>
Date: Wed, 25 Jun 2025 07:50:32 +0000
Subject: [PATCH 2/5] update CHECK-LABEL
---
llvm/test/Transforms/InstCombine/freeze.ll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
index 50483d8e41ada..f0c5eff71c086 100644
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -880,7 +880,7 @@ exit: ; preds = %loop
; The recurrence for the GEP offset can't produce undef so the freeze should be
; pushed through to the ptr, but this is not currently supported.
define void @fold_phi_gep_phi_offset(ptr %init, ptr %end, i64 noundef %n) {
-; CHECK-LABEL: @fold_phi_phi_gep(
+; CHECK-LABEL: @fold_phi_gep_phi_offset(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
>From 2ca19f1adad02b2b3b22b67e78d0ac9514a23012 Mon Sep 17 00:00:00 2001
From: Cullen Rhodes <cullen.rhodes at arm.com>
Date: Wed, 25 Jun 2025 10:41:25 +0000
Subject: [PATCH 3/5] address comments
---
llvm/test/Transforms/InstCombine/freeze.ll | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
index f0c5eff71c086..a99094ea453c3 100644
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -877,8 +877,8 @@ exit: ; preds = %loop
ret void
}
-; The recurrence for the GEP offset can't produce undef so the freeze should be
-; pushed through to the ptr, but this is not currently supported.
+; The recurrence for the GEP offset can't produce poison so the freeze should
+; be pushed through to the ptr, but this is not currently supported.
define void @fold_phi_gep_phi_offset(ptr %init, ptr %end, i64 noundef %n) {
; CHECK-LABEL: @fold_phi_gep_phi_offset(
; CHECK-NEXT: entry:
>From a82060e2a3d70bd7262f792d2e0c2e9c07ff65df Mon Sep 17 00:00:00 2001
From: Cullen Rhodes <cullen.rhodes at arm.com>
Date: Wed, 25 Jun 2025 10:49:58 +0000
Subject: [PATCH 4/5] add test for GEP that can produce poison
---
llvm/test/Transforms/InstCombine/freeze.ll | 32 ++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
index a99094ea453c3..e92a947ac004a 100644
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -910,6 +910,38 @@ exit: ; preds = %loop
ret void
}
+; GEP can produce poison, check freeze isn't moved.
+define void @cant_fold_phi_gep_phi_offset(ptr %init, ptr %end, i64 %n) {
+; CHECK-LABEL: @cant_fold_phi_gep_phi_offset(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT_FR:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N:%.*]], [[ENTRY]] ], [ [[OFF_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[OFF_NEXT]] = shl i64 [[OFF]], 3
+; CHECK-NEXT: [[I_NEXT:%.*]] = getelementptr inbounds i8, ptr [[I]], i64 [[OFF_NEXT]]
+; CHECK-NEXT: [[I_NEXT_FR]] = freeze ptr [[I_NEXT]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT_FR]], [[END:%.*]]
+; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %loop
+
+loop: ; preds = %loop, %entry
+ %i = phi ptr [ %init, %entry ], [ %i.next.fr, %loop ]
+ %off = phi i64 [ %n, %entry ], [ %off.next, %loop ]
+ %off.next = shl i64 %off, 3
+ %i.next = getelementptr inbounds i8, ptr %i, i64 %off.next
+ %i.next.fr = freeze ptr %i.next
+ %cond = icmp eq ptr %i.next.fr, %end
+ br i1 %cond, label %loop, label %exit
+
+exit: ; preds = %loop
+ ret void
+}
+
define void @fold_phi_multiple_insts(i32 %init, i32 %n) {
; CHECK-LABEL: @fold_phi_multiple_insts(
; CHECK-NEXT: entry:
>From b251c121f58af6596251c1e63313026b07d53f35 Mon Sep 17 00:00:00 2001
From: Cullen Rhodes <cullen.rhodes at arm.com>
Date: Wed, 25 Jun 2025 13:17:45 +0000
Subject: [PATCH 5/5] address comments
---
llvm/test/Transforms/InstCombine/freeze.ll | 33 ++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
index e92a947ac004a..9733f1b732c3f 100644
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -910,6 +910,39 @@ exit: ; preds = %loop
ret void
}
+; Offset is still guaranteed not to be poison, so the freeze could be moved
+; here if we strip inbounds from the GEP, but this is not currently supported.
+define void @fold_phi_gep_inbounds_phi_offset(ptr %init, ptr %end, i64 noundef %n) {
+; CHECK-LABEL: @fold_phi_gep_inbounds_phi_offset(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[I:%.*]] = phi ptr [ [[INIT:%.*]], [[ENTRY:%.*]] ], [ [[I_NEXT_FR:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[OFF:%.*]] = phi i64 [ [[N:%.*]], [[ENTRY]] ], [ [[OFF_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[OFF_NEXT]] = shl i64 [[OFF]], 3
+; CHECK-NEXT: [[I_NEXT:%.*]] = getelementptr inbounds i8, ptr [[I]], i64 [[OFF_NEXT]]
+; CHECK-NEXT: [[I_NEXT_FR]] = freeze ptr [[I_NEXT]]
+; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[I_NEXT_FR]], [[END:%.*]]
+; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %loop
+
+loop: ; preds = %loop, %entry
+ %i = phi ptr [ %init, %entry ], [ %i.next.fr, %loop ]
+ %off = phi i64 [ %n, %entry ], [ %off.next, %loop ]
+ %off.next = shl i64 %off, 3
+ %i.next = getelementptr inbounds i8, ptr %i, i64 %off.next
+ %i.next.fr = freeze ptr %i.next
+ %cond = icmp eq ptr %i.next.fr, %end
+ br i1 %cond, label %loop, label %exit
+
+exit: ; preds = %loop
+ ret void
+}
+
; GEP can produce poison, check freeze isn't moved.
define void @cant_fold_phi_gep_phi_offset(ptr %init, ptr %end, i64 %n) {
; CHECK-LABEL: @cant_fold_phi_gep_phi_offset(
More information about the llvm-commits
mailing list