Skip to content

Commit bdc6faf

Browse files
committed
[InstCombine] Support nusw in icmp of two geps with same base
Proof: https://alive2.llvm.org/ce/z/BYNQ7s
1 parent 9c5a84b commit bdc6faf

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,7 @@ Instruction *InstCombinerImpl::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
786786
return transformToIndexedCompare(GEPLHS, RHS, Cond, DL, *this);
787787
}
788788

789-
bool GEPsInBounds = GEPLHS->isInBounds() && GEPRHS->isInBounds();
789+
GEPNoWrapFlags NW = GEPLHS->getNoWrapFlags() & GEPRHS->getNoWrapFlags();
790790
if (GEPLHS->getNumOperands() == GEPRHS->getNumOperands() &&
791791
GEPLHS->getSourceElementType() == GEPRHS->getSourceElementType()) {
792792
// If the GEPs only differ by one index, compare it.
@@ -814,15 +814,15 @@ Instruction *InstCombinerImpl::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
814814
return replaceInstUsesWith(I, // No comparison is needed here.
815815
ConstantInt::get(I.getType(), ICmpInst::isTrueWhenEqual(Cond)));
816816

817-
else if (NumDifferences == 1 && GEPsInBounds) {
817+
else if (NumDifferences == 1 && NW.hasNoUnsignedSignedWrap()) {
818818
Value *LHSV = GEPLHS->getOperand(DiffOperand);
819819
Value *RHSV = GEPRHS->getOperand(DiffOperand);
820820
// Make sure we do a signed comparison here.
821821
return new ICmpInst(ICmpInst::getSignedPredicate(Cond), LHSV, RHSV);
822822
}
823823
}
824824

825-
if (GEPsInBounds || CmpInst::isEquality(Cond)) {
825+
if (NW.hasNoUnsignedSignedWrap() || CmpInst::isEquality(Cond)) {
826826
// ((gep Ptr, OFFSET1) cmp (gep Ptr, OFFSET2) ---> (OFFSET1 cmp OFFSET2)
827827
Value *L = EmitGEPOffset(GEPLHS, /*RewriteGEP=*/true);
828828
Value *R = EmitGEPOffset(GEPRHS, /*RewriteGEP=*/true);

llvm/test/Transforms/InstCombine/icmp-gep.ll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,30 @@ define i1 @test60(ptr %foo, i64 %i, i64 %j) {
295295
ret i1 %cmp
296296
}
297297

298+
define i1 @test60_nusw(ptr %foo, i64 %i, i64 %j) {
299+
; CHECK-LABEL: @test60_nusw(
300+
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2
301+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[GEP1_IDX]], [[J:%.*]]
302+
; CHECK-NEXT: ret i1 [[CMP]]
303+
;
304+
%gep1 = getelementptr nusw i32, ptr %foo, i64 %i
305+
%gep2 = getelementptr nusw i8, ptr %foo, i64 %j
306+
%cmp = icmp ult ptr %gep1, %gep2
307+
ret i1 %cmp
308+
}
309+
310+
define i1 @test60_nusw_inbounds(ptr %foo, i64 %i, i64 %j) {
311+
; CHECK-LABEL: @test60_nusw_inbounds(
312+
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[I:%.*]], 2
313+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[GEP1_IDX]], [[J:%.*]]
314+
; CHECK-NEXT: ret i1 [[CMP]]
315+
;
316+
%gep1 = getelementptr nusw i32, ptr %foo, i64 %i
317+
%gep2 = getelementptr inbounds i8, ptr %foo, i64 %j
318+
%cmp = icmp ult ptr %gep1, %gep2
319+
ret i1 %cmp
320+
}
321+
298322
define i1 @test_gep_ult_no_inbounds(ptr %foo, i64 %i, i64 %j) {
299323
; CHECK-LABEL: @test_gep_ult_no_inbounds(
300324
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i32, ptr [[FOO:%.*]], i64 [[I:%.*]]

0 commit comments

Comments
 (0)