[llvm] e8ec42b - [InstCombine] Fold icmp eq of non-inbounds gep with base pointer

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 21 02:20:19 PDT 2023


Author: Nikita Popov
Date: 2023-03-21T10:20:11+01:00
New Revision: e8ec42b80b5dc75186dca543572416f2f2e21475

URL: https://github.com/llvm/llvm-project/commit/e8ec42b80b5dc75186dca543572416f2f2e21475
DIFF: https://github.com/llvm/llvm-project/commit/e8ec42b80b5dc75186dca543572416f2f2e21475.diff

LOG: [InstCombine] Fold icmp eq of non-inbounds gep with base pointer

For equality comparisons, we don't need the gep to be inbounds:
https://alive2.llvm.org/ce/z/Fe_kn2

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/test/Transforms/InstCombine/compare-alloca.ll
    llvm/test/Transforms/InstCombine/icmp-gep.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index b1d59d355eb7..b9473634e6dc 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -741,7 +741,7 @@ Instruction *InstCombinerImpl::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
     RHS = RHS->stripPointerCasts();
 
   Value *PtrBase = GEPLHS->getOperand(0);
-  if (PtrBase == RHS && GEPLHS->isInBounds()) {
+  if (PtrBase == RHS && (GEPLHS->isInBounds() || ICmpInst::isEquality(Cond))) {
     // ((gep Ptr, OFFSET) cmp Ptr)   ---> (OFFSET cmp 0).
     Value *Offset = EmitGEPOffset(GEPLHS);
     return new ICmpInst(ICmpInst::getSignedPredicate(Cond), Offset,

diff  --git a/llvm/test/Transforms/InstCombine/compare-alloca.ll b/llvm/test/Transforms/InstCombine/compare-alloca.ll
index 6ba1850cba3b..164398382e9e 100644
--- a/llvm/test/Transforms/InstCombine/compare-alloca.ll
+++ b/llvm/test/Transforms/InstCombine/compare-alloca.ll
@@ -292,11 +292,8 @@ define void @select_alloca_unrelated_ptr(i1 %c, ptr %p, ptr %p2) {
 
 define void @alloca_offset_icmp(ptr %p, i32 %offset) {
 ; CHECK-LABEL: @alloca_offset_icmp(
-; CHECK-NEXT:    [[M:%.*]] = alloca [4 x i8], align 1
-; CHECK-NEXT:    [[G:%.*]] = getelementptr i8, ptr [[M]], i32 [[OFFSET:%.*]]
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq ptr [[M]], [[P:%.*]]
-; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq ptr [[M]], [[G]]
-; CHECK-NEXT:    call void @witness(i1 [[CMP1]], i1 [[CMP2]])
+; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[OFFSET:%.*]], 0
+; CHECK-NEXT:    call void @witness(i1 false, i1 [[CMP2]])
 ; CHECK-NEXT:    ret void
 ;
   %m = alloca [4 x i8]

diff  --git a/llvm/test/Transforms/InstCombine/icmp-gep.ll b/llvm/test/Transforms/InstCombine/icmp-gep.ll
index bc8bc7b74d3b..1ccd3819e659 100644
--- a/llvm/test/Transforms/InstCombine/icmp-gep.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-gep.ll
@@ -8,8 +8,7 @@ declare void @use(ptr)
 
 define i1 @eq_base(ptr %x, i64 %y) {
 ; CHECK-LABEL: @eq_base(
-; CHECK-NEXT:    [[G:%.*]] = getelementptr i8, ptr [[X:%.*]], i64 [[Y:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = icmp eq ptr [[G]], [[X]]
+; CHECK-NEXT:    [[R:%.*]] = icmp eq i64 [[Y:%.*]], 0
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %g = getelementptr i8, ptr %x, i64 %y
@@ -20,8 +19,7 @@ define i1 @eq_base(ptr %x, i64 %y) {
 define i1 @ne_base_commute(i64 %y) {
 ; CHECK-LABEL: @ne_base_commute(
 ; CHECK-NEXT:    [[X:%.*]] = call ptr @getptr()
-; CHECK-NEXT:    [[G:%.*]] = getelementptr i8, ptr [[X]], i64 [[Y:%.*]]
-; CHECK-NEXT:    [[R:%.*]] = icmp ne ptr [[X]], [[G]]
+; CHECK-NEXT:    [[R:%.*]] = icmp ne i64 [[Y:%.*]], 0
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %x = call ptr @getptr() ; thwart complexity-based canonicalization
@@ -176,8 +174,8 @@ define i1 @eq_base_inbounds_commute_use(i64 %y) {
 
 define i1 @eq_bitcast_base(ptr %p, i64 %x) {
 ; CHECK-LABEL: @eq_bitcast_base(
-; CHECK-NEXT:    [[GEP:%.*]] = getelementptr [2 x i8], ptr [[P:%.*]], i64 [[X:%.*]], i64 0
-; CHECK-NEXT:    [[R:%.*]] = icmp eq ptr [[GEP]], [[P]]
+; CHECK-NEXT:    [[GEP_IDX_MASK:%.*]] = and i64 [[X:%.*]], 9223372036854775807
+; CHECK-NEXT:    [[R:%.*]] = icmp eq i64 [[GEP_IDX_MASK]], 0
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %gep = getelementptr [2 x i8], ptr %p, i64 %x, i64 0
@@ -305,8 +303,8 @@ define i1 @test60_as1(ptr addrspace(1) %foo, i64 %i, i64 %j) {
 define i1 @test60_addrspacecast(ptr %foo, i64 %i, i64 %j) {
 ; CHECK-LABEL: @test60_addrspacecast(
 ; CHECK-NEXT:    [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i64 [[GEP1_IDX]], [[J:%.*]]
-; CHECK-NEXT:    ret i1 [[TMP1]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i64 [[GEP1_IDX]], [[J:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %bit = addrspacecast ptr %foo to ptr addrspace(3)
   %gep1 = getelementptr inbounds i32, ptr addrspace(3) %bit, i64 %i
@@ -320,8 +318,8 @@ define i1 @test60_addrspacecast_smaller(ptr %foo, i16 %i, i64 %j) {
 ; CHECK-LABEL: @test60_addrspacecast_smaller(
 ; CHECK-NEXT:    [[GEP1_IDX:%.*]] = shl nsw i16 [[I:%.*]], 2
 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 [[J:%.*]] to i16
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i16 [[GEP1_IDX]], [[TMP1]]
-; CHECK-NEXT:    ret i1 [[TMP2]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[GEP1_IDX]], [[TMP1]]
+; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %bit = addrspacecast ptr %foo to ptr addrspace(1)
   %gep1 = getelementptr inbounds i32, ptr addrspace(1) %bit, i16 %i
@@ -335,8 +333,8 @@ define i1 @test60_addrspacecast_larger(ptr addrspace(1) %foo, i32 %i, i16 %j) {
 ; CHECK-LABEL: @test60_addrspacecast_larger(
 ; CHECK-NEXT:    [[I_TR:%.*]] = trunc i32 [[I:%.*]] to i16
 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i16 [[I_TR]], 2
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i16 [[TMP1]], [[J:%.*]]
-; CHECK-NEXT:    ret i1 [[TMP2]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i16 [[TMP1]], [[J:%.*]]
+; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %bit = addrspacecast ptr addrspace(1) %foo to ptr addrspace(2)
   %gep1 = getelementptr inbounds i32, ptr addrspace(2) %bit, i32 %i


        


More information about the llvm-commits mailing list