Skip to content

Commit e13bed4

Browse files
d-smirnovLeporacanthicus
authored andcommitted
[PATCH] [llvm] [InstCombine] Canonicalise ADD+GEP
This patch tries to canonicalise add + gep to gep + gep. Co-authored-by: Paul Walker <[email protected]> Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D155688
1 parent a16f646 commit e13bed4

File tree

14 files changed

+266
-247
lines changed

14 files changed

+266
-247
lines changed

clang/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,9 @@ void* test9(B* x) { return dynamic_cast<void*>(x); }
9494
// CHECK-NEXT: [[VBTBL:%.*]] = load ptr, ptr [[VBPTR]], align 4
9595
// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, ptr [[VBTBL]], i32 1
9696
// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, ptr [[VBOFFP]], align 4
97-
// CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
98-
// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, ptr %x, i32 [[DELTA]]
99-
// CHECK-NEXT: [[CALL:%.*]] = tail call ptr @__RTCastToVoid(ptr nonnull [[ADJ]])
97+
// CHECK-NEXT: [[BASE:%.*]] = getelementptr i8, ptr %x, i32 [[VBOFFS]]
98+
// CHECK-NEXT: [[ADJ:%.*]] = getelementptr i8, ptr [[BASE]], i32 4
99+
// CHECK-NEXT: [[CALL:%.*]] = tail call ptr @__RTCastToVoid(ptr [[ADJ]])
100100
// CHECK-NEXT: br label
101101
// CHECK: [[RET:%.*]] = phi ptr
102102
// CHECK-NEXT: ret ptr [[RET]]

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2316,11 +2316,27 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
23162316
return CastInst::CreatePointerBitCastOrAddrSpaceCast(Y, GEPType);
23172317
}
23182318
}
2319-
23202319
// We do not handle pointer-vector geps here.
23212320
if (GEPType->isVectorTy())
23222321
return nullptr;
23232322

2323+
if (GEP.getNumIndices() == 1) {
2324+
// Try to replace ADD + GEP with GEP + GEP.
2325+
Value *Idx1, *Idx2;
2326+
if (match(GEP.getOperand(1),
2327+
m_OneUse(m_Add(m_Value(Idx1), m_Value(Idx2))))) {
2328+
// %idx = add i64 %idx1, %idx2
2329+
// %gep = getelementptr i32, i32* %ptr, i64 %idx
2330+
// as:
2331+
// %newptr = getelementptr i32, i32* %ptr, i64 %idx1
2332+
// %newgep = getelementptr i32, i32* %newptr, i64 %idx2
2333+
auto *NewPtr = Builder.CreateGEP(GEP.getResultElementType(),
2334+
GEP.getPointerOperand(), Idx1);
2335+
return GetElementPtrInst::Create(GEP.getResultElementType(), NewPtr,
2336+
Idx2);
2337+
}
2338+
}
2339+
23242340
if (!GEP.isInBounds()) {
23252341
unsigned IdxWidth =
23262342
DL.getIndexSizeInBits(PtrOp->getType()->getPointerAddressSpace());

llvm/test/CodeGen/Hexagon/autohvx/vector-align-tbaa.ll

Lines changed: 78 additions & 78 deletions
Large diffs are not rendered by default.

llvm/test/Transforms/InstCombine/align-addr.ll

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
33
target datalayout = "E-p:64:64:64-p1:32:32:32-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
44

5+
; Instcombine should be able to prove vector alignment in the
6+
; presence of a few mild address computation tricks.
7+
58
define void @test0(ptr %b, i64 %n, i64 %u, i64 %y) nounwind {
69
; CHECK-LABEL: @test0(
710
; CHECK-NEXT: entry:
@@ -15,8 +18,8 @@ define void @test0(ptr %b, i64 %n, i64 %u, i64 %y) nounwind {
1518
; CHECK: bb:
1619
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[INDVAR_NEXT:%.*]], [[BB]] ], [ 20, [[ENTRY:%.*]] ]
1720
; CHECK-NEXT: [[J:%.*]] = mul i64 [[I]], [[V]]
18-
; CHECK-NEXT: [[H:%.*]] = add i64 [[J]], [[Z]]
19-
; CHECK-NEXT: [[T8:%.*]] = getelementptr double, ptr [[E]], i64 [[H]]
21+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr double, ptr [[E]], i64 [[J]]
22+
; CHECK-NEXT: [[T8:%.*]] = getelementptr double, ptr [[TMP0]], i64 [[Z]]
2023
; CHECK-NEXT: store <2 x double> zeroinitializer, ptr [[T8]], align 8
2124
; CHECK-NEXT: [[INDVAR_NEXT]] = add i64 [[I]], 1
2225
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVAR_NEXT]], [[N]]

llvm/test/Transforms/InstCombine/mem-par-metadata-memcpy.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ define void @_Z4testPcl(ptr %out, i64 %size) {
2323
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
2424
; CHECK: for.body:
2525
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[OUT:%.*]], i64 [[I_0]]
26-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[I_0]], [[SIZE]]
27-
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[OUT]], i64 [[ADD]]
28-
; CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[ARRAYIDX1]], align 1, !llvm.access.group [[ACC_GRP0:![0-9]+]]
29-
; CHECK-NEXT: store i16 [[TMP0]], ptr [[ARRAYIDX]], align 1, !llvm.access.group [[ACC_GRP0]]
26+
; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[OUT]], i64 [[I_0]]
27+
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i8, ptr [[TMP0]], i64 [[SIZE]]
28+
; CHECK-NEXT: [[TMP1:%.*]] = load i16, ptr [[ARRAYIDX1]], align 1, !llvm.access.group [[ACC_GRP0:![0-9]+]]
29+
; CHECK-NEXT: store i16 [[TMP1]], ptr [[ARRAYIDX]], align 1, !llvm.access.group [[ACC_GRP0]]
3030
; CHECK-NEXT: br label [[FOR_INC]]
3131
; CHECK: for.inc:
3232
; CHECK-NEXT: [[ADD2]] = add nuw nsw i64 [[I_0]], 2

llvm/test/Transforms/InstCombine/memrchr-4.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ define ptr @fold_memrchr_a11111_c_n(i32 %C, i64 %N) {
3434
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[C:%.*]] to i8
3535
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], 1
3636
; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP1]], i1 [[TMP3]], i1 false
37-
; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[N]], -1
38-
; CHECK-NEXT: [[MEMRCHR_PTR_PLUS:%.*]] = getelementptr inbounds i8, ptr @a11111, i64 [[TMP5]]
37+
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr @a11111, i64 [[N]]
38+
; CHECK-NEXT: [[MEMRCHR_PTR_PLUS:%.*]] = getelementptr i8, ptr [[TMP5]], i64 -1
3939
; CHECK-NEXT: [[MEMRCHR_SEL:%.*]] = select i1 [[TMP4]], ptr [[MEMRCHR_PTR_PLUS]], ptr null
4040
; CHECK-NEXT: ret ptr [[MEMRCHR_SEL]]
4141
;

llvm/test/Transforms/InstCombine/shift.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,8 +1755,8 @@ define void @ashr_out_of_range_1(ptr %A) {
17551755
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i177 [[L_FROZEN]], -1
17561756
; CHECK-NEXT: [[B:%.*]] = select i1 [[TMP1]], i177 0, i177 [[L_FROZEN]]
17571757
; CHECK-NEXT: [[TMP2:%.*]] = trunc i177 [[B]] to i64
1758-
; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[TMP2]], -1
1759-
; CHECK-NEXT: [[G11:%.*]] = getelementptr i177, ptr [[A]], i64 [[TMP3]]
1758+
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr i177, ptr [[A]], i64 [[TMP2]]
1759+
; CHECK-NEXT: [[G11:%.*]] = getelementptr i177, ptr [[TMP3]], i64 -1
17601760
; CHECK-NEXT: [[C17:%.*]] = icmp sgt i177 [[B]], [[L_FROZEN]]
17611761
; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[C17]] to i64
17621762
; CHECK-NEXT: [[G62:%.*]] = getelementptr i177, ptr [[G11]], i64 [[TMP4]]

llvm/test/Transforms/LoopVectorize/AArch64/sve-interleaved-accesses.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,11 +1402,11 @@ define void @PR27626_5(i32 *%a, i32 %x, i32 %y, i32 %z, i64 %n) #1 {
14021402
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
14031403
; CHECK: for.body:
14041404
; CHECK-NEXT: [[I:%.*]] = phi i64 [ [[I_NEXT:%.*]], [[FOR_BODY]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
1405-
; CHECK-NEXT: [[I_MINUS_1:%.*]] = add i64 [[I]], -1
1406-
; CHECK-NEXT: [[I_MINUS_3:%.*]] = add i64 [[I]], -3
14071405
; CHECK-NEXT: [[A_I:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[I]]
1408-
; CHECK-NEXT: [[A_I_MINUS_1:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[I_MINUS_1]]
1409-
; CHECK-NEXT: [[A_I_MINUS_3:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[I_MINUS_3]]
1406+
; CHECK-NEXT: [[TMP19:%.*]] = getelementptr i32, ptr [[A]], i64 [[I]]
1407+
; CHECK-NEXT: [[A_I_MINUS_1:%.*]] = getelementptr i32, ptr [[TMP19]], i64 -1
1408+
; CHECK-NEXT: [[TMP20:%.*]] = getelementptr i32, ptr [[A]], i64 [[I]]
1409+
; CHECK-NEXT: [[A_I_MINUS_3:%.*]] = getelementptr i32, ptr [[TMP20]], i64 -3
14101410
; CHECK-NEXT: store i32 [[X]], ptr [[A_I_MINUS_1]], align 4
14111411
; CHECK-NEXT: store i32 [[Y]], ptr [[A_I_MINUS_3]], align 4
14121412
; CHECK-NEXT: store i32 [[Z]], ptr [[A_I]], align 4
@@ -1459,11 +1459,11 @@ define void @PR34743(i16* %a, i32* %b, i64 %n) #1 {
14591459
; CHECK: vector.memcheck:
14601460
; CHECK-NEXT: [[TMP4:%.*]] = shl i64 [[N]], 1
14611461
; CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], -4
1462-
; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[TMP5]], 4
1463-
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[B:%.*]], i64 [[TMP6]]
1462+
; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[B:%.*]], i64 [[TMP5]]
1463+
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[TMP6]], i64 4
14641464
; CHECK-NEXT: [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[A]], i64 2
1465-
; CHECK-NEXT: [[TMP7:%.*]] = add i64 [[TMP5]], 6
1466-
; CHECK-NEXT: [[SCEVGEP2:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP7]]
1465+
; CHECK-NEXT: [[TMP7:%.*]] = getelementptr i8, ptr [[A]], i64 [[TMP5]]
1466+
; CHECK-NEXT: [[SCEVGEP2:%.*]] = getelementptr i8, ptr [[TMP7]], i64 6
14671467
; CHECK-NEXT: [[BOUND0:%.*]] = icmp ugt ptr [[SCEVGEP2]], [[B]]
14681468
; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult ptr [[SCEVGEP1]], [[SCEVGEP]]
14691469
; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]

llvm/test/Transforms/LoopVectorize/AArch64/sve-widen-phi.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ define void @widen_ptr_phi_unrolled(ptr noalias nocapture %a, ptr noalias nocapt
3535
; CHECK-NEXT: [[TMP5:%.*]] = call i64 @llvm.vscale.i64()
3636
; CHECK-NEXT: [[TMP6:%.*]] = shl nuw nsw i64 [[TMP5]], 5
3737
; CHECK-NEXT: [[TMP7:%.*]] = shl i64 [[INDEX]], 3
38-
; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[TMP6]], [[TMP7]]
39-
; CHECK-NEXT: [[NEXT_GEP2:%.*]] = getelementptr i8, ptr [[C]], i64 [[TMP8]]
38+
; CHECK-NEXT: [[TMP8:%.*]] = getelementptr i8, ptr [[C]], i64 [[TMP6]]
39+
; CHECK-NEXT: [[NEXT_GEP2:%.*]] = getelementptr i8, ptr [[TMP8]], i64 [[TMP7]]
4040
; CHECK-NEXT: [[WIDE_VEC:%.*]] = load <vscale x 8 x i32>, ptr [[NEXT_GEP]], align 4
4141
; CHECK-NEXT: [[WIDE_VEC3:%.*]] = load <vscale x 8 x i32>, ptr [[NEXT_GEP2]], align 4
4242
; CHECK-NEXT: [[STRIDED_VEC:%.*]] = call { <vscale x 4 x i32>, <vscale x 4 x i32> } @llvm.experimental.vector.deinterleave2.nxv8i32(<vscale x 8 x i32> [[WIDE_VEC]])

0 commit comments

Comments
 (0)