@@ -225,6 +225,32 @@ Argument* CImagesBI::CImagesUtils::findImageFromBufferPtr(const MetaDataUtils &M
225225
226226Value* CImagesBI::CImagesUtils::traceImageOrSamplerArgument (CallInst* pCallInst, unsigned int paramIndex, const MetaDataUtils *pMdUtils, const IGC::ModuleMetaData* modMD)
227227{
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+
228254 Value* baseValue = pCallInst->getOperand (paramIndex);
229255 while (true )
230256 {
@@ -366,32 +392,6 @@ Value* CImagesBI::CImagesUtils::traceImageOrSamplerArgument(CallInst* pCallInst,
366392 pSamplerVal->getAggregateElement (0U ) : pSamplerVal;
367393 }
368394
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-
395395 {
396396 Value *pVal = addr->stripPointerCasts ();
397397 // If, after stripping casts and zero GEPs, we make it to an
@@ -418,23 +418,20 @@ Value* CImagesBI::CImagesUtils::traceImageOrSamplerArgument(CallInst* pCallInst,
418418 // want to redirect search to
419419 // store %opencl.image1d_t addrspace(1)* %0, %opencl.image1d_t addrspace(1)** %5, align 8
420420 // 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 ));
436426 index = dyn_cast<ConstantInt>(getElementPtr->getOperand (2 ));
437427 }
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+ }
438435
439436 StoreInst* store = NULL ;
440437
@@ -474,12 +471,59 @@ Value* CImagesBI::CImagesUtils::traceImageOrSamplerArgument(CallInst* pCallInst,
474471 {
475472 // dispatch kernel search
476473 // 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);
478485 }
479486 assert (isa<StoreInst>(user) && !store && " expected only one store instruction" );
480487 store = cast<StoreInst>(user);
481488 }
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+
483527 assert (store && " expected one store instruction" );
484528 // Update the baseValue and repeat the check.
485529 baseValue = store->getValueOperand ();
0 commit comments