@@ -225,6 +225,32 @@ Argument* CImagesBI::CImagesUtils::findImageFromBufferPtr(const MetaDataUtils &M
225
225
226
226
Value* CImagesBI::CImagesUtils::traceImageOrSamplerArgument (CallInst* pCallInst, unsigned int paramIndex, const MetaDataUtils *pMdUtils, const IGC::ModuleMetaData* modMD)
227
227
{
228
+ std::function<Value*(Value*)> track = [&track](Value *pVal) -> Value*
229
+ {
230
+ for (auto U : pVal->users ())
231
+ {
232
+ if (auto *GEP = dyn_cast<GetElementPtrInst>(U))
233
+ {
234
+ if (!GEP->hasAllZeroIndices ())
235
+ continue ;
236
+
237
+ if (auto *leaf = track (GEP))
238
+ return leaf;
239
+ }
240
+ else if (CastInst* inst = dyn_cast<CastInst>(U))
241
+ {
242
+ if (auto *leaf = track (inst))
243
+ return leaf;
244
+ }
245
+ else if (auto *ST = dyn_cast<StoreInst>(U))
246
+ {
247
+ return ST->getValueOperand ();
248
+ }
249
+ }
250
+
251
+ return nullptr ;
252
+ };
253
+
228
254
Value* baseValue = pCallInst->getOperand (paramIndex);
229
255
while (true )
230
256
{
@@ -366,32 +392,6 @@ Value* CImagesBI::CImagesUtils::traceImageOrSamplerArgument(CallInst* pCallInst,
366
392
pSamplerVal->getAggregateElement (0U ) : pSamplerVal;
367
393
}
368
394
369
- std::function<Value*(Value*)> track = [&track](Value *pVal) -> Value*
370
- {
371
- for (auto U : pVal->users ())
372
- {
373
- if (auto *GEP = dyn_cast<GetElementPtrInst>(U))
374
- {
375
- if (!GEP->hasAllZeroIndices ())
376
- continue ;
377
-
378
- if (auto *leaf = track (GEP))
379
- return leaf;
380
- }
381
- else if (CastInst* inst = dyn_cast<CastInst>(U))
382
- {
383
- if (auto *leaf = track (inst))
384
- return leaf;
385
- }
386
- else if (auto *ST = dyn_cast<StoreInst>(U))
387
- {
388
- return ST->getValueOperand ();
389
- }
390
- }
391
-
392
- return nullptr ;
393
- };
394
-
395
395
{
396
396
Value *pVal = addr->stripPointerCasts ();
397
397
// If, after stripping casts and zero GEPs, we make it to an
@@ -418,23 +418,20 @@ Value* CImagesBI::CImagesUtils::traceImageOrSamplerArgument(CallInst* pCallInst,
418
418
// want to redirect search to
419
419
// store %opencl.image1d_t addrspace(1)* %0, %opencl.image1d_t addrspace(1)** %5, align 8
420
420
// and continue existing search path
421
-
422
- if (CastInst* blockDescr = dyn_cast<CastInst>(getElementPtr->getOperand (0 )))
423
- {
424
- // %10 = bitcast <...>* %sbd0 to i8*
425
- if (CastInst* bcast = dyn_cast<CastInst>(blockDescr->getOperand (0 )))
426
- {
427
- // %sbd0 = alloca <...>, align 8
428
- if (AllocaInst* sblockDescr = dyn_cast<AllocaInst>(bcast->getOperand (0 )))
429
- {
430
- // use new addr to continue existing search path
431
- addr = sblockDescr;
432
- }
433
- }
434
- }
435
-
421
+ CastInst* blockDescr = nullptr ;
422
+ for (CastInst* ptr = dyn_cast<CastInst>(getElementPtr->getOperand (0 )); ptr; ptr = dyn_cast<CastInst>(ptr->getOperand (0 )))
423
+ blockDescr = ptr;
424
+ if (blockDescr && isa<AllocaInst>(blockDescr->getOperand (0 )))
425
+ addr = dyn_cast<AllocaInst>(blockDescr->getOperand (0 ));
436
426
index = dyn_cast<ConstantInt>(getElementPtr->getOperand (2 ));
437
427
}
428
+ else if (getElementPtr && getElementPtr->getNumIndices () > 1 )
429
+ {
430
+ Value *pVal = addr->stripPointerCasts ();
431
+ if (pVal && isa<AllocaInst>(pVal))
432
+ addr = pVal;
433
+ index = dyn_cast<ConstantInt>(getElementPtr->getOperand (2 ));
434
+ }
438
435
439
436
StoreInst* store = NULL ;
440
437
@@ -474,12 +471,59 @@ Value* CImagesBI::CImagesUtils::traceImageOrSamplerArgument(CallInst* pCallInst,
474
471
{
475
472
// dispatch kernel search
476
473
// first usege of proper getElementPtr is the store of input argument image
477
- user = *(user->user_begin ());
474
+ std::function<Value*(Value*)> trackStore = [&trackStore](Value *pVal) -> Value*
475
+ {
476
+ for (auto U : pVal->users ())
477
+ {
478
+ if (isa<StoreInst>(U)) return U;
479
+ if (Value *leaf = trackStore (U)) return leaf;
480
+ }
481
+ return nullptr ;
482
+ };
483
+
484
+ user = trackStore (user);
478
485
}
479
486
assert (isa<StoreInst>(user) && !store && " expected only one store instruction" );
480
487
store = cast<StoreInst>(user);
481
488
}
482
-
489
+
490
+ if (!store)
491
+ {
492
+ std::function<Value*(Value*)> track2 = [&track2](Value *pVal) -> Value*
493
+ {
494
+ for (auto U : pVal->users ())
495
+ {
496
+ if (CallInst *callInst = dyn_cast<CallInst>(U))
497
+ {
498
+ if (callInst->getCalledFunction ()->getIntrinsicID () == Intrinsic::ID::memcpy )
499
+ return callInst->getOperand (1 );
500
+ } else if (Value *leaf = track2 (U))
501
+ return leaf;
502
+ }
503
+ return nullptr ;
504
+ };
505
+
506
+ Value *tmpptr = nullptr ;
507
+ for (auto i = addr->user_begin (), e = addr->user_end (); !tmpptr && i != e; ++i)
508
+ {
509
+ Value* user = *i;
510
+ tmpptr = track2 (user);
511
+ }
512
+
513
+ if (tmpptr && isa<CastInst>(tmpptr))
514
+ {
515
+ Value *pVal = tmpptr->stripPointerCasts ();
516
+ if (pVal && isa<AllocaInst>(pVal))
517
+ {
518
+ auto *pArg = track (pVal);
519
+ if (pArg && (isa<Argument>(pArg) || isa<ConstantInt>(pArg)))
520
+ return pArg;
521
+ }
522
+ baseValue = tmpptr;
523
+ continue ;
524
+ }
525
+ }
526
+
483
527
assert (store && " expected one store instruction" );
484
528
// Update the baseValue and repeat the check.
485
529
baseValue = store->getValueOperand ();
0 commit comments