[llvm] b27ab06 - [InstCombine] Preserve flags for difference of gep chains (#143488)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 10 07:19:48 PDT 2025


Author: Nikita Popov
Date: 2025-06-10T16:19:45+02:00
New Revision: b27ab06a3d3f7f37496c5fa4dc367a3be0a8498d

URL: https://github.com/llvm/llvm-project/commit/b27ab06a3d3f7f37496c5fa4dc367a3be0a8498d
DIFF: https://github.com/llvm/llvm-project/commit/b27ab06a3d3f7f37496c5fa4dc367a3be0a8498d.diff

LOG: [InstCombine] Preserve flags for difference of gep chains (#143488)

When expanding the offset of a GEP chain via a series of adds, try to
preserve the nsw/nuw flags based on inbounds/nuw. This is a followup to
https://github.com/llvm/llvm-project/pull/142958.

Proof: https://alive2.llvm.org/ce/z/8HiFYY (note that preserving nsw in
the nusw case is not valid)

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
    llvm/test/Transforms/InstCombine/sub-gep.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 4b6958618557f..fc7dd302b27a5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2146,12 +2146,14 @@ Value *InstCombinerImpl::OptimizePointerDifference(Value *LHS, Value *RHS,
   bool RewriteGEPs = !Base.LHSGEPs.empty() && !Base.RHSGEPs.empty();
 
   Type *IdxTy = DL.getIndexType(Base.Ptr->getType());
-  auto EmitOffsetFromBase = [&](ArrayRef<GEPOperator *> GEPs) -> Value * {
+  auto EmitOffsetFromBase = [&](ArrayRef<GEPOperator *> GEPs,
+                                GEPNoWrapFlags NW) -> Value * {
     Value *Sum = nullptr;
     for (GEPOperator *GEP : reverse(GEPs)) {
       Value *Offset = EmitGEPOffset(GEP, RewriteGEPs);
       if (Sum)
-        Sum = Builder.CreateAdd(Sum, Offset);
+        Sum = Builder.CreateAdd(Sum, Offset, "", NW.hasNoUnsignedWrap(),
+                                NW.isInBounds());
       else
         Sum = Offset;
     }
@@ -2160,8 +2162,8 @@ Value *InstCombinerImpl::OptimizePointerDifference(Value *LHS, Value *RHS,
     return Sum;
   };
 
-  Value *Result = EmitOffsetFromBase(Base.LHSGEPs);
-  Value *Offset2 = EmitOffsetFromBase(Base.RHSGEPs);
+  Value *Result = EmitOffsetFromBase(Base.LHSGEPs, Base.LHSNW);
+  Value *Offset2 = EmitOffsetFromBase(Base.RHSGEPs, Base.RHSNW);
 
   // If this is a single inbounds GEP and the original sub was nuw,
   // then the final multiplication is also nuw.

diff  --git a/llvm/test/Transforms/InstCombine/sub-gep.ll b/llvm/test/Transforms/InstCombine/sub-gep.ll
index c2122f20a56c2..9444fef1887d3 100644
--- a/llvm/test/Transforms/InstCombine/sub-gep.ll
+++ b/llvm/test/Transforms/InstCombine/sub-gep.ll
@@ -945,7 +945,7 @@ define i64 @multiple_geps_two_chains_gep_base(ptr %base, i64 %base.idx, i64 %idx
 
 define i64 @multiple_geps_inbounds(ptr %base, i64 %idx, i64 %idx2) {
 ; CHECK-LABEL: @multiple_geps_inbounds(
-; CHECK-NEXT:    [[D:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]
+; CHECK-NEXT:    [[D:%.*]] = add nsw i64 [[IDX:%.*]], [[IDX2:%.*]]
 ; CHECK-NEXT:    ret i64 [[D]]
 ;
   %p2 = getelementptr inbounds i8, ptr %base, i64 %idx
@@ -971,7 +971,7 @@ define i64 @multiple_geps_nusw(ptr %base, i64 %idx, i64 %idx2) {
 
 define i64 @multiple_geps_nuw(ptr %base, i64 %idx, i64 %idx2) {
 ; CHECK-LABEL: @multiple_geps_nuw(
-; CHECK-NEXT:    [[D:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]
+; CHECK-NEXT:    [[D:%.*]] = add nuw i64 [[IDX:%.*]], [[IDX2:%.*]]
 ; CHECK-NEXT:    ret i64 [[D]]
 ;
   %p2 = getelementptr nuw i8, ptr %base, i64 %idx
@@ -985,7 +985,7 @@ define i64 @multiple_geps_nuw(ptr %base, i64 %idx, i64 %idx2) {
 
 define i64 @multiple_geps_inbounds_nuw(ptr %base, i64 %idx, i64 %idx2) {
 ; CHECK-LABEL: @multiple_geps_inbounds_nuw(
-; CHECK-NEXT:    [[D:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]
+; CHECK-NEXT:    [[D:%.*]] = add nuw nsw i64 [[IDX:%.*]], [[IDX2:%.*]]
 ; CHECK-NEXT:    ret i64 [[D]]
 ;
   %p2 = getelementptr inbounds nuw i8, ptr %base, i64 %idx


        


More information about the llvm-commits mailing list