From 2daa3626c1c88aca27b9ad0f9774a5a8f1a89666 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 10 Sep 2025 14:40:15 +0200 Subject: [PATCH] [InstCombine] Use intersectForOffsetAdd() in CommonPointerBase Transform using this will add up all the offsets, so we should use intersectForOffsetAdd() instead of plain intersection. Annoyingly, this requires specially handling the first GEP to avoid losing flags in that case. Fixes https://github.com/llvm/llvm-project/issues/157714. --- .../Transforms/InstCombine/InstCombineAddSub.cpp | 16 ++++++++++++++-- llvm/test/Transforms/InstCombine/icmp-gep.ll | 6 +++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index d934638c15e75..f9155cc660317 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -2115,6 +2115,7 @@ CommonPointerBase CommonPointerBase::compute(Value *LHS, Value *RHS) { } // Find common base and collect RHS GEPs. + bool First = true; while (true) { if (Ptrs.contains(RHS)) { Base.Ptr = RHS; @@ -2123,7 +2124,12 @@ CommonPointerBase CommonPointerBase::compute(Value *LHS, Value *RHS) { if (auto *GEP = dyn_cast(RHS)) { Base.RHSGEPs.push_back(GEP); - Base.RHSNW &= GEP->getNoWrapFlags(); + if (First) { + First = false; + Base.RHSNW = GEP->getNoWrapFlags(); + } else { + Base.RHSNW = Base.RHSNW.intersectForOffsetAdd(GEP->getNoWrapFlags()); + } RHS = GEP->getPointerOperand(); } else { // No common base. @@ -2132,13 +2138,19 @@ CommonPointerBase CommonPointerBase::compute(Value *LHS, Value *RHS) { } // Collect LHS GEPs. + First = true; while (true) { if (LHS == Base.Ptr) break; auto *GEP = cast(LHS); Base.LHSGEPs.push_back(GEP); - Base.LHSNW &= GEP->getNoWrapFlags(); + if (First) { + First = false; + Base.LHSNW = GEP->getNoWrapFlags(); + } else { + Base.LHSNW = Base.LHSNW.intersectForOffsetAdd(GEP->getNoWrapFlags()); + } LHS = GEP->getPointerOperand(); } diff --git a/llvm/test/Transforms/InstCombine/icmp-gep.ll b/llvm/test/Transforms/InstCombine/icmp-gep.ll index 1385dc3f625f1..10d7b6df8eaf3 100644 --- a/llvm/test/Transforms/InstCombine/icmp-gep.ll +++ b/llvm/test/Transforms/InstCombine/icmp-gep.ll @@ -838,9 +838,9 @@ define i1 @gep_mugtiple_ugt_not_all_nuw(ptr %base, i64 %idx, i64 %idx2) { define i1 @gep_mugtiple_ugt_inbounds_nusw(ptr %base, i64 %idx, i64 %idx2) { ; CHECK-LABEL: @gep_mugtiple_ugt_inbounds_nusw( -; CHECK-NEXT: [[GEP1_IDX1:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]] -; CHECK-NEXT: [[TMP1:%.*]] = shl i64 [[GEP1_IDX1]], 2 -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[TMP1]], 0 +; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, ptr [[BASE:%.*]], i64 [[IDX:%.*]] +; CHECK-NEXT: [[GEP2:%.*]] = getelementptr nusw i32, ptr [[GEP1]], i64 [[IDX2:%.*]] +; CHECK-NEXT: [[CMP:%.*]] = icmp ugt ptr [[GEP2]], [[BASE]] ; CHECK-NEXT: ret i1 [[CMP]] ; %gep1 = getelementptr inbounds i32, ptr %base, i64 %idx