@@ -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