@@ -77,6 +77,7 @@ class DxilAnnotateWithVirtualRegister : public llvm::ModulePass {
7777private:
7878 void AnnotateValues (llvm::Instruction *pI);
7979 void AnnotateStore (llvm::Instruction *pI);
80+ void SplitVectorStores (hlsl::OP *HlslOP, llvm::Instruction *pI);
8081 bool IsAllocaRegisterWrite (llvm::Value *V, llvm::AllocaInst **pAI,
8182 llvm::Value **pIdx);
8283 void AnnotateAlloca (llvm::AllocaInst *pAlloca);
@@ -133,6 +134,15 @@ bool DxilAnnotateWithVirtualRegister::runOnModule(llvm::Module &M) {
133134 auto instrumentableFunctions =
134135 PIXPassHelpers::GetAllInstrumentableFunctions (*m_DM);
135136
137+ for (auto *F : instrumentableFunctions) {
138+ for (auto &block : F->getBasicBlockList ()) {
139+ for (auto it = block.begin (); it != block.end ();) {
140+ llvm::Instruction *I = &*(it++);
141+ SplitVectorStores (m_DM->GetOP (), I);
142+ }
143+ }
144+ }
145+
136146 for (auto *F : instrumentableFunctions) {
137147 for (auto &block : F->getBasicBlockList ()) {
138148 for (llvm::Instruction &I : block.getInstList ()) {
@@ -297,15 +307,37 @@ bool DxilAnnotateWithVirtualRegister::IsAllocaRegisterWrite(
297307 return false ;
298308 }
299309 // And of course the member we're after might not be at the beginning of
300- // the struct:
301- auto *pStructType = llvm::dyn_cast<llvm::StructType>(
302- pPointerGEP->getPointerOperandType ()->getPointerElementType ());
303- auto *pStructMember =
304- llvm::dyn_cast<llvm::ConstantInt>(pPointerGEP->getOperand (2 ));
305- uint64_t memberIndex = pStructMember->getLimitedValue ();
306- for (uint64_t i = 0 ; i < memberIndex; ++i) {
307- precedingMemberCount +=
308- CountStructMembers (pStructType->getStructElementType (i));
310+ // any containing struct:
311+ if (auto *pStructType = llvm::dyn_cast<llvm::StructType>(
312+ pPointerGEP->getPointerOperandType ()
313+ ->getPointerElementType ())) {
314+ auto *pStructMember =
315+ llvm::dyn_cast<llvm::ConstantInt>(pPointerGEP->getOperand (2 ));
316+ uint64_t memberIndex = pStructMember->getLimitedValue ();
317+ for (uint64_t i = 0 ; i < memberIndex; ++i) {
318+ precedingMemberCount +=
319+ CountStructMembers (pStructType->getStructElementType (i));
320+ }
321+ }
322+
323+ // And the source pointer may be a vector (floatn) type,
324+ // and if so, that's another offset to consider.
325+ llvm::Type *DestType = pGEP->getPointerOperand ()->getType ();
326+ // We expect this to be a pointer type (it's a GEP after all):
327+ if (DestType->isPointerTy ()) {
328+ llvm::Type *PointedType = DestType->getPointerElementType ();
329+ // Being careful to check num operands too in order to avoid false
330+ // positives:
331+ if (PointedType->isVectorTy () && pGEP->getNumOperands () == 3 ) {
332+ // Fetch the second deref (in operand 2).
333+ // (the first derefs the pointer to the "floatn",
334+ // and the second denotes the index into the floatn.)
335+ llvm::Value *vectorIndex = pGEP->getOperand (2 );
336+ if (auto *constIntIIndex =
337+ llvm::cast<llvm::ConstantInt>(vectorIndex)) {
338+ precedingMemberCount += constIntIIndex->getLimitedValue ();
339+ }
340+ }
309341 }
310342 } else {
311343 return false ;
@@ -365,6 +397,8 @@ void DxilAnnotateWithVirtualRegister::AnnotateAlloca(
365397 AssignNewAllocaRegister (pAlloca, 1 );
366398 } else if (auto *AT = llvm::dyn_cast<llvm::ArrayType>(pAllocaTy)) {
367399 AssignNewAllocaRegister (pAlloca, AT->getNumElements ());
400+ } else if (auto *VT = llvm::dyn_cast<llvm::VectorType>(pAllocaTy)) {
401+ AssignNewAllocaRegister (pAlloca, VT->getNumElements ());
368402 } else if (auto *ST = llvm::dyn_cast<llvm::StructType>(pAllocaTy)) {
369403 AssignNewAllocaRegister (pAlloca, CountStructMembers (ST));
370404 } else {
@@ -433,6 +467,36 @@ void DxilAnnotateWithVirtualRegister::AssignNewAllocaRegister(
433467 m_uVReg += C;
434468}
435469
470+ void DxilAnnotateWithVirtualRegister::SplitVectorStores (hlsl::OP *HlslOP,
471+ llvm::Instruction *pI) {
472+ auto *pSt = llvm::dyn_cast<llvm::StoreInst>(pI);
473+ if (pSt == nullptr ) {
474+ return ;
475+ }
476+
477+ llvm::AllocaInst *Alloca;
478+ llvm::Value *Index;
479+ if (!IsAllocaRegisterWrite (pSt->getPointerOperand (), &Alloca, &Index)) {
480+ return ;
481+ }
482+
483+ llvm::Type *SourceType = pSt->getValueOperand ()->getType ();
484+ if (SourceType->isVectorTy ()) {
485+ if (auto *constIntIIndex = llvm::cast<llvm::ConstantInt>(Index)) {
486+ // break vector alloca stores up into individual stores
487+ llvm::IRBuilder<> B (pSt);
488+ for (uint64_t el = 0 ; el < SourceType->getVectorNumElements (); ++el) {
489+ llvm::Value *destPointer = B.CreateGEP (pSt->getPointerOperand (),
490+ {B.getInt32 (0 ), B.getInt32 (el)});
491+ llvm::Value *source =
492+ B.CreateExtractElement (pSt->getValueOperand (), el);
493+ B.CreateStore (source, destPointer);
494+ }
495+ pI->eraseFromParent ();
496+ }
497+ }
498+ }
499+
436500} // namespace
437501
438502using namespace llvm ;
0 commit comments