[llvm] [SPIRV] Handle GEP on i8 with const offset in legalize ptr cast (PR #145045)
Steven Perron via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 20 07:55:30 PDT 2025
https://github.com/s-perron updated https://github.com/llvm/llvm-project/pull/145045
>From 5fc5cd402e24ee5cdda01958cce606dde2622c97 Mon Sep 17 00:00:00 2001
From: Steven Perron <stevenperron at google.com>
Date: Fri, 20 Jun 2025 10:53:09 -0400
Subject: [PATCH] [SPIRV] Handle GEP on i8 with const offset in legalize ptr
cast
---
.../Target/SPIRV/SPIRVLegalizePointerCast.cpp | 63 ++++++++++++++++++-
1 file changed, 60 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp
index 5cda6a07352d5..04734d9f493d8 100644
--- a/llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp
@@ -144,13 +144,69 @@ class SPIRVLegalizePointerCast : public FunctionPass {
// - float v = s.m;
else if (SST && SST->getTypeAtIndex(0u) == ToTy)
Output = loadFirstValueFromAggregate(B, ToTy, OriginalOperand, LI);
- else
+ else {
+ LI->dump();
llvm_unreachable("Unimplemented implicit down-cast from load.");
+ }
GR->replaceAllUsesWith(LI, Output, /* DeleteOld= */ true);
DeadInstructions.push_back(LI);
}
+ llvm::SmallVector<uint32_t>
+ getAccessChainIndiciesForOffset(Type *FromTy, uint32_t Offset,
+ const DataLayout &DL) {
+ llvm::SmallVector<uint32_t> Indices;
+ APInt O(32, Offset, true);
+
+ while (!O.isZero()) {
+ // TODO: getGEPIndexForOffset does not work for vector types. Need to do
+ // something.
+ auto R = DL.getGEPIndexForOffset(FromTy, O);
+ assert(R.has_value() && "Unable to build AC indices.");
+ Indices.push_back(R->getSExtValue());
+ }
+ return Indices;
+ }
+
+ void transformGEP(IRBuilder<> &B, IntrinsicInst *GEP, Value *CastedOperand,
+ Value *OriginalOperand) {
+ // Assumptions: If the offset for the GEP is not constant then it would not
+ // have changed the type for the GEP, and there should be no pointer cast.
+
+ assert(GEP->getNumOperands() == 4 &&
+ "Expecting operand to have been fold to a single operand");
+
+ Type *ToTy = GR->findDeducedElementType(CastedOperand);
+ assert(ToTy->isIntegerTy() && ToTy->getIntegerBitWidth() == 8);
+
+ llvm::Value *OffsetOperand = GEP->getOperand(2);
+ assert(isa<ConstantInt>(OffsetOperand) &&
+ "Expecing the offset in the operand to have been folded to a "
+ "constant operand.");
+
+ uint32_t Offset = cast<ConstantInt>(OffsetOperand)->getSExtValue();
+
+ Type *FromTy = GR->findDeducedElementType(OriginalOperand);
+ FromTy->dump();
+ llvm::dbgs() << "We have an offset of " << Offset << "\n";
+ const DataLayout &DL = GEP->getModule()->getDataLayout();
+
+ llvm::SmallVector<uint32_t> ACIndecies =
+ getAccessChainIndiciesForOffset(FromTy, Offset, DL);
+
+ llvm::dbgs() << "The ac indexes are:";
+ for (uint32_t Idx : ACIndecies) {
+ llvm::dbgs() << " " << Idx;
+ }
+
+ llvm::dbgs() << "\n";
+ llvm_unreachable("Need to build new access chain.");
+
+ // GR->replaceAllUsesWith(LI, Output, /* DeleteOld= */ true);
+ // DeadInstructions.push_back(LI);
+ }
+
// Creates an spv_insertelt instruction (equivalent to llvm's insertelement).
Value *makeInsertElement(IRBuilder<> &B, Value *Vector, Value *Element,
unsigned Index) {
@@ -297,8 +353,9 @@ class SPIRVLegalizePointerCast : public FunctionPass {
}
if (Intrin->getIntrinsicID() == Intrinsic::spv_gep) {
- GR->replaceAllUsesWith(CastedOperand, OriginalOperand,
- /* DeleteOld= */ false);
+ transformGEP(B, Intrin, CastedOperand, OriginalOperand);
+ // GR->replaceAllUsesWith(CastedOperand, OriginalOperand,
+ // /* DeleteOld= */ false);
continue;
}
More information about the llvm-commits
mailing list