Skip to content

[InstCombine] Pre-commit tests related to ADDLIKE+GEP->GEP+GEP. NFC #135154

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
merged 2 commits into from
Apr 14, 2025

Conversation

bjope
Copy link
Collaborator

@bjope bjope commented Apr 10, 2025

InstCombine can transform ADD+GEP into GEP+GEP. But those rewrites does not currently trigger when the ADD is a disjoint OR (which happens to be the canonical form for certain ADD operations). Add lit tests to show that we are lacking such rewrites.

Also add a test case showing that we do not preserve "inbounds nuw" and "nuw" when doing such transforms and the ADD/OR is known to be NUW.

InstCombine can transform ADD+GEP into GEP+GEP. But those rewrites
does not currently trigger when the ADD is a disjoint OR (which
happens to be the canonical form for certain ADD operations). Add
lit tests to show that we are lacking such rewrites.

Also add a test case showing that we do not preserve "inbounds nuw"
and "nuw" when doing such transforms and the ADD/OR is known to be
NUW.
@bjope bjope requested a review from nikic April 10, 2025 10:41
@llvmbot llvmbot added llvm:instcombine Covers the InstCombine, InstSimplify and AggressiveInstCombine passes llvm:transforms labels Apr 10, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 10, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Björn Pettersson (bjope)

Changes

InstCombine can transform ADD+GEP into GEP+GEP. But those rewrites does not currently trigger when the ADD is a disjoint OR (which happens to be the canonical form for certain ADD operations). Add lit tests to show that we are lacking such rewrites.

Also add a test case showing that we do not preserve "inbounds nuw" and "nuw" when doing such transforms and the ADD/OR is known to be NUW.


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

1 Files Affected:

  • (modified) llvm/test/Transforms/InstCombine/array.ll (+60)
diff --git a/llvm/test/Transforms/InstCombine/array.ll b/llvm/test/Transforms/InstCombine/array.ll
index 3edb47dda62cc..763c6e77f89ee 100644
--- a/llvm/test/Transforms/InstCombine/array.ll
+++ b/llvm/test/Transforms/InstCombine/array.ll
@@ -109,6 +109,45 @@ entry:
   ret void
 }
 
+; FIXME: Should be transformed as OR+GEP -> GEP+GEP (similar to gep_inbounds_add_nuw below).
+define ptr @gep_inbounds_nuwaddlike(ptr %ptr, i64 %a, i64 %b) {
+; CHECK-LABEL: define ptr @gep_inbounds_nuwaddlike(
+; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
+; CHECK-NEXT:    [[ADD:%.*]] = or disjoint i64 [[A]], [[B]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds nuw i32, ptr [[PTR]], i64 [[ADD]]
+; CHECK-NEXT:    ret ptr [[GEP]]
+;
+  %add = or disjoint i64 %a, %b
+  %gep = getelementptr inbounds nuw i32, ptr %ptr, i64 %add
+  ret ptr %gep
+}
+
+; FIXME: Preserve "inbounds nuw".
+define ptr @gep_inbounds_add_nuw(ptr %ptr, i64 %a, i64 %b) {
+; CHECK-LABEL: define ptr @gep_inbounds_add_nuw(
+; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[A]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[TMP1]], i64 [[B]]
+; CHECK-NEXT:    ret ptr [[GEP]]
+;
+  %add = add nuw i64 %a, %b
+  %gep = getelementptr inbounds nuw i32, ptr %ptr, i64 %add
+  ret ptr %gep
+}
+
+; FIXME: Preserve "nuw".
+define ptr @gep_add_nuw(ptr %ptr, i64 %a, i64 %b) {
+; CHECK-LABEL: define ptr @gep_add_nuw(
+; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[A]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[TMP1]], i64 [[B]]
+; CHECK-NEXT:    ret ptr [[GEP]]
+;
+  %add = add nuw i64 %a, %b
+  %gep = getelementptr nuw i32, ptr %ptr, i64 %add
+  ret ptr %gep
+}
+
 define ptr @gep_inbounds_add_nsw_nonneg(ptr %ptr, i64 %a, i64 %b) {
 ; CHECK-LABEL: define ptr @gep_inbounds_add_nsw_nonneg(
 ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
@@ -219,6 +258,27 @@ define ptr @gep_inbounds_sext_add_nonneg(ptr %ptr, i32 %a) {
   ret ptr %gep
 }
 
+; FIXME: Could be optimized similar to gep_inbounds_sext_add_nonneg above
+;        (difference is that we are using disjoint OR which is canonical form
+;        of ADD with disjoint operands).
+define ptr @gep_inbounds_sext_addlike_nonneg(ptr %ptr, i32 %a) {
+; CHECK-LABEL: define ptr @gep_inbounds_sext_addlike_nonneg(
+; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]]) {
+; CHECK-NEXT:    [[A_NNEG:%.*]] = icmp sgt i32 [[A]], -1
+; CHECK-NEXT:    call void @llvm.assume(i1 [[A_NNEG]])
+; CHECK-NEXT:    [[ADD:%.*]] = or disjoint i32 [[A]], 10
+; CHECK-NEXT:    [[IDX:%.*]] = zext nneg i32 [[ADD]] to i64
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds nuw i32, ptr [[PTR]], i64 [[IDX]]
+; CHECK-NEXT:    ret ptr [[GEP]]
+;
+  %a.nneg = icmp sgt i32 %a, -1
+  call void @llvm.assume(i1 %a.nneg)
+  %add = or disjoint i32 %a, 10
+  %idx = sext i32 %add to i64
+  %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx
+  ret ptr %gep
+}
+
 define ptr @gep_inbounds_sext_add_not_nonneg_1(ptr %ptr, i32 %a) {
 ; CHECK-LABEL: define ptr @gep_inbounds_sext_add_not_nonneg_1(
 ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]]) {

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

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

LGTM

@bjope bjope merged commit 51fe5d2 into main Apr 14, 2025
11 checks passed
@bjope bjope deleted the users/bjope/addlikegep_1 branch April 14, 2025 07:34
var-const pushed a commit to ldionne/llvm-project that referenced this pull request Apr 17, 2025
…lvm#135154)

InstCombine can transform ADD+GEP into GEP+GEP. But those rewrites does
not currently trigger when the ADD is a disjoint OR (which happens to be
the canonical form for certain ADD operations). Add lit tests to show
that we are lacking such rewrites.

Also add a test case showing that we do not preserve "inbounds nuw",
"nusw nuw" and "nuw" when doing such transforms and the ADD/OR is
known to be NUW.
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.

3 participants