Skip to content

[InstCombine] Add test for freeze of GEP with recurrence offset (NFC) #145541

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

c-rhodes
Copy link
Collaborator

The freeze should be pushed through the GEP to the ptr like in: https://godbolt.org/z/jrcozT8rz

@c-rhodes c-rhodes requested review from arsenm, nikic and david-arm June 24, 2025 16:11
@llvmbot llvmbot added llvm:instcombine Covers the InstCombine, InstSimplify and AggressiveInstCombine passes llvm:transforms labels Jun 24, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 24, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Cullen Rhodes (c-rhodes)

Changes

The freeze should be pushed through the GEP to the ptr like in: https://godbolt.org/z/jrcozT8rz


Full diff: https://github.com/llvm/llvm-project/pull/145541.diff

1 Files Affected:

  • (modified) llvm/test/Transforms/InstCombine/freeze.ll (+33)
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:

Copy link

github-actions bot commented Jun 24, 2025

✅ With the latest revision this PR passed the undef deprecator.

@c-rhodes
Copy link
Collaborator Author

the undef checker is firing because of undef in a comment, is it ok to keep this or should i use something else?

Copy link
Contributor

@david-arm david-arm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! The formatting issue refers purely to a comment so that's fine with me.

ret void
}

; GEP can produce poison, check freeze isn't moved.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly the freeze could be moved here too if we strip inbounds from the gep and push the freeze up to the pointer %i? The offset %off.next is still guaranteed not to be poison or undef I think.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly the freeze could be moved here too if we strip inbounds from the gep and push the freeze up to the pointer %i?

Yes I think so.

The offset %off.next is still guaranteed not to be poison or undef I think.

I don't believe so, %n needs to be marked noundef for that? I think this example is what you're referring to: https://godbolt.org/z/e8rGsz66W. Whereas Nikita wanted a test where the GEP can produce poison.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both variants probably have value. One requires just stripping poison, the other requires freezing an additional value.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I've also added a test for the inbounds GEP + noundef offset variant

@david-arm
Copy link
Contributor

@c-rhodes is on holiday for a while, but given this patch is only adding tests I figured it should ok for me to merge on his behalf.

@david-arm david-arm merged commit a161268 into llvm:main Jun 26, 2025
7 checks passed
anthonyhatran pushed a commit to anthonyhatran/llvm-project that referenced this pull request Jun 26, 2025
rlavaee pushed a commit to rlavaee/llvm-project that referenced this pull request Jul 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
llvm:instcombine Covers the InstCombine, InstSimplify and AggressiveInstCombine passes llvm:transforms
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants