Skip to content

Commit 3c0cc7b

Browse files
author
git apple-llvm automerger
committed
Merge commit 'cbe1760f0288' from llvm.org/main into next
2 parents 9f758c2 + cbe1760 commit 3c0cc7b

File tree

2 files changed

+20
-40
lines changed

2 files changed

+20
-40
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2001,29 +2001,13 @@ Value *InstCombinerImpl::OptimizePointerDifference(Value *LHS, Value *RHS,
20012001
if (!GEP1)
20022002
return nullptr;
20032003

2004-
if (GEP2) {
2005-
// (gep X, ...) - (gep X, ...)
2006-
//
2007-
// Avoid duplicating the arithmetic if there are more than one non-constant
2008-
// indices between the two GEPs and either GEP has a non-constant index and
2009-
// multiple users. If zero non-constant index, the result is a constant and
2010-
// there is no duplication. If one non-constant index, the result is an add
2011-
// or sub with a constant, which is no larger than the original code, and
2012-
// there's no duplicated arithmetic, even if either GEP has multiple
2013-
// users. If more than one non-constant indices combined, as long as the GEP
2014-
// with at least one non-constant index doesn't have multiple users, there
2015-
// is no duplication.
2016-
unsigned NumNonConstantIndices1 = GEP1->countNonConstantIndices();
2017-
unsigned NumNonConstantIndices2 = GEP2->countNonConstantIndices();
2018-
if (NumNonConstantIndices1 + NumNonConstantIndices2 > 1 &&
2019-
((NumNonConstantIndices1 > 0 && !GEP1->hasOneUse()) ||
2020-
(NumNonConstantIndices2 > 0 && !GEP2->hasOneUse()))) {
2021-
return nullptr;
2022-
}
2023-
}
2004+
// To avoid duplicating the offset arithmetic, rewrite the GEP to use the
2005+
// computed offset.
2006+
// TODO: We should probably do this even if there is only one GEP.
2007+
bool RewriteGEPs = GEP2 != nullptr;
20242008

20252009
// Emit the offset of the GEP and an intptr_t.
2026-
Value *Result = EmitGEPOffset(GEP1);
2010+
Value *Result = EmitGEPOffset(GEP1, RewriteGEPs);
20272011

20282012
// If this is a single inbounds GEP and the original sub was nuw,
20292013
// then the final multiplication is also nuw.
@@ -2035,7 +2019,7 @@ Value *InstCombinerImpl::OptimizePointerDifference(Value *LHS, Value *RHS,
20352019
// If we have a 2nd GEP of the same base pointer, subtract the offsets.
20362020
// If both GEPs are inbounds, then the subtract does not have signed overflow.
20372021
if (GEP2) {
2038-
Value *Offset = EmitGEPOffset(GEP2);
2022+
Value *Offset = EmitGEPOffset(GEP2, RewriteGEPs);
20392023
Result = Builder.CreateSub(Result, Offset, "gepdiff", /* NUW */ false,
20402024
GEP1->isInBounds() && GEP2->isInBounds());
20412025
}

llvm/test/Transforms/InstCombine/sub.ll

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,7 +1123,8 @@ define i64 @test58(ptr %foo, i64 %i, i64 %j) {
11231123

11241124
define i64 @test59(ptr %foo, i64 %i) {
11251125
; CHECK-LABEL: @test59(
1126-
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [100 x [100 x i8]], ptr [[FOO:%.*]], i64 0, i64 42, i64 [[I:%.*]]
1126+
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[FOO:%.*]], i64 [[I:%.*]]
1127+
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr i8, ptr [[TMP1]], i64 4200
11271128
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i8, ptr [[FOO]], i64 4200
11281129
; CHECK-NEXT: store ptr [[GEP1]], ptr @dummy_global1, align 8
11291130
; CHECK-NEXT: store ptr [[GEP2]], ptr @dummy_global2, align 8
@@ -1142,13 +1143,12 @@ define i64 @test59(ptr %foo, i64 %i) {
11421143

11431144
define i64 @test60(ptr %foo, i64 %i, i64 %j) {
11441145
; CHECK-LABEL: @test60(
1145-
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [100 x [100 x i8]], ptr [[FOO:%.*]], i64 0, i64 [[J:%.*]], i64 [[I:%.*]]
1146-
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i8, ptr [[FOO]], i64 4200
1147-
; CHECK-NEXT: [[CAST1:%.*]] = ptrtoint ptr [[GEP1]] to i64
1148-
; CHECK-NEXT: [[CAST2:%.*]] = ptrtoint ptr [[GEP2]] to i64
1149-
; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[CAST1]], [[CAST2]]
1146+
; CHECK-NEXT: [[GEP1_IDX:%.*]] = mul nsw i64 [[J:%.*]], 100
1147+
; CHECK-NEXT: [[GEP1_OFFS:%.*]] = add nsw i64 [[GEP1_IDX]], [[I:%.*]]
1148+
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, ptr [[FOO:%.*]], i64 [[GEP1_OFFS]]
1149+
; CHECK-NEXT: [[GEPDIFF:%.*]] = add nsw i64 [[GEP1_OFFS]], -4200
11501150
; CHECK-NEXT: store ptr [[GEP1]], ptr @dummy_global1, align 8
1151-
; CHECK-NEXT: ret i64 [[SUB]]
1151+
; CHECK-NEXT: ret i64 [[GEPDIFF]]
11521152
;
11531153
; gep1 has a non-constant index and more than one uses. Shouldn't duplicate the arithmetic.
11541154
%gep1 = getelementptr inbounds [100 x [100 x i8]], ptr %foo, i64 0, i64 %j, i64 %i
@@ -1162,13 +1162,12 @@ define i64 @test60(ptr %foo, i64 %i, i64 %j) {
11621162

11631163
define i64 @test61(ptr %foo, i64 %i, i64 %j) {
11641164
; CHECK-LABEL: @test61(
1165-
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, ptr [[FOO:%.*]], i64 4200
1166-
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds [100 x [100 x i8]], ptr [[FOO]], i64 0, i64 [[J:%.*]], i64 [[I:%.*]]
1167-
; CHECK-NEXT: [[CAST1:%.*]] = ptrtoint ptr [[GEP1]] to i64
1168-
; CHECK-NEXT: [[CAST2:%.*]] = ptrtoint ptr [[GEP2]] to i64
1169-
; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[CAST1]], [[CAST2]]
1165+
; CHECK-NEXT: [[GEP2_IDX:%.*]] = mul nsw i64 [[J:%.*]], 100
1166+
; CHECK-NEXT: [[GEP2_OFFS:%.*]] = add nsw i64 [[GEP2_IDX]], [[I:%.*]]
1167+
; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i8, ptr [[FOO:%.*]], i64 [[GEP2_OFFS]]
1168+
; CHECK-NEXT: [[GEPDIFF:%.*]] = sub nsw i64 4200, [[GEP2_OFFS]]
11701169
; CHECK-NEXT: store ptr [[GEP2]], ptr @dummy_global2, align 8
1171-
; CHECK-NEXT: ret i64 [[SUB]]
1170+
; CHECK-NEXT: ret i64 [[GEPDIFF]]
11721171
;
11731172
; gep2 has a non-constant index and more than one uses. Shouldn't duplicate the arithmetic.
11741173
%gep1 = getelementptr inbounds [100 x [100 x i8]], ptr %foo, i64 0, i64 42, i64 0
@@ -1186,11 +1185,8 @@ define i64 @test_sub_ptradd_multiuse(ptr %p, i64 %idx1, i64 %idx2) {
11861185
; CHECK-LABEL: @test_sub_ptradd_multiuse(
11871186
; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i8, ptr [[P:%.*]], i64 [[IDX1:%.*]]
11881187
; CHECK-NEXT: call void @use.ptr(ptr [[P1]])
1189-
; CHECK-NEXT: [[P2:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 [[IDX2:%.*]]
1190-
; CHECK-NEXT: [[P1_INT:%.*]] = ptrtoint ptr [[P1]] to i64
1191-
; CHECK-NEXT: [[P2_INT:%.*]] = ptrtoint ptr [[P2]] to i64
1192-
; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[P1_INT]], [[P2_INT]]
1193-
; CHECK-NEXT: ret i64 [[SUB]]
1188+
; CHECK-NEXT: [[GEPDIFF:%.*]] = sub nsw i64 [[IDX1]], [[IDX2:%.*]]
1189+
; CHECK-NEXT: ret i64 [[GEPDIFF]]
11941190
;
11951191
%p1 = getelementptr inbounds i8, ptr %p, i64 %idx1
11961192
call void @use.ptr(ptr %p1)

0 commit comments

Comments
 (0)