[PATCH] D138637: [InstCombine] Combine opaque pointer single index GEP and with src GEP which has result of array type
krishna chaitanya sankisa via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 23 21:39:00 PST 2022
skc7 created this revision.
skc7 added reviewers: nikic, ABataev.
Herald added subscribers: arphaman, hiraditya.
Herald added a project: All.
skc7 requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
Removing zero indices opaque pointer gep, link <https://reviews.llvm.org/rG87a0b1bd233a3680c32a6e17acf147d0fe90c9e9>, has caused Instcombine pass to not combine few GepOfGep instructions which were previously possible for non-opaque pointers case.
Consider below IR : link <https://llvm.godbolt.org/z/ec6aTxdo5>
@ext = external hidden global [2 x [1 x float]]
%a = getelementptr inbounds [2 x [1 x float]], [2 x [1 x float]]* @ext, i64 0, i64 %c
%b = getelementptr inbounds [1 x float], [1 x float]* %a, i64 0, i64 0
%c = getelementptr inbounds float, float* %b, i64 %in1
would be optimized to
%c = getelementptr inbounds [2 x [1 x float]], [2 x [1 x float]]* @ext, i64 0, i64 %c, i64 %in1
This is currently not happening for opaque pointer case. link <https://llvm.godbolt.org/z/GMWbsvGoE>
This patch tries to address this issue by combining single index gep with src gep of array type.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D138637
Files:
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
llvm/test/Transforms/InstCombine/opaque-ptr-gep-of-gep.ll
Index: llvm/test/Transforms/InstCombine/opaque-ptr-gep-of-gep.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/InstCombine/opaque-ptr-gep-of-gep.ll
@@ -0,0 +1,55 @@
+; RUN: opt -S -instcombine -opaque-pointers < %s | FileCheck %s
+
+ at ext1 = external hidden global [2 x [1 x float]]
+ at ext2 = external hidden global [2 x [2 x [1 x float]]]
+
+define void @gepofgep1(i64 %in1, i64 %in2, ptr %out) {
+; CHECK-LABEL: @gepofgep1(
+; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds [2 x [1 x float]], ptr [[EXT1:@.*]], i64 0, i64 [[IN1:%.*]], i64 [[IN2:%.*]]
+; CHECK-NEXT: store ptr [[B]], ptr [[OUT:%.*]], align 8
+; CHECK-NEXT: ret void
+
+ %a = getelementptr inbounds [2 x [1 x float]], ptr @ext1, i64 0, i64 %in1
+ %b = getelementptr inbounds float, ptr %a, i64 %in2
+ store ptr %b, ptr %out
+ ret void
+}
+
+define void @gepofgep2(i64 %in1, i64 %in2, ptr %out) {
+; CHECK-LABEL: @gepofgep2(
+; CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [2 x [2 x [1 x float]]], ptr [[EXT2:@.*]], i64 0, i64 [[IN1:%.*]]
+; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds [1 x float], ptr [[A]], i64 0, i64 [[IN2:%.*]]
+; CHECK-NEXT: store ptr [[B]], ptr [[OUT:%.*]], align 8
+; CHECK-NEXT: ret void
+ %a = getelementptr inbounds [2 x [2 x [1 x float]]], ptr @ext2, i64 0, i64 %in1
+ %b = getelementptr inbounds [1 x float], ptr %a, i64 0, i64 %in2
+ store ptr %b, ptr %out
+ ret void
+}
+
+define void @gepofgep3(i64 %in1, i64 %in2, ptr %out) {
+; CHECK-LABEL: @gepofgep3(
+; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds [2 x [2 x [1 x float]]], ptr [[EXT2:@.*]], i64 [[IN1:%.*]], i64 [[IN2:%.*]]
+; CHECK-NEXT: store ptr [[B]], ptr [[OUT:%.*]], align 8
+; CHECK-NEXT: ret void
+ %a = getelementptr inbounds [2 x [2 x [1 x float]]], ptr @ext2, i64 %in1
+ %b = getelementptr inbounds float, ptr %a, i64 %in2
+ store ptr %b, ptr %out
+ ret void
+}
+
+define void @gepofgep4(i64 %in1, i64 %in2, ptr %out1, ptr %out2) {
+; CHECK-LABEL: @gepofgep4(
+; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds [2 x [1 x float]], ptr [[EXT1:@.*]], i64 0, i64 [[IN1:%.*]], i64 [[IN1]]
+; CHECK-NEXT: [[C:%.*]] = getelementptr inbounds [2 x [1 x float]], ptr [[EXT1:@.*]], i64 0, i64 [[IN1]], i64 [[IN2:%.*]]
+; CHECK-NEXT: store ptr [[B]], ptr [[OUT1:%.*]], align 8
+; CHECK-NEXT: store ptr [[C]], ptr [[OUT2:%.*]], align 8
+; CHECK-NEXT: ret void
+
+ %a = getelementptr inbounds [2 x [1 x float]], ptr @ext1, i64 0, i64 %in1
+ %b = getelementptr inbounds float, ptr %a, i64 %in1
+ %c = getelementptr inbounds float, ptr %a, i64 %in2
+ store ptr %b, ptr %out1
+ store ptr %c, ptr %out2
+ ret void
+}
Index: llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2109,6 +2109,24 @@
GEP.getName());
}
+ // Combine opaque pointer GEPs having source array type with
+ // GEP having single index.
+ if (PtrTy->isOpaquePointerTy() && Src->getResultElementType()->isArrayTy() &&
+ GEP.getNumIndices() == 1) {
+ SmallVector<Value *, 16> NewIndices;
+ NewIndices.reserve(Src->getNumIndices() + GEP.getNumIndices());
+ NewIndices.append(Src->idx_begin(), Src->idx_end());
+ NewIndices.append(GEP.idx_begin(), GEP.idx_end());
+ bool IsInBounds = isMergedGEPInBounds(*Src, *cast<GEPOperator>(&GEP));
+ return IsInBounds
+ ? GetElementPtrInst::CreateInBounds(Src->getSourceElementType(),
+ Src->getOperand(0),
+ NewIndices, GEP.getName())
+ : GetElementPtrInst::Create(Src->getSourceElementType(),
+ Src->getOperand(0), NewIndices,
+ GEP.getName());
+ }
+
if (Src->getResultElementType() != GEP.getSourceElementType())
return nullptr;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D138637.477681.patch
Type: text/x-patch
Size: 4093 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20221124/4ca8a470/attachment.bin>
More information about the llvm-commits
mailing list