Skip to content

Commit 5fc5cd4

Browse files
committed
[SPIRV] Handle GEP on i8 with const offset in legalize ptr cast
1 parent a4e4527 commit 5fc5cd4

File tree

1 file changed

+60
-3
lines changed

1 file changed

+60
-3
lines changed

llvm/lib/Target/SPIRV/SPIRVLegalizePointerCast.cpp

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,69 @@ class SPIRVLegalizePointerCast : public FunctionPass {
144144
// - float v = s.m;
145145
else if (SST && SST->getTypeAtIndex(0u) == ToTy)
146146
Output = loadFirstValueFromAggregate(B, ToTy, OriginalOperand, LI);
147-
else
147+
else {
148+
LI->dump();
148149
llvm_unreachable("Unimplemented implicit down-cast from load.");
150+
}
149151

150152
GR->replaceAllUsesWith(LI, Output, /* DeleteOld= */ true);
151153
DeadInstructions.push_back(LI);
152154
}
153155

156+
llvm::SmallVector<uint32_t>
157+
getAccessChainIndiciesForOffset(Type *FromTy, uint32_t Offset,
158+
const DataLayout &DL) {
159+
llvm::SmallVector<uint32_t> Indices;
160+
APInt O(32, Offset, true);
161+
162+
while (!O.isZero()) {
163+
// TODO: getGEPIndexForOffset does not work for vector types. Need to do
164+
// something.
165+
auto R = DL.getGEPIndexForOffset(FromTy, O);
166+
assert(R.has_value() && "Unable to build AC indices.");
167+
Indices.push_back(R->getSExtValue());
168+
}
169+
return Indices;
170+
}
171+
172+
void transformGEP(IRBuilder<> &B, IntrinsicInst *GEP, Value *CastedOperand,
173+
Value *OriginalOperand) {
174+
// Assumptions: If the offset for the GEP is not constant then it would not
175+
// have changed the type for the GEP, and there should be no pointer cast.
176+
177+
assert(GEP->getNumOperands() == 4 &&
178+
"Expecting operand to have been fold to a single operand");
179+
180+
Type *ToTy = GR->findDeducedElementType(CastedOperand);
181+
assert(ToTy->isIntegerTy() && ToTy->getIntegerBitWidth() == 8);
182+
183+
llvm::Value *OffsetOperand = GEP->getOperand(2);
184+
assert(isa<ConstantInt>(OffsetOperand) &&
185+
"Expecing the offset in the operand to have been folded to a "
186+
"constant operand.");
187+
188+
uint32_t Offset = cast<ConstantInt>(OffsetOperand)->getSExtValue();
189+
190+
Type *FromTy = GR->findDeducedElementType(OriginalOperand);
191+
FromTy->dump();
192+
llvm::dbgs() << "We have an offset of " << Offset << "\n";
193+
const DataLayout &DL = GEP->getModule()->getDataLayout();
194+
195+
llvm::SmallVector<uint32_t> ACIndecies =
196+
getAccessChainIndiciesForOffset(FromTy, Offset, DL);
197+
198+
llvm::dbgs() << "The ac indexes are:";
199+
for (uint32_t Idx : ACIndecies) {
200+
llvm::dbgs() << " " << Idx;
201+
}
202+
203+
llvm::dbgs() << "\n";
204+
llvm_unreachable("Need to build new access chain.");
205+
206+
// GR->replaceAllUsesWith(LI, Output, /* DeleteOld= */ true);
207+
// DeadInstructions.push_back(LI);
208+
}
209+
154210
// Creates an spv_insertelt instruction (equivalent to llvm's insertelement).
155211
Value *makeInsertElement(IRBuilder<> &B, Value *Vector, Value *Element,
156212
unsigned Index) {
@@ -297,8 +353,9 @@ class SPIRVLegalizePointerCast : public FunctionPass {
297353
}
298354

299355
if (Intrin->getIntrinsicID() == Intrinsic::spv_gep) {
300-
GR->replaceAllUsesWith(CastedOperand, OriginalOperand,
301-
/* DeleteOld= */ false);
356+
transformGEP(B, Intrin, CastedOperand, OriginalOperand);
357+
// GR->replaceAllUsesWith(CastedOperand, OriginalOperand,
358+
// /* DeleteOld= */ false);
302359
continue;
303360
}
304361

0 commit comments

Comments
 (0)