Skip to content

Commit 9725595

Browse files
authored
[InstCombine] Check nowrap flags when folding comparison of GEPs with the same base pointer (#121892)
Alive2: https://alive2.llvm.org/ce/z/P5XbMx Closes #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
1 parent 7612dcc commit 9725595

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -834,8 +834,9 @@ Instruction *InstCombinerImpl::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS,
834834
return replaceInstUsesWith(
835835
I, // No comparison is needed here.
836836
ConstantInt::get(I.getType(), ICmpInst::isTrueWhenEqual(Cond)));
837-
838-
else if (NumDifferences == 1 && CanFold(NW)) {
837+
// If two GEPs only differ by an index, compare them.
838+
// Note that nowrap flags are always needed when comparing two indices.
839+
else if (NumDifferences == 1 && NW != GEPNoWrapFlags::none()) {
839840
Value *LHSV = GEPLHS->getOperand(DiffOperand);
840841
Value *RHSV = GEPRHS->getOperand(DiffOperand);
841842
return NewICmp(NW, LHSV, RHSV);

llvm/test/Transforms/InstCombine/opaque-ptr.ll

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,41 @@ define i1 @cmp_gep_same_base_same_type(ptr %ptr, i64 %idx1, i64 %idx2) {
467467
ret i1 %cmp
468468
}
469469

470+
define i1 @cmp_gep_same_base_same_type_maywrap(ptr %ptr, i64 %idx1, i64 %idx2) {
471+
; CHECK-LABEL: @cmp_gep_same_base_same_type_maywrap(
472+
; CHECK-NEXT: [[CMP_UNSHIFTED:%.*]] = xor i64 [[IDX1:%.*]], [[IDX2:%.*]]
473+
; CHECK-NEXT: [[CMP_MASK:%.*]] = and i64 [[CMP_UNSHIFTED]], 4611686018427387903
474+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[CMP_MASK]], 0
475+
; CHECK-NEXT: ret i1 [[CMP]]
476+
;
477+
%gep1 = getelementptr i32, ptr %ptr, i64 %idx1
478+
%gep2 = getelementptr i32, ptr %ptr, i64 %idx2
479+
%cmp = icmp eq ptr %gep1, %gep2
480+
ret i1 %cmp
481+
}
482+
483+
define i1 @cmp_gep_same_base_same_type_nuw(ptr %ptr, i64 %idx1, i64 %idx2) {
484+
; CHECK-LABEL: @cmp_gep_same_base_same_type_nuw(
485+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IDX1:%.*]], [[IDX2:%.*]]
486+
; CHECK-NEXT: ret i1 [[CMP]]
487+
;
488+
%gep1 = getelementptr nuw i32, ptr %ptr, i64 %idx1
489+
%gep2 = getelementptr nuw i32, ptr %ptr, i64 %idx2
490+
%cmp = icmp eq ptr %gep1, %gep2
491+
ret i1 %cmp
492+
}
493+
494+
define i1 @cmp_gep_same_base_same_type_nusw(ptr %ptr, i64 %idx1, i64 %idx2) {
495+
; CHECK-LABEL: @cmp_gep_same_base_same_type_nusw(
496+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IDX1:%.*]], [[IDX2:%.*]]
497+
; CHECK-NEXT: ret i1 [[CMP]]
498+
;
499+
%gep1 = getelementptr nusw i32, ptr %ptr, i64 %idx1
500+
%gep2 = getelementptr nusw i32, ptr %ptr, i64 %idx2
501+
%cmp = icmp eq ptr %gep1, %gep2
502+
ret i1 %cmp
503+
}
504+
470505
define i1 @cmp_gep_same_base_different_type(ptr %ptr, i64 %idx1, i64 %idx2) {
471506
; CHECK-LABEL: @cmp_gep_same_base_different_type(
472507
; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[IDX1:%.*]], 2

0 commit comments

Comments
 (0)