diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 5a4791870ac77..b64ac20ab0533 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -834,7 +834,7 @@ Instruction *InstCombinerImpl::foldGEPICmp(GEPOperator *GEPLHS, Value *RHS, return replaceInstUsesWith(I, // No comparison is needed here. ConstantInt::get(I.getType(), ICmpInst::isTrueWhenEqual(Cond))); - else if (NumDifferences == 1 && CanFold(NW)) { + else if (NumDifferences == 1 && NW != GEPNoWrapFlags::none()) { Value *LHSV = GEPLHS->getOperand(DiffOperand); Value *RHSV = GEPRHS->getOperand(DiffOperand); return NewICmp(NW, LHSV, RHSV); diff --git a/llvm/test/Transforms/InstCombine/opaque-ptr.ll b/llvm/test/Transforms/InstCombine/opaque-ptr.ll index b05274658e812..be734243d14a1 100644 --- a/llvm/test/Transforms/InstCombine/opaque-ptr.ll +++ b/llvm/test/Transforms/InstCombine/opaque-ptr.ll @@ -467,6 +467,41 @@ define i1 @cmp_gep_same_base_same_type(ptr %ptr, i64 %idx1, i64 %idx2) { ret i1 %cmp } +define i1 @cmp_gep_same_base_same_type_maywrap(ptr %ptr, i64 %idx1, i64 %idx2) { +; CHECK-LABEL: @cmp_gep_same_base_same_type_maywrap( +; CHECK-NEXT: [[CMP_UNSHIFTED:%.*]] = xor i64 [[IDX1:%.*]], [[IDX2:%.*]] +; CHECK-NEXT: [[CMP_MASK:%.*]] = and i64 [[CMP_UNSHIFTED]], 4611686018427387903 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[CMP_MASK]], 0 +; CHECK-NEXT: ret i1 [[CMP]] +; + %gep1 = getelementptr i32, ptr %ptr, i64 %idx1 + %gep2 = getelementptr i32, ptr %ptr, i64 %idx2 + %cmp = icmp eq ptr %gep1, %gep2 + ret i1 %cmp +} + +define i1 @cmp_gep_same_base_same_type_nuw(ptr %ptr, i64 %idx1, i64 %idx2) { +; CHECK-LABEL: @cmp_gep_same_base_same_type_nuw( +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IDX1:%.*]], [[IDX2:%.*]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %gep1 = getelementptr nuw i32, ptr %ptr, i64 %idx1 + %gep2 = getelementptr nuw i32, ptr %ptr, i64 %idx2 + %cmp = icmp eq ptr %gep1, %gep2 + ret i1 %cmp +} + +define i1 @cmp_gep_same_base_same_type_nusw(ptr %ptr, i64 %idx1, i64 %idx2) { +; CHECK-LABEL: @cmp_gep_same_base_same_type_nusw( +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[IDX1:%.*]], [[IDX2:%.*]] +; CHECK-NEXT: ret i1 [[CMP]] +; + %gep1 = getelementptr nusw i32, ptr %ptr, i64 %idx1 + %gep2 = getelementptr nusw i32, ptr %ptr, i64 %idx2 + %cmp = icmp eq ptr %gep1, %gep2 + ret i1 %cmp +} + define i1 @cmp_gep_same_base_different_type(ptr %ptr, i64 %idx1, i64 %idx2) { ; CHECK-LABEL: @cmp_gep_same_base_different_type( ; CHECK-NEXT: [[GEP1_IDX:%.*]] = shl nsw i64 [[IDX1:%.*]], 2