فهرست منبع

MultiDimArrayToOneDimArray: support multi-dim array of struct

- Required for native structure ptr used directly by certain intrinsics,
  such as DispatchMesh.
Tex Riddell 5 سال پیش
والد
کامیت
5e06769ac8
1فایلهای تغییر یافته به همراه13 افزوده شده و 1 حذف شده
  1. 13 1
      lib/Transforms/Scalar/LowerTypePasses.cpp

+ 13 - 1
lib/Transforms/Scalar/LowerTypePasses.cpp

@@ -522,19 +522,31 @@ void ReplaceMultiDimGEP(User *GEP, Value *OneDim, IRBuilder<> &Builder) {
   Value *ArrayIdx = GEPIt.getOperand();
   ++GEPIt;
   Value *VecIdx = nullptr;
+  SmallVector<Value*,8> StructIdxs;
   for (; GEPIt != E; ++GEPIt) {
     if (GEPIt->isArrayTy()) {
       unsigned arraySize = GEPIt->getArrayNumElements();
       Value *V = GEPIt.getOperand();
       ArrayIdx = Builder.CreateMul(ArrayIdx, Builder.getInt32(arraySize));
       ArrayIdx = Builder.CreateAdd(V, ArrayIdx);
+    } else if (isa<StructType>(*GEPIt)) {
+      // Replaces multi-dim array of struct, with single-dim array of struct
+      StructIdxs.push_back(PtrOffset);
+      StructIdxs.push_back(ArrayIdx);
+      while (GEPIt != E) {
+        StructIdxs.push_back(GEPIt.getOperand());
+        ++GEPIt;
+      }
+      break;
     } else {
       DXASSERT_NOMSG(isa<VectorType>(*GEPIt));
       VecIdx = GEPIt.getOperand();
     }
   }
   Value *NewGEP = nullptr;
-  if (!VecIdx)
+  if (StructIdxs.size())
+    NewGEP = Builder.CreateGEP(OneDim, StructIdxs);
+  else if (!VecIdx)
     NewGEP = Builder.CreateGEP(OneDim, {PtrOffset, ArrayIdx});
   else
     NewGEP = Builder.CreateGEP(OneDim, {PtrOffset, ArrayIdx, VecIdx});