[llvm] [InstCombine] Check nowrap flags when folding comparison of GEPs with the same base pointer (PR #121892)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Sat Feb 1 03:25:06 PST 2025
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/121892
>From a3fa39044cfde3fb1b4ee763c44ef437d56eb231 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 7 Jan 2025 14:52:31 +0800
Subject: [PATCH 1/4] [InstCombine] Add pre-commit tests. NFC.
---
.../test/Transforms/InstCombine/opaque-ptr.ll | 33 +++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/opaque-ptr.ll b/llvm/test/Transforms/InstCombine/opaque-ptr.ll
index b05274658e812e..c6e778d79a5f8d 100644
--- a/llvm/test/Transforms/InstCombine/opaque-ptr.ll
+++ b/llvm/test/Transforms/InstCombine/opaque-ptr.ll
@@ -467,6 +467,39 @@ define i1 @cmp_gep_same_base_same_type(ptr %ptr, i64 %idx1, i64 %idx2) {
ret i1 %cmp
}
+define i1 @cmp_gep_same_base_same_type_maywrap(ptr %ptr, i64 %idx1, i64 %idx2) {
+; CHECK-LABEL: @cmp_gep_same_base_same_type_maywrap(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IDX1:%.*]], [[IDX2:%.*]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %gep1 = getelementptr i32, ptr %ptr, i64 %idx1
+ %gep2 = getelementptr i32, ptr %ptr, i64 %idx2
+ %cmp = icmp eq ptr %gep1, %gep2
+ ret i1 %cmp
+}
+
+define i1 @cmp_gep_same_base_same_type_nuw(ptr %ptr, i64 %idx1, i64 %idx2) {
+; CHECK-LABEL: @cmp_gep_same_base_same_type_nuw(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IDX1:%.*]], [[IDX2:%.*]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %gep1 = getelementptr nuw i32, ptr %ptr, i64 %idx1
+ %gep2 = getelementptr nuw i32, ptr %ptr, i64 %idx2
+ %cmp = icmp eq ptr %gep1, %gep2
+ ret i1 %cmp
+}
+
+define i1 @cmp_gep_same_base_same_type_nusw(ptr %ptr, i64 %idx1, i64 %idx2) {
+; CHECK-LABEL: @cmp_gep_same_base_same_type_nusw(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IDX1:%.*]], [[IDX2:%.*]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %gep1 = getelementptr nusw i32, ptr %ptr, i64 %idx1
+ %gep2 = getelementptr nusw i32, ptr %ptr, i64 %idx2
+ %cmp = icmp eq ptr %gep1, %gep2
+ ret i1 %cmp
+}
+
define i1 @cmp_gep_same_base_different_type(ptr %ptr, i64 %idx1, i64 %idx2) {
; CHECK-LABEL: @cmp_gep_same_base_different_type(
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[IDX1:%.*]], 2
>From b14982b61f8f7944d676bd369f3bcdedab06d832 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 7 Jan 2025 15:04:54 +0800
Subject: [PATCH 2/4] [InstCombine] Check nowrap flags when folding comparison
of GEPs with the same base pointer
---
.../Transforms/InstCombine/InstCombineCompares.cpp | 14 ++++++++------
llvm/test/Transforms/InstCombine/opaque-ptr.ll | 4 +++-
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 9e9739ac244005..e4a2dc279ed3d0 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -830,12 +830,14 @@ Instruction *InstCombinerImpl::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
DiffOperand = i;
}
- if (NumDifferences == 0) // SAME GEP?
- return replaceInstUsesWith(
- I, // No comparison is needed here.
- ConstantInt::get(I.getType(), ICmpInst::isTrueWhenEqual(Cond)));
-
- else if (NumDifferences == 1 && CanFold(NW)) {
+ if (NumDifferences == 0) // SAME GEP?
+ return replaceInstUsesWith(I, // No comparison is needed here.
+ ConstantInt::get(I.getType(), ICmpInst::isTrueWhenEqual(Cond)));
+ // If two GEPs only differ by an index/the base pointer, compare them.
+ // Note that nowrap flags are always needed when comparing two indices.
+ else if (NumDifferences == 1 &&
+ (DiffOperand == 0 ? CanFold(NW)
+ : NW != GEPNoWrapFlags::none())) {
Value *LHSV = GEPLHS->getOperand(DiffOperand);
Value *RHSV = GEPRHS->getOperand(DiffOperand);
return NewICmp(NW, LHSV, RHSV);
diff --git a/llvm/test/Transforms/InstCombine/opaque-ptr.ll b/llvm/test/Transforms/InstCombine/opaque-ptr.ll
index c6e778d79a5f8d..be734243d14a10 100644
--- a/llvm/test/Transforms/InstCombine/opaque-ptr.ll
+++ b/llvm/test/Transforms/InstCombine/opaque-ptr.ll
@@ -469,7 +469,9 @@ define i1 @cmp_gep_same_base_same_type(ptr %ptr, i64 %idx1, i64 %idx2) {
define i1 @cmp_gep_same_base_same_type_maywrap(ptr %ptr, i64 %idx1, i64 %idx2) {
; CHECK-LABEL: @cmp_gep_same_base_same_type_maywrap(
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IDX1:%.*]], [[IDX2:%.*]]
+; CHECK-NEXT: [[CMP_UNSHIFTED:%.*]] = xor i64 [[IDX1:%.*]], [[IDX2:%.*]]
+; CHECK-NEXT: [[CMP_MASK:%.*]] = and i64 [[CMP_UNSHIFTED]], 4611686018427387903
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[CMP_MASK]], 0
; CHECK-NEXT: ret i1 [[CMP]]
;
%gep1 = getelementptr i32, ptr %ptr, i64 %idx1
>From d59529c6ab99fd91c31af26127b1f1587e515e8c Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 7 Jan 2025 17:34:09 +0800
Subject: [PATCH 3/4] [InstCombine] Address review comments. NFC.
---
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index e4a2dc279ed3d0..552f19341c0fc2 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -833,11 +833,9 @@ Instruction *InstCombinerImpl::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
if (NumDifferences == 0) // SAME GEP?
return replaceInstUsesWith(I, // No comparison is needed here.
ConstantInt::get(I.getType(), ICmpInst::isTrueWhenEqual(Cond)));
- // If two GEPs only differ by an index/the base pointer, compare them.
+ // If two GEPs only differ by an index, compare them.
// Note that nowrap flags are always needed when comparing two indices.
- else if (NumDifferences == 1 &&
- (DiffOperand == 0 ? CanFold(NW)
- : NW != GEPNoWrapFlags::none())) {
+ else if (NumDifferences == 1 && NW != GEPNoWrapFlags::none()) {
Value *LHSV = GEPLHS->getOperand(DiffOperand);
Value *RHSV = GEPRHS->getOperand(DiffOperand);
return NewICmp(NW, LHSV, RHSV);
>From 1cf4654bc67f5d5535cf089bf5ec937d53418660 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sat, 1 Feb 2025 19:23:53 +0800
Subject: [PATCH 4/4] format
---
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 552f19341c0fc2..a8a5cb2b20d7ad 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -830,9 +830,10 @@ Instruction *InstCombinerImpl::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
DiffOperand = i;
}
- if (NumDifferences == 0) // SAME GEP?
- return replaceInstUsesWith(I, // No comparison is needed here.
- ConstantInt::get(I.getType(), ICmpInst::isTrueWhenEqual(Cond)));
+ if (NumDifferences == 0) // SAME GEP?
+ return replaceInstUsesWith(
+ I, // No comparison is needed here.
+ ConstantInt::get(I.getType(), ICmpInst::isTrueWhenEqual(Cond)));
// If two GEPs only differ by an index, compare them.
// Note that nowrap flags are always needed when comparing two indices.
else if (NumDifferences == 1 && NW != GEPNoWrapFlags::none()) {
More information about the llvm-commits
mailing list