From: Nikita Popov Date: Tue, 21 Mar 2023 09:16:51 +0000 (+0100) Subject: [InstCombine] Fold icmp eq of non-inbounds gep with base pointer X-Git-Tag: upstream/17.0.6~14148 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e8ec42b80b5dc75186dca543572416f2f2e21475;p=platform%2Fupstream%2Fllvm.git [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 --- 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