[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