[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