@@ -359,11 +359,74 @@ bool SPIRVRegularizeLLVMBase::runRegularizeLLVM(Module &Module) {
359
359
return true ;
360
360
}
361
361
362
+ // This is a temporary workaround to deal with a graphics driver failure not
363
+ // able to support the typed pointer reverse translation of
364
+ // getelementptr i8, ptr @__spirv_Builtin* patterns. This replaces such
365
+ // accesses with getelementptr i32, ptr @__spirv_Builtin instead.
366
+ static void simplifyBuiltinVarAccesses (GlobalValue *GV) {
367
+ // IGC only supports:
368
+ // load GV
369
+ // load (addrspacecast GV)
370
+ // load (gep (addrspacecast GV))
371
+ // load (gep GV)
372
+ // Opaque pointers will cause the optimizer to use i8 geps, or to remove
373
+ // 0-index geps entirely (adding bitcasts to the result). Restore these to
374
+ // avoid bitcasts in the resulting IR.
375
+ if (GV->getContext ().supportsTypedPointers ())
376
+ return ;
377
+
378
+ Type *Ty = GV->getValueType ();
379
+ Type *ScalarTy = Ty->getScalarType ();
380
+ SmallVector<Value *, 4 > Users;
381
+ for (auto User : GV->users ()) {
382
+ if (auto *LI = dyn_cast<LoadInst>(User)) {
383
+ if (LI->getType () != Ty)
384
+ Users.push_back (LI);
385
+ } else if (auto *GEP = dyn_cast<GEPOperator>(User)) {
386
+ if (GEP->getSourceElementType () != Ty)
387
+ Users.push_back (GEP);
388
+ }
389
+ }
390
+
391
+ Type *Int32Ty = Type::getInt32Ty (GV->getContext ());
392
+ auto GetGep = [&](unsigned Offset) {
393
+ return ConstantExpr::getGetElementPtr (
394
+ Ty, GV,
395
+ ArrayRef<Constant *>(
396
+ {ConstantInt::get (Int32Ty, 0 ), ConstantInt::get (Int32Ty, Offset)}),
397
+ true , 0 );
398
+ };
399
+
400
+ const DataLayout &DL = GV->getParent ()->getDataLayout ();
401
+ for (auto *User : Users) {
402
+ if (auto *LI = dyn_cast<LoadInst>(User)) {
403
+ LI->setOperand (0 , GetGep (0 ));
404
+ } else if (auto *GEP = dyn_cast<GEPOperator>(User)) {
405
+ APInt Offset (64 , 0 );
406
+ GEP->accumulateConstantOffset (DL, Offset);
407
+ APInt Index;
408
+ uint64_t Remainder;
409
+ APInt::udivrem (Offset, ScalarTy->getScalarSizeInBits () / 8 , Index,
410
+ Remainder);
411
+ assert (Remainder == 0 && " Cannot handle misaligned access to builtins" );
412
+ GEP->replaceAllUsesWith (GetGep (Index.getZExtValue ()));
413
+ if (auto *Inst = dyn_cast<Instruction>(GEP))
414
+ Inst->eraseFromParent ();
415
+ }
416
+ }
417
+ }
418
+
362
419
// / Remove entities not representable by SPIR-V
363
420
bool SPIRVRegularizeLLVMBase::regularize () {
364
421
eraseUselessFunctions (M);
365
422
expandSYCLTypeUsing (M);
366
423
424
+ for (auto &GV : M->globals ()) {
425
+ SPIRVBuiltinVariableKind Kind;
426
+ if (isSPIRVBuiltinVariable (&GV, &Kind))
427
+ simplifyBuiltinVarAccesses (&GV);
428
+ }
429
+
367
430
for (auto I = M->begin (), E = M->end (); I != E;) {
368
431
Function *F = &(*I++);
369
432
if (F->isDeclaration () && F->use_empty ()) {
0 commit comments