From 289542b1e72dc4fe17093952dfb1b04cce259183 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 21 Mar 2023 10:46:13 +0100 Subject: [PATCH] [InstCombine] Fold icmp eq of non-inbounds geps We can fold equality comparisons of non-inbounds geps to offset comparison (https://alive2.llvm.org/ce/z/x2Zp8b). The inbounds requirement is only necessary for relational comparisons. --- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 3 ++- llvm/test/Transforms/InstCombine/icmp-gep.ll | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index b9473634e6dc..421b1824b965 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -884,7 +884,8 @@ Instruction *InstCombinerImpl::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS, // Only lower this if the icmp is the only user of the GEP or if we expect // the result to fold to a constant! - if (GEPsInBounds && (isa(GEPLHS) || GEPLHS->hasOneUse()) && + if ((GEPsInBounds || CmpInst::isEquality(Cond)) && + (isa(GEPLHS) || GEPLHS->hasOneUse()) && (isa(GEPRHS) || GEPRHS->hasOneUse())) { // ((gep Ptr, OFFSET1) cmp (gep Ptr, OFFSET2) ---> (OFFSET1 cmp OFFSET2) Value *L = EmitGEPOffset(GEPLHS); diff --git a/llvm/test/Transforms/InstCombine/icmp-gep.ll b/llvm/test/Transforms/InstCombine/icmp-gep.ll index 5fef7ac43536..5cc6d9f80bac 100644 --- a/llvm/test/Transforms/InstCombine/icmp-gep.ll +++ b/llvm/test/Transforms/InstCombine/icmp-gep.ll @@ -299,9 +299,8 @@ define i1 @test_gep_ult_no_inbounds(ptr %foo, i64 %i, i64 %j) { define i1 @test_gep_eq_no_inbounds(ptr %foo, i64 %i, i64 %j) { ; CHECK-LABEL: @test_gep_eq_no_inbounds( -; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i32, ptr [[FOO:%.*]], i64 [[I:%.*]] -; CHECK-NEXT: [[GEP2:%.*]] = getelementptr i8, ptr [[FOO]], i64 [[J:%.*]] -; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[GEP1]], [[GEP2]] +; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl i64 [[I:%.*]], 2 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[GEP1_IDX]], [[J:%.*]] ; CHECK-NEXT: ret i1 [[CMP]] ; %gep1 = getelementptr i32, ptr %foo, i64 %i