Skip to content

Commit b10b428

Browse files
committed
[InstCombine] Canonicalize gep of ptradd
1 parent 1ab5329 commit b10b428

File tree

2 files changed

+53
-25
lines changed

2 files changed

+53
-25
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2317,6 +2317,43 @@ static Instruction *foldSelectGEP(GetElementPtrInst &GEP,
23172317
return SelectInst::Create(Cond, NewTrueC, NewFalseC, "", nullptr, Sel);
23182318
}
23192319

2320+
// Canonicalization:
2321+
// gep T, (gep i8, base, C1), (Index +nsw C2) into
2322+
// gep T, (gep i8, base, C1 + C2 * sizeof(T)), Index
2323+
static Instruction *canonicalizeGEPOfConstGEPI8(GetElementPtrInst &GEP,
2324+
GEPOperator *Src,
2325+
InstCombinerImpl &IC) {
2326+
if (GEP.getNumIndices() != 1)
2327+
return nullptr;
2328+
auto &DL = IC.getDataLayout();
2329+
Value *Base;
2330+
const APInt *C1;
2331+
if (!match(Src, m_PtrAdd(m_Value(Base), m_APInt(C1))))
2332+
return nullptr;
2333+
Value *VarIndex;
2334+
const APInt *C2;
2335+
Type *PtrTy = Src->getType()->getScalarType();
2336+
unsigned IndexSizeInBits = DL.getIndexTypeSizeInBits(PtrTy);
2337+
if (!match(GEP.getOperand(1), m_AddLike(m_Value(VarIndex), m_APInt(C2))))
2338+
return nullptr;
2339+
if (C1->getBitWidth() != IndexSizeInBits ||
2340+
C2->getBitWidth() != IndexSizeInBits)
2341+
return nullptr;
2342+
Type *BaseType = GEP.getSourceElementType();
2343+
if (isa<ScalableVectorType>(BaseType))
2344+
return nullptr;
2345+
APInt TypeSize(IndexSizeInBits, DL.getTypeAllocSize(BaseType));
2346+
APInt NewOffset = TypeSize * *C2 + *C1;
2347+
if (NewOffset.isZero() ||
2348+
(Src->hasOneUse() && GEP.getOperand(1)->hasOneUse())) {
2349+
Value *GEPConst = IC.Builder.CreateGEP(IC.Builder.getInt8Ty(), Base,
2350+
IC.Builder.getInt(NewOffset));
2351+
return GetElementPtrInst::Create(BaseType, GEPConst, VarIndex);
2352+
}
2353+
2354+
return nullptr;
2355+
}
2356+
23202357
Instruction *InstCombinerImpl::visitGEPOfGEP(GetElementPtrInst &GEP,
23212358
GEPOperator *Src) {
23222359
// Combine Indices - If the source pointer to this getelementptr instruction
@@ -2325,6 +2362,9 @@ Instruction *InstCombinerImpl::visitGEPOfGEP(GetElementPtrInst &GEP,
23252362
if (!shouldMergeGEPs(*cast<GEPOperator>(&GEP), *Src))
23262363
return nullptr;
23272364

2365+
if (auto *I = canonicalizeGEPOfConstGEPI8(GEP, Src, *this))
2366+
return I;
2367+
23282368
// For constant GEPs, use a more general offset-based folding approach.
23292369
Type *PtrTy = Src->getType()->getScalarType();
23302370
if (GEP.hasAllConstantIndices() &&

llvm/test/Transforms/InstCombine/gepofconstgepi8.ll

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ define ptr @test_zero(ptr %base, i64 %a) {
88
; CHECK-LABEL: define ptr @test_zero(
99
; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
1010
; CHECK-NEXT: entry:
11-
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -4
12-
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32, ptr [[P1]], i64 [[A]]
13-
; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[TMP0]], i64 4
11+
; CHECK-NEXT: [[P2:%.*]] = getelementptr i32, ptr [[BASE]], i64 [[A]]
1412
; CHECK-NEXT: ret ptr [[P2]]
1513
;
1614
entry:
@@ -24,10 +22,9 @@ define ptr @test_nonzero(ptr %base, i64 %a) {
2422
; CHECK-LABEL: define ptr @test_nonzero(
2523
; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
2624
; CHECK-NEXT: entry:
27-
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[BASE]], i64 -4
25+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[BASE]], i64 4
2826
; CHECK-NEXT: [[P2:%.*]] = getelementptr i32, ptr [[TMP0]], i64 [[A]]
29-
; CHECK-NEXT: [[P3:%.*]] = getelementptr i8, ptr [[P2]], i64 8
30-
; CHECK-NEXT: ret ptr [[P3]]
27+
; CHECK-NEXT: ret ptr [[P2]]
3128
;
3229
entry:
3330
%p1 = getelementptr i8, ptr %base, i64 -4
@@ -40,9 +37,7 @@ define ptr @test_or_disjoint(ptr %base, i64 %a) {
4037
; CHECK-LABEL: define ptr @test_or_disjoint(
4138
; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
4239
; CHECK-NEXT: entry:
43-
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -4
44-
; CHECK-NEXT: [[INDEX:%.*]] = or disjoint i64 [[A]], 1
45-
; CHECK-NEXT: [[P2:%.*]] = getelementptr i32, ptr [[P1]], i64 [[INDEX]]
40+
; CHECK-NEXT: [[P2:%.*]] = getelementptr i32, ptr [[BASE]], i64 [[A]]
4641
; CHECK-NEXT: ret ptr [[P2]]
4742
;
4843
entry:
@@ -56,10 +51,9 @@ define ptr @test_zero_multiuse_index(ptr %base, i64 %a) {
5651
; CHECK-LABEL: define ptr @test_zero_multiuse_index(
5752
; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
5853
; CHECK-NEXT: entry:
59-
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -4
6054
; CHECK-NEXT: [[INDEX:%.*]] = add i64 [[A]], 1
6155
; CHECK-NEXT: call void @use64(i64 [[INDEX]])
62-
; CHECK-NEXT: [[P2:%.*]] = getelementptr i32, ptr [[P1]], i64 [[INDEX]]
56+
; CHECK-NEXT: [[P2:%.*]] = getelementptr i32, ptr [[BASE]], i64 [[A]]
6357
; CHECK-NEXT: ret ptr [[P2]]
6458
;
6559
entry:
@@ -76,8 +70,7 @@ define ptr @test_zero_multiuse_ptr(ptr %base, i64 %a) {
7670
; CHECK-NEXT: entry:
7771
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -4
7872
; CHECK-NEXT: call void @useptr(ptr [[P1]])
79-
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32, ptr [[P1]], i64 [[A]]
80-
; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[TMP0]], i64 4
73+
; CHECK-NEXT: [[P2:%.*]] = getelementptr i32, ptr [[BASE]], i64 [[A]]
8174
; CHECK-NEXT: ret ptr [[P2]]
8275
;
8376
entry:
@@ -109,10 +102,8 @@ define ptr @test_zero_trunc_add(ptr %base, i128 %a) {
109102
; CHECK-LABEL: define ptr @test_zero_trunc_add(
110103
; CHECK-SAME: ptr [[BASE:%.*]], i128 [[A:%.*]]) {
111104
; CHECK-NEXT: entry:
112-
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -4
113105
; CHECK-NEXT: [[TMP0:%.*]] = trunc i128 [[A]] to i64
114-
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[P1]], i64 [[TMP0]]
115-
; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[TMP1]], i64 4
106+
; CHECK-NEXT: [[P2:%.*]] = getelementptr i32, ptr [[BASE]], i64 [[TMP0]]
116107
; CHECK-NEXT: ret ptr [[P2]]
117108
;
118109
entry:
@@ -126,10 +117,9 @@ define ptr @test_non_i8(ptr %base, i64 %a) {
126117
; CHECK-LABEL: define ptr @test_non_i8(
127118
; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
128119
; CHECK-NEXT: entry:
129-
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -8
120+
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -4
130121
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32, ptr [[P1]], i64 [[A]]
131-
; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[TMP0]], i64 4
132-
; CHECK-NEXT: ret ptr [[P2]]
122+
; CHECK-NEXT: ret ptr [[TMP0]]
133123
;
134124
entry:
135125
%p1 = getelementptr i16, ptr %base, i64 -4
@@ -223,10 +213,9 @@ define ptr @test_smul_overflow(ptr %base, i64 %a) {
223213
; CHECK-LABEL: define ptr @test_smul_overflow(
224214
; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
225215
; CHECK-NEXT: entry:
226-
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -4
216+
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -12
227217
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32, ptr [[P1]], i64 [[A]]
228-
; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[TMP0]], i64 -8
229-
; CHECK-NEXT: ret ptr [[P2]]
218+
; CHECK-NEXT: ret ptr [[TMP0]]
230219
;
231220
entry:
232221
%p1 = getelementptr i8, ptr %base, i64 -4
@@ -239,10 +228,9 @@ define ptr @test_sadd_overflow(ptr %base, i64 %a) {
239228
; CHECK-LABEL: define ptr @test_sadd_overflow(
240229
; CHECK-SAME: ptr [[BASE:%.*]], i64 [[A:%.*]]) {
241230
; CHECK-NEXT: entry:
242-
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 9223372036854775804
231+
; CHECK-NEXT: [[P1:%.*]] = getelementptr i8, ptr [[BASE]], i64 -9223372036854775808
243232
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i32, ptr [[P1]], i64 [[A]]
244-
; CHECK-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[TMP0]], i64 4
245-
; CHECK-NEXT: ret ptr [[P2]]
233+
; CHECK-NEXT: ret ptr [[TMP0]]
246234
;
247235
entry:
248236
%p1 = getelementptr i8, ptr %base, i64 9223372036854775804

0 commit comments

Comments
 (0)