Skip to content

Commit b27ab06

Browse files
authored
[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 #142958. Proof: https://alive2.llvm.org/ce/z/8HiFYY (note that preserving nsw in the nusw case is not valid)
1 parent 99f6cb8 commit b27ab06

File tree

2 files changed

+9
-7
lines changed

2 files changed

+9
-7
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,12 +2146,14 @@ Value *InstCombinerImpl::OptimizePointerDifference(Value *LHS, Value *RHS,
21462146
bool RewriteGEPs = !Base.LHSGEPs.empty() && !Base.RHSGEPs.empty();
21472147

21482148
Type *IdxTy = DL.getIndexType(Base.Ptr->getType());
2149-
auto EmitOffsetFromBase = [&](ArrayRef<GEPOperator *> GEPs) -> Value * {
2149+
auto EmitOffsetFromBase = [&](ArrayRef<GEPOperator *> GEPs,
2150+
GEPNoWrapFlags NW) -> Value * {
21502151
Value *Sum = nullptr;
21512152
for (GEPOperator *GEP : reverse(GEPs)) {
21522153
Value *Offset = EmitGEPOffset(GEP, RewriteGEPs);
21532154
if (Sum)
2154-
Sum = Builder.CreateAdd(Sum, Offset);
2155+
Sum = Builder.CreateAdd(Sum, Offset, "", NW.hasNoUnsignedWrap(),
2156+
NW.isInBounds());
21552157
else
21562158
Sum = Offset;
21572159
}
@@ -2160,8 +2162,8 @@ Value *InstCombinerImpl::OptimizePointerDifference(Value *LHS, Value *RHS,
21602162
return Sum;
21612163
};
21622164

2163-
Value *Result = EmitOffsetFromBase(Base.LHSGEPs);
2164-
Value *Offset2 = EmitOffsetFromBase(Base.RHSGEPs);
2165+
Value *Result = EmitOffsetFromBase(Base.LHSGEPs, Base.LHSNW);
2166+
Value *Offset2 = EmitOffsetFromBase(Base.RHSGEPs, Base.RHSNW);
21652167

21662168
// If this is a single inbounds GEP and the original sub was nuw,
21672169
// then the final multiplication is also nuw.

llvm/test/Transforms/InstCombine/sub-gep.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,7 @@ define i64 @multiple_geps_two_chains_gep_base(ptr %base, i64 %base.idx, i64 %idx
945945

946946
define i64 @multiple_geps_inbounds(ptr %base, i64 %idx, i64 %idx2) {
947947
; CHECK-LABEL: @multiple_geps_inbounds(
948-
; CHECK-NEXT: [[D:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]
948+
; CHECK-NEXT: [[D:%.*]] = add nsw i64 [[IDX:%.*]], [[IDX2:%.*]]
949949
; CHECK-NEXT: ret i64 [[D]]
950950
;
951951
%p2 = getelementptr inbounds i8, ptr %base, i64 %idx
@@ -971,7 +971,7 @@ define i64 @multiple_geps_nusw(ptr %base, i64 %idx, i64 %idx2) {
971971

972972
define i64 @multiple_geps_nuw(ptr %base, i64 %idx, i64 %idx2) {
973973
; CHECK-LABEL: @multiple_geps_nuw(
974-
; CHECK-NEXT: [[D:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]
974+
; CHECK-NEXT: [[D:%.*]] = add nuw i64 [[IDX:%.*]], [[IDX2:%.*]]
975975
; CHECK-NEXT: ret i64 [[D]]
976976
;
977977
%p2 = getelementptr nuw i8, ptr %base, i64 %idx
@@ -985,7 +985,7 @@ define i64 @multiple_geps_nuw(ptr %base, i64 %idx, i64 %idx2) {
985985

986986
define i64 @multiple_geps_inbounds_nuw(ptr %base, i64 %idx, i64 %idx2) {
987987
; CHECK-LABEL: @multiple_geps_inbounds_nuw(
988-
; CHECK-NEXT: [[D:%.*]] = add i64 [[IDX:%.*]], [[IDX2:%.*]]
988+
; CHECK-NEXT: [[D:%.*]] = add nuw nsw i64 [[IDX:%.*]], [[IDX2:%.*]]
989989
; CHECK-NEXT: ret i64 [[D]]
990990
;
991991
%p2 = getelementptr inbounds nuw i8, ptr %base, i64 %idx

0 commit comments

Comments
 (0)