[PATCH] D137664: [InstCombine][NFC] Baseline tests for D137212 Simplify chain of GEP with constant indices
William Junda Huang via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 8 12:29:49 PST 2022
huangjd created this revision.
huangjd added reviewers: davidxl, Carrot, nikic, spatel, reames.
Herald added a project: All.
huangjd requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
Baseline tests showing current optimizer can't simplify GEP (GEP (GEP p C1 <https://reviews.llvm.org/C1>) I1) C2 where C1 <https://reviews.llvm.org/C1> and C2 are constants
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D137664
Files:
llvm/test/Transforms/InstCombine/gep-merge-constant-indices.ll
Index: llvm/test/Transforms/InstCombine/gep-merge-constant-indices.ll
===================================================================
--- llvm/test/Transforms/InstCombine/gep-merge-constant-indices.ll
+++ llvm/test/Transforms/InstCombine/gep-merge-constant-indices.ll
@@ -9,6 +9,8 @@
%struct.B = type { i8, [3 x i16], %struct.A, float }
%struct.C = type { i8, i32, i32 }
+declare void @use(ptr %p)
+
; result = (i32*) p + 3
define ptr @mergeBasic(ptr %p) {
; CHECK-LABEL: @mergeBasic(
@@ -220,3 +222,77 @@
%2 = getelementptr inbounds i32, ptr %1, i64 1
ret ptr %2
}
+
+; If the first and last in a chain of GEP are constant indexed, they can be
+; merged, even if the first GEP has multiple uses.
+; result = (i8*) ((i32*) p + a + b) + 22
+define ptr @gepChain1(ptr %p, i64 %a, i64 %b) {
+; CHECK-LABEL: @gepChain1(
+; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i64, ptr [[P:%.*]], i64 2
+; CHECK-NEXT: call void @use(ptr nonnull [[TMP1]])
+; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 [[A:%.*]]
+; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i64 [[B:%.*]]
+; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i16, ptr [[TMP3]], i64 3
+; CHECK-NEXT: ret ptr [[TMP4]]
+;
+ %1 = getelementptr inbounds i64, ptr %p, i64 2
+ call void @use(ptr %1)
+ %2 = getelementptr inbounds i32, ptr %1, i64 %a
+ %3 = getelementptr inbounds i32, ptr %2, i64 %b
+ %4 = getelementptr inbounds i16, ptr %3, i64 3
+ ret ptr %4
+}
+
+; Constant indexed GEP cancel out.
+; result = (i32*) p + a + b
+define ptr @gepChain2(ptr %p, i64 %a, i64 %b) {
+; CHECK-LABEL: @gepChain2(
+; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i64, ptr [[P:%.*]], i64 2
+; CHECK-NEXT: call void @use(ptr nonnull [[TMP1]])
+; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 [[A:%.*]]
+; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i64 [[B:%.*]]
+; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i16, ptr [[TMP3]], i64 -8
+; CHECK-NEXT: ret ptr [[TMP4]]
+;
+ %1 = getelementptr inbounds i64, ptr %p, i64 2
+ call void @use(ptr %1)
+ %2 = getelementptr inbounds i32, ptr %1, i64 %a
+ %3 = getelementptr inbounds i32, ptr %2, i64 %b
+ %4 = getelementptr inbounds i16, ptr %3, i64 -8
+ ret ptr %4
+}
+
+; Negative test. If the last GEP offset is zero, do not merge since it is a
+; bitcast with no cost.
+define ptr @gepChainZeroOffset(ptr %p, i64 %a) {
+; CHECK-LABEL: @gepChainZeroOffset(
+; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i64, ptr [[P:%.*]], i64 2
+; CHECK-NEXT: call void @use(ptr nonnull [[TMP1]])
+; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 [[A:%.*]]
+; CHECK-NEXT: ret ptr [[TMP2]]
+;
+ %1 = getelementptr inbounds i64, ptr %p, i64 2
+ call void @use(ptr %1)
+ %2 = getelementptr inbounds i32, ptr %1, i64 %a
+ %3 = getelementptr inbounds [4 x i16], ptr %2, i64 1, i64 -4
+ ret ptr %3
+}
+
+; Negative test. Do not merge if a GEP in the middle has multiple use, such that
+; the transform is invalid.
+define ptr @gepChainMultipleUse(ptr %p, i64 %a) {
+; CHECK-LABEL: @gepChainMultipleUse(
+; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i64, ptr [[P:%.*]], i64 2
+; CHECK-NEXT: call void @use(ptr nonnull [[TMP1]])
+; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 [[A:%.*]]
+; CHECK-NEXT: call void @use(ptr nonnull [[TMP2]])
+; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i64 3
+; CHECK-NEXT: ret ptr [[TMP3]]
+;
+ %1 = getelementptr inbounds i64, ptr %p, i64 2
+ call void @use(ptr %1)
+ %2 = getelementptr inbounds i32, ptr %1, i64 %a
+ call void @use(ptr %2)
+ %3 = getelementptr inbounds i32, ptr %2, i64 3
+ ret ptr %3
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D137664.474069.patch
Type: text/x-patch
Size: 3823 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20221108/e919b77f/attachment.bin>
More information about the llvm-commits
mailing list