[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
Mon Jan 6 23:09:02 PST 2025
https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/121892
Alive2: https://alive2.llvm.org/ce/z/P5XbMx
Closes https://github.com/llvm/llvm-project/issues/121890
TODO: It is still safe to perform this transform without nowrap flags if the corresponding scale factor is 1 byte: https://alive2.llvm.org/ce/z/J-JCJd
>From 953329a085efdd9ea60481a505f8c582b1c7b632 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/2] [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 c964487b40d49b911d9558f96480c321a9da3ac5 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/2] [InstCombine] Check nowrap flags when folding comparison
of GEPs with the same base pointer
---
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 7 +++++--
llvm/test/Transforms/InstCombine/opaque-ptr.ll | 4 +++-
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 8b23583c510637..9f136860724db8 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -833,8 +833,11 @@ 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)));
-
- else if (NumDifferences == 1 && CanFold(NW)) {
+ // 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
More information about the llvm-commits
mailing list