Quellcode durchsuchen

[spirv] Emit single store for cross-storage-class composite types (#1158)

Previously we emit a store for each sub-element, which is not
friendly to SPIR-V transformations. This commit converted that
into first constructing a temporary value of the target storage
class, and the store once.
Lei Zhang vor 7 Jahren
Ursprung
Commit
4cfcdf3239

+ 69 - 49
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -4657,31 +4657,8 @@ void SPIRVEmitter::storeValue(const SpirvEvalInfo &lhsPtr,
                               const SpirvEvalInfo &rhsVal,
                               const SpirvEvalInfo &rhsVal,
                               const QualType lhsValType) {
                               const QualType lhsValType) {
 
 
-  // Lambda for cases where we want to store per each array element.
-  const auto storeValueForEachArrayElement = [this, &lhsPtr,
-                                              &rhsVal](uint32_t arraySize,
-                                                       QualType arrayElemType) {
-    for (uint32_t i = 0; i < arraySize; ++i) {
-      const auto subRhsValType =
-          typeTranslator.translateType(arrayElemType, rhsVal.getLayoutRule());
-      const auto subRhsVal =
-          theBuilder.createCompositeExtract(subRhsValType, rhsVal, {i});
-      const auto subLhsPtrType = theBuilder.getPointerType(
-          typeTranslator.translateType(arrayElemType, lhsPtr.getLayoutRule()),
-          lhsPtr.getStorageClass());
-      const auto subLhsPtr = theBuilder.createAccessChain(
-          subLhsPtrType, lhsPtr, {theBuilder.getConstantUint32(i)});
-
-      storeValue(lhsPtr.substResultId(subLhsPtr),
-                 rhsVal.substResultId(subRhsVal), arrayElemType);
-    }
-  };
-
   QualType matElemType = {};
   QualType matElemType = {};
-  QualType elemType = {};
-  uint32_t numRows = 0, numCols = 0;
-  const bool lhsIsMat =
-      typeTranslator.isMxNMatrix(lhsValType, &matElemType, &numRows, &numCols);
+  const bool lhsIsMat = typeTranslator.isMxNMatrix(lhsValType, &matElemType);
   const bool lhsIsFloatMat = lhsIsMat && matElemType->isFloatingType();
   const bool lhsIsFloatMat = lhsIsMat && matElemType->isFloatingType();
   const bool lhsIsNonFpMat = lhsIsMat && !matElemType->isFloatingType();
   const bool lhsIsNonFpMat = lhsIsMat && !matElemType->isFloatingType();
 
 
@@ -4743,40 +4720,83 @@ void SPIRVEmitter::storeValue(const SpirvEvalInfo &lhsPtr,
     // Note: this check should happen after those setting needsLegalization.
     // Note: this check should happen after those setting needsLegalization.
     // TODO: is this optimization always correct?
     // TODO: is this optimization always correct?
     theBuilder.createStore(lhsPtr, rhsVal);
     theBuilder.createStore(lhsPtr, rhsVal);
-  } else if (lhsIsNonFpMat) {
+  } else if (lhsValType->isRecordType() || lhsValType->isConstantArrayType() ||
+             lhsIsNonFpMat) {
+    theBuilder.createStore(
+        lhsPtr, reconstructValue(rhsVal, lhsValType, lhsPtr.getLayoutRule()));
+  } else {
+    emitError("storing value of type %0 unimplemented", {}) << lhsValType;
+  }
+}
+
+uint32_t SPIRVEmitter::reconstructValue(const SpirvEvalInfo &srcVal,
+                                        const QualType valType,
+                                        LayoutRule dstLR) {
+  // Lambda for cases where we want to reconstruct an array
+  const auto reconstructArray = [this, &srcVal, valType,
+                                 dstLR](uint32_t arraySize,
+                                        QualType arrayElemType) {
+    llvm::SmallVector<uint32_t, 4> elements;
+    for (uint32_t i = 0; i < arraySize; ++i) {
+      const auto subSrcValType =
+          typeTranslator.translateType(arrayElemType, srcVal.getLayoutRule());
+      const auto subSrcVal =
+          theBuilder.createCompositeExtract(subSrcValType, srcVal, {i});
+
+      elements.push_back(reconstructValue(srcVal.substResultId(subSrcVal),
+                                          arrayElemType, dstLR));
+    }
+    const auto dstValType = typeTranslator.translateType(valType, dstLR);
+    return theBuilder.createCompositeConstruct(dstValType, elements);
+  };
+
+  // Constant arrays
+  if (const auto *arrayType = astContext.getAsConstantArrayType(valType)) {
+    const auto elemType = arrayType->getElementType();
+    const auto size =
+        static_cast<uint32_t>(arrayType->getSize().getZExtValue());
+    return reconstructArray(size, elemType);
+  }
+
+  // Non-floating-point matrices
+  QualType matElemType = {};
+  uint32_t numRows = 0, numCols = 0;
+  const bool isNonFpMat =
+      typeTranslator.isMxNMatrix(valType, &matElemType, &numRows, &numCols) &&
+      !matElemType->isFloatingType();
+
+  if (isNonFpMat) {
     // Note: This check should happen before the RecordType check.
     // Note: This check should happen before the RecordType check.
     // Non-fp matrices are represented as arrays of vectors in SPIR-V.
     // Non-fp matrices are represented as arrays of vectors in SPIR-V.
     // Each array element is a vector. Get the QualType for the vector.
     // Each array element is a vector. Get the QualType for the vector.
     const auto elemType = astContext.getExtVectorType(matElemType, numCols);
     const auto elemType = astContext.getExtVectorType(matElemType, numCols);
-    storeValueForEachArrayElement(numRows, elemType);
-  } else if (const auto *recordType = lhsValType->getAs<RecordType>()) {
+    return reconstructArray(numRows, elemType);
+  }
+
+  // Note: This check should happen before the RecordType check since
+  // vector/matrix/resource types are represented as RecordType in the AST.
+  if (hlsl::IsHLSLVecMatType(valType) || hlsl::IsHLSLResourceType(valType))
+    return srcVal;
+
+  // Structs
+  if (const auto *recordType = valType->getAs<RecordType>()) {
     uint32_t index = 0;
     uint32_t index = 0;
+    llvm::SmallVector<uint32_t, 4> elements;
     for (const auto *field : recordType->getDecl()->fields()) {
     for (const auto *field : recordType->getDecl()->fields()) {
-      const auto subRhsValType = typeTranslator.translateType(
-          field->getType(), rhsVal.getLayoutRule());
-      const auto subRhsVal =
-          theBuilder.createCompositeExtract(subRhsValType, rhsVal, {index});
-      const auto subLhsPtrType = theBuilder.getPointerType(
-          typeTranslator.translateType(field->getType(),
-                                       lhsPtr.getLayoutRule()),
-          lhsPtr.getStorageClass());
-      const auto subLhsPtr = theBuilder.createAccessChain(
-          subLhsPtrType, lhsPtr, {theBuilder.getConstantUint32(index)});
-
-      storeValue(lhsPtr.substResultId(subLhsPtr),
-                 rhsVal.substResultId(subRhsVal), field->getType());
+      const auto subSrcValType = typeTranslator.translateType(
+          field->getType(), srcVal.getLayoutRule());
+      const auto subSrcVal =
+          theBuilder.createCompositeExtract(subSrcValType, srcVal, {index});
+
+      elements.push_back(reconstructValue(srcVal.substResultId(subSrcVal),
+                                          field->getType(), dstLR));
       ++index;
       ++index;
     }
     }
-  } else if (const auto *arrayType =
-                 astContext.getAsConstantArrayType(lhsValType)) {
-    const auto elemType = arrayType->getElementType();
-    // TODO: handle extra large array size?
-    const auto size =
-        static_cast<uint32_t>(arrayType->getSize().getZExtValue());
-    storeValueForEachArrayElement(size, elemType);
-  } else {
-    emitError("storing value of type %0 unimplemented", {}) << lhsValType;
+    const auto dstValType = typeTranslator.translateType(valType, dstLR);
+    return theBuilder.createCompositeConstruct(dstValType, elements);
   }
   }
+
+  return srcVal;
 }
 }
 
 
 SpirvEvalInfo SPIRVEmitter::processBinaryOp(const Expr *lhs, const Expr *rhs,
 SpirvEvalInfo SPIRVEmitter::processBinaryOp(const Expr *lhs, const Expr *rhs,

+ 5 - 0
tools/clang/lib/SPIRV/SPIRVEmitter.h

@@ -149,6 +149,11 @@ private:
   void storeValue(const SpirvEvalInfo &lhsPtr, const SpirvEvalInfo &rhsVal,
   void storeValue(const SpirvEvalInfo &lhsPtr, const SpirvEvalInfo &rhsVal,
                   QualType lhsValType);
                   QualType lhsValType);
 
 
+  /// Decomposes and reconstructs the given srcVal of the given valType to meet
+  /// the requirements of the dstLR layout rule.
+  uint32_t reconstructValue(const SpirvEvalInfo &srcVal, QualType valType,
+                            LayoutRule dstLR);
+
   /// Generates the necessary instructions for conducting the given binary
   /// Generates the necessary instructions for conducting the given binary
   /// operation on lhs and rhs.
   /// operation on lhs and rhs.
   ///
   ///

+ 35 - 50
tools/clang/test/CodeGenSPIRV/binary-op.assign.composite.hlsl

@@ -31,71 +31,56 @@ void main(uint index: A) {
 // CHECK-NEXT: [[lbuf:%\d+]] = OpLoad %BufferType_0 %lbuf
 // CHECK-NEXT: [[lbuf:%\d+]] = OpLoad %BufferType_0 %lbuf
 // CHECK-NEXT: [[sbuf5:%\d+]] = OpAccessChain %_ptr_Uniform_BufferType %sbuf %int_0 %uint_5
 // CHECK-NEXT: [[sbuf5:%\d+]] = OpAccessChain %_ptr_Uniform_BufferType %sbuf %int_0 %uint_5
 
 
-    // sbuf[5].a <- lbuf.a
-// CHECK-NEXT: [[val:%\d+]] = OpCompositeExtract %float [[lbuf]] 0
-// CHECK-NEXT: [[ptr:%\d+]] = OpAccessChain %_ptr_Uniform_float [[sbuf5]] %uint_0
-// CHECK-NEXT: OpStore [[ptr]] [[val]]
-
-    // sbuf[5].b <- lbuf.b
-// CHECK-NEXT: [[val:%\d+]] = OpCompositeExtract %v3float [[lbuf]] 1
-// CHECK-NEXT: [[ptr:%\d+]] = OpAccessChain %_ptr_Uniform_v3float [[sbuf5]] %uint_1
-// CHECK-NEXT: OpStore [[ptr]] [[val]]
-
-    // sbuf[5].c <- lbuf.c
-// CHECK-NEXT: [[val:%\d+]] = OpCompositeExtract %mat3v2float [[lbuf]] 2
-// CHECK-NEXT: [[ptr:%\d+]] = OpAccessChain %_ptr_Uniform_mat3v2float [[sbuf5]] %uint_2
-// CHECK-NEXT: OpStore [[ptr]] [[val]]
-
-// CHECK-NEXT: [[lbuf_d:%\d+]] = OpCompositeExtract %_arr_SubBuffer_1_uint_1 [[lbuf]] 3
-// CHECK-NEXT: [[sbuf_d:%\d+]] = OpAccessChain %_ptr_Uniform__arr_SubBuffer_uint_1 [[sbuf5]] %uint_3
-// CHECK-NEXT: [[lbuf_d0:%\d+]] = OpCompositeExtract %SubBuffer_1 [[lbuf_d]] 0
-// CHECK-NEXT: [[sbuf_d0:%\d+]] = OpAccessChain %_ptr_Uniform_SubBuffer [[sbuf_d]] %uint_0
-
-    // sbuf[5].d[0].a[0] <- lbuf.a[0]
-// CHECK-NEXT: [[lbuf_d0_a:%\d+]] = OpCompositeExtract %_arr_float_uint_1_1 [[lbuf_d0]] 0
-// CHECK-NEXT: [[sbuf_d0_a:%\d+]] = OpAccessChain %_ptr_Uniform__arr_float_uint_1 [[sbuf_d0]] %uint_0
+// CHECK-NEXT:     [[lbuf_a:%\d+]] = OpCompositeExtract %float [[lbuf]] 0
+// CHECK-NEXT:     [[lbuf_b:%\d+]] = OpCompositeExtract %v3float [[lbuf]] 1
+// CHECK-NEXT:     [[lbuf_c:%\d+]] = OpCompositeExtract %mat3v2float [[lbuf]] 2
+
+    // Get lbuf.d[0]
+// CHECK-NEXT:     [[lbuf_d:%\d+]] = OpCompositeExtract %_arr_SubBuffer_1_uint_1 [[lbuf]] 3
+// CHECK-NEXT:    [[lbuf_d0:%\d+]] = OpCompositeExtract %SubBuffer_1 [[lbuf_d]] 0
+
+    // Reconstruct lbuf.d[0].a
+// CHECK-NEXT:  [[lbuf_d0_a:%\d+]] = OpCompositeExtract %_arr_float_uint_1_1 [[lbuf_d0]] 0
 // CHECK-NEXT: [[lbuf_d0_a0:%\d+]] = OpCompositeExtract %float [[lbuf_d0_a]] 0
 // CHECK-NEXT: [[lbuf_d0_a0:%\d+]] = OpCompositeExtract %float [[lbuf_d0_a]] 0
-// CHECK-NEXT: [[sbuf_d0_a0:%\d+]] = OpAccessChain %_ptr_Uniform_float [[sbuf_d0_a]] %uint_0
-// CHECK-NEXT: OpStore [[sbuf_d0_a0]] [[lbuf_d0_a0]]
+// CHECK-NEXT:  [[sbuf_d0_a:%\d+]] = OpCompositeConstruct %_arr_float_uint_1 [[lbuf_d0_a0]]
 
 
-    // sbuf[5].d[0].b[0] <- lbuf.b[0]
-// CHECK-NEXT: [[lbuf_d0_b:%\d+]] = OpCompositeExtract %_arr_v2float_uint_1_1 [[lbuf_d0]] 1
-// CHECK-NEXT: [[sbuf_d0_b:%\d+]] = OpAccessChain %_ptr_Uniform__arr_v2float_uint_1 [[sbuf_d0]] %uint_1
+    // Reconstruct lbuf.d[0].b
+// CHECK-NEXT:  [[lbuf_d0_b:%\d+]] = OpCompositeExtract %_arr_v2float_uint_1_1 [[lbuf_d0]] 1
 // CHECK-NEXT: [[lbuf_d0_b0:%\d+]] = OpCompositeExtract %v2float [[lbuf_d0_b]] 0
 // CHECK-NEXT: [[lbuf_d0_b0:%\d+]] = OpCompositeExtract %v2float [[lbuf_d0_b]] 0
-// CHECK-NEXT: [[sbuf_d0_b0:%\d+]] = OpAccessChain %_ptr_Uniform_v2float [[sbuf_d0_b]] %uint_0
-// CHECK-NEXT: OpStore [[sbuf_d0_b0]] [[lbuf_d0_b0]]
+// CHECK-NEXT:  [[sbuf_d0_b:%\d+]] = OpCompositeConstruct %_arr_v2float_uint_1 [[lbuf_d0_b0]]
 
 
-    // sbuf[5].d[0].c[0] <- lbuf.c[0]
-// CHECK-NEXT: [[lbuf_d0_c:%\d+]] = OpCompositeExtract %_arr_mat2v3float_uint_1_1 [[lbuf_d0]] 2
-// CHECK-NEXT: [[sbuf_d0_c:%\d+]] = OpAccessChain %_ptr_Uniform__arr_mat2v3float_uint_1 [[sbuf_d0]] %uint_2
+    // Reconstruct lbuf.d[0].c
+// CHECK-NEXT:  [[lbuf_d0_c:%\d+]] = OpCompositeExtract %_arr_mat2v3float_uint_1_1 [[lbuf_d0]] 2
 // CHECK-NEXT: [[lbuf_d0_c0:%\d+]] = OpCompositeExtract %mat2v3float [[lbuf_d0_c]] 0
 // CHECK-NEXT: [[lbuf_d0_c0:%\d+]] = OpCompositeExtract %mat2v3float [[lbuf_d0_c]] 0
-// CHECK-NEXT: [[sbuf_d0_c0:%\d+]] = OpAccessChain %_ptr_Uniform_mat2v3float [[sbuf_d0_c]] %uint_0
-// CHECK-NEXT: OpStore [[sbuf_d0_c0]] [[lbuf_d0_c0]]
+// CHECK-NEXT:  [[sbuf_d0_c:%\d+]] = OpCompositeConstruct %_arr_mat2v3float_uint_1 [[lbuf_d0_c0]]
+
+// CHECK-NEXT:    [[sbuf_d0:%\d+]] = OpCompositeConstruct %SubBuffer [[sbuf_d0_a]] [[sbuf_d0_b]] [[sbuf_d0_c]]
+// CHECK-NEXT:     [[sbuf_d:%\d+]] = OpCompositeConstruct %_arr_SubBuffer_uint_1 [[sbuf_d0]]
+// CHECK-NEXT:   [[sbuf_val:%\d+]] = OpCompositeConstruct %BufferType [[lbuf_a]] [[lbuf_b]] [[lbuf_c]] [[sbuf_d]]
+
+// CHECK-NEXT: OpStore [[sbuf5]] [[sbuf_val]]
     BufferType lbuf;                  // %BufferType_0                   & %SubBuffer_1
     BufferType lbuf;                  // %BufferType_0                   & %SubBuffer_1
     sbuf[5]  = lbuf;             // %BufferType <- %BufferType_0
     sbuf[5]  = lbuf;             // %BufferType <- %BufferType_0
 
 
 // CHECK-NEXT: [[ptr:%\d+]] = OpAccessChain %_ptr_Uniform_SubBuffer_0 %cbuf %int_3 %int_0
 // CHECK-NEXT: [[ptr:%\d+]] = OpAccessChain %_ptr_Uniform_SubBuffer_0 %cbuf %int_3 %int_0
 // CHECK-NEXT: [[cbuf_d0:%\d+]] = OpLoad %SubBuffer_0 [[ptr]]
 // CHECK-NEXT: [[cbuf_d0:%\d+]] = OpLoad %SubBuffer_0 [[ptr]]
 
 
-    // sub.a[0] <- cbuf.d[0].a[0]
-// CHECK-NEXT: [[cbuf_d0_a:%\d+]] = OpCompositeExtract %_arr_float_uint_1_0 [[cbuf_d0]] 0
-// CHECK-NEXT: [[sub_a:%\d+]] = OpAccessChain %_ptr_Function__arr_float_uint_1_1 %sub %uint_0
+    // Reconstruct lbuf.d[0].a
+// CHECK-NEXT:  [[cbuf_d0_a:%\d+]] = OpCompositeExtract %_arr_float_uint_1_0 [[cbuf_d0]] 0
 // CHECK-NEXT: [[cbuf_d0_a0:%\d+]] = OpCompositeExtract %float [[cbuf_d0_a]] 0
 // CHECK-NEXT: [[cbuf_d0_a0:%\d+]] = OpCompositeExtract %float [[cbuf_d0_a]] 0
-// CHECK-NEXT: [[sub_a0:%\d+]] = OpAccessChain %_ptr_Function_float [[sub_a]] %uint_0
-// CHECK-NEXT: OpStore [[sub_a0]] [[cbuf_d0_a0]]
+// CHECK-NEXT:      [[sub_a:%\d+]] = OpCompositeConstruct %_arr_float_uint_1_1 [[cbuf_d0_a0]]
 
 
-    // sub.b[0] <- cbuf.d[0].b[0]
-// CHECK-NEXT: [[cbuf_d0_b:%\d+]] = OpCompositeExtract %_arr_v2float_uint_1_0 [[cbuf_d0]] 1
-// CHECK-NEXT: [[sub_b:%\d+]] = OpAccessChain %_ptr_Function__arr_v2float_uint_1_1 %sub %uint_1
+    // Reconstruct lbuf.d[0].b
+// CHECK-NEXT:  [[cbuf_d0_b:%\d+]] = OpCompositeExtract %_arr_v2float_uint_1_0 [[cbuf_d0]] 1
 // CHECK-NEXT: [[cbuf_d0_b0:%\d+]] = OpCompositeExtract %v2float [[cbuf_d0_b]] 0
 // CHECK-NEXT: [[cbuf_d0_b0:%\d+]] = OpCompositeExtract %v2float [[cbuf_d0_b]] 0
-// CHECK-NEXT: [[sub_b0:%\d+]] = OpAccessChain %_ptr_Function_v2float [[sub_b]] %uint_0
-// CHECK-NEXT: OpStore [[sub_b0]] [[cbuf_d0_b0]]
+// CHECK-NEXT:      [[sub_b:%\d+]] = OpCompositeConstruct %_arr_v2float_uint_1_1 [[cbuf_d0_b0]]
 
 
-    // sub.c[0] <- cbuf.d[0].c[0]
-// CHECK-NEXT: [[cbuf_d0_c:%\d+]] = OpCompositeExtract %_arr_mat2v3float_uint_1_0 [[cbuf_d0]] 2
-// CHECK-NEXT: [[sub_c:%\d+]] = OpAccessChain %_ptr_Function__arr_mat2v3float_uint_1_1 %sub %uint_2
+    // Reconstruct lbuf.d[0].c
+// CHECK-NEXT:  [[cbuf_d0_c:%\d+]] = OpCompositeExtract %_arr_mat2v3float_uint_1_0 [[cbuf_d0]] 2
 // CHECK-NEXT: [[cbuf_d0_c0:%\d+]] = OpCompositeExtract %mat2v3float [[cbuf_d0_c]] 0
 // CHECK-NEXT: [[cbuf_d0_c0:%\d+]] = OpCompositeExtract %mat2v3float [[cbuf_d0_c]] 0
-// CHECK-NEXT: [[sub_c0:%\d+]] = OpAccessChain %_ptr_Function_mat2v3float [[sub_c]] %uint_0
-// CHECK-NEXT: OpStore [[sub_c0]] [[cbuf_d0_c0]]
+// CHECK-NEXT:      [[sub_c:%\d+]] = OpCompositeConstruct %_arr_mat2v3float_uint_1_1 [[cbuf_d0_c0]]
+
+// CHECK-NEXT:    [[sub_val:%\d+]] = OpCompositeConstruct %SubBuffer_1 [[sub_a]] [[sub_b]] [[sub_c]]
+// CHECK-NEXT:                       OpStore %sub [[sub_val]]
     SubBuffer sub = cbuf.d[0];        // %SubBuffer_1 <- %SubBuffer_0
     SubBuffer sub = cbuf.d[0];        // %SubBuffer_1 <- %SubBuffer_0
 }
 }

+ 6 - 8
tools/clang/test/CodeGenSPIRV/cast.flat-conversion.no-op.hlsl

@@ -19,27 +19,25 @@ float4 main() : SV_Target {
 // CHECK-NEXT:   [[gscalars_val:%\d+]] = OpLoad %_arr_float_uint_1 [[gscalars_ptr]]
 // CHECK-NEXT:   [[gscalars_val:%\d+]] = OpLoad %_arr_float_uint_1 [[gscalars_ptr]]
 // CHECK-NEXT:    [[scalars_ptr:%\d+]] = OpAccessChain %_ptr_Function__arr_float_uint_1_0 %t %int_0
 // CHECK-NEXT:    [[scalars_ptr:%\d+]] = OpAccessChain %_ptr_Function__arr_float_uint_1_0 %t %int_0
 // CHECK-NEXT:      [[gscalars0:%\d+]] = OpCompositeExtract %float [[gscalars_val]] 0
 // CHECK-NEXT:      [[gscalars0:%\d+]] = OpCompositeExtract %float [[gscalars_val]] 0
-// CHECK-NEXT:   [[scalars0_ptr:%\d+]] = OpAccessChain %_ptr_Function_float [[scalars_ptr]] %uint_0
-// CHECK-NEXT:                           OpStore [[scalars0_ptr]] [[gscalars0]]
+// CHECK-NEXT:    [[scalars_val:%\d+]] = OpCompositeConstruct %_arr_float_uint_1_0 [[gscalars0]]
+// CHECK-NEXT:                           OpStore [[scalars_ptr]] [[scalars_val]]
     t.scalars = gScalars;
     t.scalars = gScalars;
 
 
 // CHECK-NEXT: [[gvecs_ptr:%\d+]] = OpAccessChain %_ptr_Uniform__arr_v4float_uint_2 %Data %int_1
 // CHECK-NEXT: [[gvecs_ptr:%\d+]] = OpAccessChain %_ptr_Uniform__arr_v4float_uint_2 %Data %int_1
 // CHECK-NEXT: [[gvecs_val:%\d+]] = OpLoad %_arr_v4float_uint_2 [[gvecs_ptr]]
 // CHECK-NEXT: [[gvecs_val:%\d+]] = OpLoad %_arr_v4float_uint_2 [[gvecs_ptr]]
 // CHECK-NEXT:  [[vecs_ptr:%\d+]] = OpAccessChain %_ptr_Function__arr_v4float_uint_2_0 %t %int_1
 // CHECK-NEXT:  [[vecs_ptr:%\d+]] = OpAccessChain %_ptr_Function__arr_v4float_uint_2_0 %t %int_1
 // CHECK-NEXT:    [[gvecs0:%\d+]] = OpCompositeExtract %v4float [[gvecs_val]] 0
 // CHECK-NEXT:    [[gvecs0:%\d+]] = OpCompositeExtract %v4float [[gvecs_val]] 0
-// CHECK-NEXT: [[vecs0_ptr:%\d+]] = OpAccessChain %_ptr_Function_v4float [[vecs_ptr]] %uint_0
-// CHECK-NEXT:                      OpStore [[vecs0_ptr]] [[gvecs0]]
 // CHECK-NEXT:    [[gvecs1:%\d+]] = OpCompositeExtract %v4float [[gvecs_val]] 1
 // CHECK-NEXT:    [[gvecs1:%\d+]] = OpCompositeExtract %v4float [[gvecs_val]] 1
-// CHECK-NEXT: [[vecs1_ptr:%\d+]] = OpAccessChain %_ptr_Function_v4float [[vecs_ptr]] %uint_1
-// CHECK-NEXT:                      OpStore [[vecs1_ptr]] [[gvecs1]]
+// CHECK-NEXT:  [[vecs_val:%\d+]] = OpCompositeConstruct %_arr_v4float_uint_2_0 [[gvecs0]] [[gvecs1]]
+// CHECK-NEXT:                      OpStore [[vecs_ptr]] [[vecs_val]]
     t.vecs    = gVecs;
     t.vecs    = gVecs;
 
 
 // CHECK-NEXT: [[gmats_ptr:%\d+]] = OpAccessChain %_ptr_Uniform__arr_mat2v3float_uint_1 %Data %int_2
 // CHECK-NEXT: [[gmats_ptr:%\d+]] = OpAccessChain %_ptr_Uniform__arr_mat2v3float_uint_1 %Data %int_2
 // CHECK-NEXT: [[gmats_val:%\d+]] = OpLoad %_arr_mat2v3float_uint_1 [[gmats_ptr]]
 // CHECK-NEXT: [[gmats_val:%\d+]] = OpLoad %_arr_mat2v3float_uint_1 [[gmats_ptr]]
 // CHECK-NEXT:  [[mats_ptr:%\d+]] = OpAccessChain %_ptr_Function__arr_mat2v3float_uint_1_0 %t %int_2
 // CHECK-NEXT:  [[mats_ptr:%\d+]] = OpAccessChain %_ptr_Function__arr_mat2v3float_uint_1_0 %t %int_2
 // CHECK-NEXT:    [[gmats0:%\d+]] = OpCompositeExtract %mat2v3float [[gmats_val]] 0
 // CHECK-NEXT:    [[gmats0:%\d+]] = OpCompositeExtract %mat2v3float [[gmats_val]] 0
-// CHECK-NEXT: [[mats0_ptr:%\d+]] = OpAccessChain %_ptr_Function_mat2v3float [[mats_ptr]] %uint_0
-// CHECK-NEXT:                      OpStore [[mats0_ptr]] [[gmats0]]
+// CHECK-NEXT:  [[mats_val:%\d+]] = OpCompositeConstruct %_arr_mat2v3float_uint_1_0 [[gmats0]]
+// CHECK-NEXT:                      OpStore [[mats_ptr]] [[mats_val]]
     t.mats    = gMats;
     t.mats    = gMats;
 
 
     return t.vecs[1];
     return t.vecs[1];

+ 2 - 6
tools/clang/test/CodeGenSPIRV/cf.return.storage-class.hlsl

@@ -15,14 +15,10 @@ BufferType retSBuffer5() {            // BufferType_0
 // CHECK-NEXT: [[sbuf:%\d+]] = OpAccessChain %_ptr_Uniform_BufferType %sbuf %int_0 %uint_5
 // CHECK-NEXT: [[sbuf:%\d+]] = OpAccessChain %_ptr_Uniform_BufferType %sbuf %int_0 %uint_5
 // CHECK-NEXT:  [[val:%\d+]] = OpLoad %BufferType [[sbuf]]
 // CHECK-NEXT:  [[val:%\d+]] = OpLoad %BufferType [[sbuf]]
 // CHECK-NEXT:    [[a:%\d+]] = OpCompositeExtract %float [[val]] 0
 // CHECK-NEXT:    [[a:%\d+]] = OpCompositeExtract %float [[val]] 0
-// CHECK-NEXT: [[tmp0:%\d+]] = OpAccessChain %_ptr_Function_float %temp_var_ret %uint_0
-// CHECK-NEXT:                 OpStore [[tmp0]] [[a]]
 // CHECK-NEXT:    [[b:%\d+]] = OpCompositeExtract %v3float [[val]] 1
 // CHECK-NEXT:    [[b:%\d+]] = OpCompositeExtract %v3float [[val]] 1
-// CHECK-NEXT: [[tmp1:%\d+]] = OpAccessChain %_ptr_Function_v3float %temp_var_ret %uint_1
-// CHECK-NEXT:                 OpStore [[tmp1]] [[b]]
 // CHECK-NEXT:    [[c:%\d+]] = OpCompositeExtract %mat3v2float [[val]] 2
 // CHECK-NEXT:    [[c:%\d+]] = OpCompositeExtract %mat3v2float [[val]] 2
-// CHECK-NEXT: [[tmp2:%\d+]] = OpAccessChain %_ptr_Function_mat3v2float %temp_var_ret %uint_2
-// CHECK-NEXT:                 OpStore [[tmp2]] [[c]]
+// CHECK-NEXT:  [[tmp:%\d+]] = OpCompositeConstruct %BufferType_0 [[a]] [[b]] [[c]]
+// CHECK-NEXT:                 OpStore %temp_var_ret [[tmp]]
 // CHECK-NEXT:  [[tmp:%\d+]] = OpLoad %BufferType_0 %temp_var_ret
 // CHECK-NEXT:  [[tmp:%\d+]] = OpLoad %BufferType_0 %temp_var_ret
 // CHECK-NEXT:       OpReturnValue [[tmp]]
 // CHECK-NEXT:       OpReturnValue [[tmp]]
 // CHECK-NEXT:       OpFunctionEnd
 // CHECK-NEXT:       OpFunctionEnd

+ 2 - 2
tools/clang/test/CodeGenSPIRV/fn.ctbuffer.hlsl

@@ -30,8 +30,8 @@ float4 main() : SV_Target {
 // CHECK:       [[tb_s:%\d+]] = OpAccessChain %_ptr_Uniform_S %MyTBuffer %int_1
 // CHECK:       [[tb_s:%\d+]] = OpAccessChain %_ptr_Uniform_S %MyTBuffer %int_1
 // CHECK-NEXT:     [[s:%\d+]] = OpLoad %S [[tb_s]]
 // CHECK-NEXT:     [[s:%\d+]] = OpLoad %S [[tb_s]]
 // CHECK-NEXT: [[s_val:%\d+]] = OpCompositeExtract %v3float [[s]] 0
 // CHECK-NEXT: [[s_val:%\d+]] = OpCompositeExtract %v3float [[s]] 0
-// CHECK-NEXT:   [[ptr:%\d+]] = OpAccessChain %_ptr_Function_v3float %temp_var_S %uint_0
-// CHECK-NEXT:                  OpStore [[ptr]] [[s_val]]
+// CHECK-NEXT:   [[tmp:%\d+]] = OpCompositeConstruct %S_0 [[s_val]]
+// CHECK-NEXT:                  OpStore %temp_var_S [[tmp]]
 // CHECK-NEXT:       {{%\d+}} = OpFunctionCall %v3float %S_get_s_val %temp_var_S
 // CHECK-NEXT:       {{%\d+}} = OpFunctionCall %v3float %S_get_s_val %temp_var_S
     return get_cb_val() + float4(tb_s.get_s_val(), 0.) * get_tb_val();
     return get_cb_val() + float4(tb_s.get_s_val(), 0.) * get_tb_val();
 }
 }

+ 5 - 10
tools/clang/test/CodeGenSPIRV/method.append-structured-buffer.append.hlsl

@@ -25,16 +25,11 @@ void main(float4 vec: A) {
 // CHECK-NEXT: [[buffer2:%\d+]] = OpAccessChain %_ptr_Uniform_S %buffer2 %uint_0 [[index]]
 // CHECK-NEXT: [[buffer2:%\d+]] = OpAccessChain %_ptr_Uniform_S %buffer2 %uint_0 [[index]]
 // CHECK-NEXT: [[s:%\d+]] = OpLoad %S_0 %s
 // CHECK-NEXT: [[s:%\d+]] = OpLoad %S_0 %s
 
 
-// CHECK-NEXT: [[s0:%\d+]] = OpCompositeExtract %float [[s]] 0
-// CHECK-NEXT: [[buffer20:%\d+]] = OpAccessChain %_ptr_Uniform_float [[buffer2]] %uint_0
-// CHECK-NEXT: OpStore [[buffer20]] [[s0]]
+// CHECK-NEXT: [[s_a:%\d+]] = OpCompositeExtract %float [[s]] 0
+// CHECK-NEXT: [[s_b:%\d+]] = OpCompositeExtract %v3float [[s]] 1
+// CHECK-NEXT: [[s_c:%\d+]] = OpCompositeExtract %mat2v3float [[s]] 2
 
 
-// CHECK-NEXT: [[s1:%\d+]] = OpCompositeExtract %v3float [[s]] 1
-// CHECK-NEXT: [[buffer21:%\d+]] = OpAccessChain %_ptr_Uniform_v3float [[buffer2]] %uint_1
-// CHECK-NEXT: OpStore [[buffer21]] [[s1]]
-
-// CHECK-NEXT: [[s2:%\d+]] = OpCompositeExtract %mat2v3float [[s]] 2
-// CHECK-NEXT: [[buffer22:%\d+]] = OpAccessChain %_ptr_Uniform_mat2v3float [[buffer2]] %uint_2
-// CHECK-NEXT: OpStore [[buffer22]] [[s2]]
+// CHECK-NEXT: [[val:%\d+]] = OpCompositeConstruct %S [[s_a]] [[s_b]] [[s_c]]
+// CHECK-NEXT: OpStore [[buffer2]] [[val]]
     buffer2.Append(s);
     buffer2.Append(s);
 }
 }

+ 5 - 10
tools/clang/test/CodeGenSPIRV/method.consume-structured-buffer.consume.hlsl

@@ -32,17 +32,12 @@ float4 main() : A {
 // CHECK-NEXT: [[buffer2:%\d+]] = OpAccessChain %_ptr_Uniform_S %buffer2 %uint_0 [[index]]
 // CHECK-NEXT: [[buffer2:%\d+]] = OpAccessChain %_ptr_Uniform_S %buffer2 %uint_0 [[index]]
 // CHECK-NEXT: [[val:%\d+]] = OpLoad %S [[buffer2]]
 // CHECK-NEXT: [[val:%\d+]] = OpLoad %S [[buffer2]]
 
 
-// CHECK-NEXT: [[buffer20:%\d+]] = OpCompositeExtract %float [[val]] 0
-// CHECK-NEXT: [[s0:%\d+]] = OpAccessChain %_ptr_Function_float %s %uint_0
-// CHECK-NEXT: OpStore [[s0]] [[buffer20]]
+// CHECK-NEXT: [[s_a:%\d+]] = OpCompositeExtract %float [[val]] 0
+// CHECK-NEXT: [[s_b:%\d+]] = OpCompositeExtract %v3float [[val]] 1
+// CHECK-NEXT: [[s_c:%\d+]] = OpCompositeExtract %mat2v3float [[val]] 2
 
 
-// CHECK-NEXT: [[buffer21:%\d+]] = OpCompositeExtract %v3float [[val]] 1
-// CHECK-NEXT: [[s1:%\d+]] = OpAccessChain %_ptr_Function_v3float %s %uint_1
-// CHECK-NEXT: OpStore [[s1]] [[buffer21]]
-
-// CHECK-NEXT: [[buffer22:%\d+]] = OpCompositeExtract %mat2v3float [[val]] 2
-// CHECK-NEXT: [[s2:%\d+]] = OpAccessChain %_ptr_Function_mat2v3float %s %uint_2
-// CHECK-NEXT: OpStore [[s2]] [[buffer22]]
+// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %S_0 [[s_a]] [[s_b]] [[s_c]]
+// CHECK-NEXT: OpStore %s [[tmp]]
     s = buffer2.Consume();
     s = buffer2.Consume();
 
 
 // CHECK:      [[counter:%\d+]] = OpAccessChain %_ptr_Uniform_int %counter_var_buffer3 %uint_0
 // CHECK:      [[counter:%\d+]] = OpAccessChain %_ptr_Uniform_int %counter_var_buffer3 %uint_0

+ 10 - 10
tools/clang/test/CodeGenSPIRV/spirv.legal.cbuffer.hlsl

@@ -30,15 +30,15 @@ float4 main(in float4 pos : SV_Position) : SV_Target
 // Initializing a T with a ConstantBuffer<T> is a copy
 // Initializing a T with a ConstantBuffer<T> is a copy
 // CHECK:      [[val:%\d+]] = OpLoad %type_ConstantBuffer_S %myCBuffer
 // CHECK:      [[val:%\d+]] = OpLoad %type_ConstantBuffer_S %myCBuffer
 // CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0
 // CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0
-// CHECK-NEXT: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_v4float %buffer1 %uint_0
-// CHECK-NEXT:                OpStore [[ptr]] [[vec]]
+// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %S_0 [[vec]]
+// CHECK-NEXT:                OpStore %buffer1 [[tmp]]
     S buffer1 = myCBuffer;
     S buffer1 = myCBuffer;
 
 
 // Assigning a ConstantBuffer<T> to a T is a copy
 // Assigning a ConstantBuffer<T> to a T is a copy
 // CHECK:      [[val:%\d+]] = OpLoad %type_ConstantBuffer_S %myCBuffer
 // CHECK:      [[val:%\d+]] = OpLoad %type_ConstantBuffer_S %myCBuffer
 // CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0
 // CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0
-// CHECK-NEXT: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_v4float %buffer2 %uint_0
-// CHECK-NEXT:                OpStore [[ptr]] [[vec]]
+// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %S_0 [[vec]]
+// CHECK-NEXT:                OpStore %buffer2 [[tmp]]
     S buffer2;
     S buffer2;
     buffer2 = myCBuffer;
     buffer2 = myCBuffer;
 
 
@@ -52,15 +52,15 @@ float4 main(in float4 pos : SV_Position) : SV_Target
 // CHECK:      [[ptr:%\d+]] = OpAccessChain %_ptr_Uniform_S %myASBuffer %uint_0 {{%\d+}}
 // CHECK:      [[ptr:%\d+]] = OpAccessChain %_ptr_Uniform_S %myASBuffer %uint_0 {{%\d+}}
 // CHECK-NEXT: [[val:%\d+]] = OpLoad %type_ConstantBuffer_S %myCBuffer
 // CHECK-NEXT: [[val:%\d+]] = OpLoad %type_ConstantBuffer_S %myCBuffer
 // CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0
 // CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0
-// CHECK-NEXT: [[adr:%\d+]] = OpAccessChain %_ptr_Uniform_v4float [[ptr]] %uint_0
-// CHECK-NEXT:                OpStore [[adr]] [[vec]]
+// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %S [[vec]]
+// CHECK-NEXT:                OpStore [[ptr]] [[tmp]]
     myASBuffer.Append(myCBuffer);
     myASBuffer.Append(myCBuffer);
 
 
 // Passing a ConstantBuffer<T> to a T parameter is a copy
 // Passing a ConstantBuffer<T> to a T parameter is a copy
 // CHECK:      [[val:%\d+]] = OpLoad %type_ConstantBuffer_S %myCBuffer
 // CHECK:      [[val:%\d+]] = OpLoad %type_ConstantBuffer_S %myCBuffer
 // CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0
 // CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0
-// CHECK-NEXT: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_v4float %param_var_buffer %uint_0
-// CHECK-NEXT:                OpStore [[ptr]] [[vec]]
+// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %S_0 [[vec]]
+// CHECK-NEXT:                OpStore %param_var_buffer [[tmp]]
     return doStuff(myCBuffer);
     return doStuff(myCBuffer);
 }
 }
 
 
@@ -68,8 +68,8 @@ S retStuff() {
 // Returning a ConstantBuffer<T> as a T is a copy
 // Returning a ConstantBuffer<T> as a T is a copy
 // CHECK:      [[val:%\d+]] = OpLoad %type_ConstantBuffer_S %myCBuffer
 // CHECK:      [[val:%\d+]] = OpLoad %type_ConstantBuffer_S %myCBuffer
 // CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0
 // CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0
-// CHECK-NEXT: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_v4float %temp_var_ret %uint_0
-// CHECK-NEXT:                OpStore [[ptr]] [[vec]]
+// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %S_0 [[vec]]
+// CHECK-NEXT:                OpStore %temp_var_ret [[tmp]]
 // CHECK-NEXT: [[ret:%\d+]] = OpLoad %S_0 %temp_var_ret
 // CHECK-NEXT: [[ret:%\d+]] = OpLoad %S_0 %temp_var_ret
 // CHECK-NEXT:                OpReturnValue [[ret]]
 // CHECK-NEXT:                OpReturnValue [[ret]]
     return myCBuffer;
     return myCBuffer;

+ 4 - 4
tools/clang/test/CodeGenSPIRV/spirv.legal.sbuffer.counter.hlsl

@@ -94,8 +94,8 @@ float4 main() : SV_Target {
 // CHECK-NEXT: [[ptr3:%\d+]] = OpAccessChain %_ptr_Uniform_S3 [[call]] %uint_0 [[idx]]
 // CHECK-NEXT: [[ptr3:%\d+]] = OpAccessChain %_ptr_Uniform_S3 [[call]] %uint_0 [[idx]]
 // CHECK-NEXT:  [[val:%\d+]] = OpLoad %S3 [[ptr3]]
 // CHECK-NEXT:  [[val:%\d+]] = OpLoad %S3 [[ptr3]]
 // CHECK-NEXT:  [[vec:%\d+]] = OpCompositeExtract %v2float [[val]] 0
 // CHECK-NEXT:  [[vec:%\d+]] = OpCompositeExtract %v2float [[val]] 0
-// CHECK-NEXT: [[ptr4:%\d+]] = OpAccessChain %_ptr_Function_v2float %val3 %uint_0
-// CHECK-NEXT:                 OpStore [[ptr4]] [[vec]]
+// CHECK-NEXT:  [[tmp:%\d+]] = OpCompositeConstruct %S3_0 [[vec]]
+// CHECK-NEXT:                 OpStore %val3 [[tmp]]
         .Consume();
         .Consume();
 
 
     float3 vec = float3(val3.f, 1.0);
     float3 vec = float3(val3.f, 1.0);
@@ -119,8 +119,8 @@ float4 main() : SV_Target {
 // CHECK-NEXT: [[ptr4:%\d+]] = OpAccessChain %_ptr_Uniform_S2 [[ptr1]] %uint_0 [[idx]]
 // CHECK-NEXT: [[ptr4:%\d+]] = OpAccessChain %_ptr_Uniform_S2 [[ptr1]] %uint_0 [[idx]]
 // CHECK-NEXT:  [[val:%\d+]] = OpLoad %S2_0 %val2
 // CHECK-NEXT:  [[val:%\d+]] = OpLoad %S2_0 %val2
 // CHECK-NEXT:  [[vec:%\d+]] = OpCompositeExtract %v3float [[val]] 0
 // CHECK-NEXT:  [[vec:%\d+]] = OpCompositeExtract %v3float [[val]] 0
-// CHECK-NEXT: [[ptr5:%\d+]] = OpAccessChain %_ptr_Uniform_v3float [[ptr4]] %uint_0
-// CHECK-NEXT:                 OpStore [[ptr5]] [[vec]]
+// CHECK-NEXT:  [[tmp:%\d+]] = OpCompositeConstruct %S2 [[vec]]
+// CHECK-NEXT:                 OpStore [[ptr4]] [[tmp]]
     localASBufferMain.Append(val2);
     localASBufferMain.Append(val2);
 
 
     return float4(val2, 2.0);
     return float4(val2, 2.0);

+ 8 - 8
tools/clang/test/CodeGenSPIRV/spirv.legal.tbuffer.hlsl

@@ -34,15 +34,15 @@ float4 main(in float4 pos : SV_Position) : SV_Target
 // Initializing a T with a TextureBuffer<T> is a copy
 // Initializing a T with a TextureBuffer<T> is a copy
 // CHECK:      [[val:%\d+]] = OpLoad %type_TextureBuffer_S %myTBuffer
 // CHECK:      [[val:%\d+]] = OpLoad %type_TextureBuffer_S %myTBuffer
 // CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0
 // CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0
-// CHECK-NEXT: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_v4float %buffer1 %uint_0
-// CHECK-NEXT:                OpStore [[ptr]] [[vec]]
+// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %S_0 [[vec]]
+// CHECK-NEXT:                OpStore %buffer1 [[tmp]]
     S buffer1 = myTBuffer;
     S buffer1 = myTBuffer;
 
 
 // Assigning a TextureBuffer<T> to a T is a copy
 // Assigning a TextureBuffer<T> to a T is a copy
 // CHECK:      [[val:%\d+]] = OpLoad %type_TextureBuffer_S %myTBuffer
 // CHECK:      [[val:%\d+]] = OpLoad %type_TextureBuffer_S %myTBuffer
 // CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0
 // CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0
-// CHECK-NEXT: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_v4float %buffer2 %uint_0
-// CHECK-NEXT:                OpStore [[ptr]] [[vec]]
+// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %S_0 [[vec]]
+// CHECK-NEXT:                OpStore %buffer2 [[tmp]]
     S buffer2;
     S buffer2;
     buffer2 = myTBuffer;
     buffer2 = myTBuffer;
 
 
@@ -62,8 +62,8 @@ float4 main(in float4 pos : SV_Position) : SV_Target
 // Passing a TextureBuffer<T> to a T parameter is a copy
 // Passing a TextureBuffer<T> to a T parameter is a copy
 // CHECK:      [[val:%\d+]] = OpLoad %type_TextureBuffer_S %myTBuffer
 // CHECK:      [[val:%\d+]] = OpLoad %type_TextureBuffer_S %myTBuffer
 // CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0
 // CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0
-// CHECK-NEXT: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_v4float %param_var_buffer %uint_0
-// CHECK-NEXT:                OpStore [[ptr]] [[vec]]
+// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %S_0 [[vec]]
+// CHECK-NEXT:                OpStore %param_var_buffer [[tmp]]
     return doStuff(myTBuffer);
     return doStuff(myTBuffer);
 }
 }
 
 
@@ -71,8 +71,8 @@ S retStuff() {
 // Returning a TextureBuffer<T> as a T is a copy
 // Returning a TextureBuffer<T> as a T is a copy
 // CHECK:      [[val:%\d+]] = OpLoad %type_TextureBuffer_S %myTBuffer
 // CHECK:      [[val:%\d+]] = OpLoad %type_TextureBuffer_S %myTBuffer
 // CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0
 // CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0
-// CHECK-NEXT: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_v4float %temp_var_ret %uint_0
-// CHECK-NEXT:                OpStore [[ptr]] [[vec]]
+// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %S_0 [[vec]]
+// CHECK-NEXT:                OpStore %temp_var_ret [[tmp]]
 // CHECK-NEXT: [[ret:%\d+]] = OpLoad %S_0 %temp_var_ret
 // CHECK-NEXT: [[ret:%\d+]] = OpLoad %S_0 %temp_var_ret
 // CHECK-NEXT:                OpReturnValue [[ret]]
 // CHECK-NEXT:                OpReturnValue [[ret]]
     return myTBuffer;
     return myTBuffer;

+ 4 - 4
tools/clang/test/CodeGenSPIRV/var.init.cross-storage-class.hlsl

@@ -19,8 +19,8 @@ cbuffer Constants {
 // CHECK:          [[ptr:%\d+]] = OpAccessChain %_ptr_Uniform_S %Constants %int_0
 // CHECK:          [[ptr:%\d+]] = OpAccessChain %_ptr_Uniform_S %Constants %int_0
 // CHECK-NEXT: [[uniform:%\d+]] = OpLoad %S [[ptr]]
 // CHECK-NEXT: [[uniform:%\d+]] = OpLoad %S [[ptr]]
 // CHECK-NEXT:     [[vec:%\d+]] = OpCompositeExtract %v4float [[uniform]] 0
 // CHECK-NEXT:     [[vec:%\d+]] = OpCompositeExtract %v4float [[uniform]] 0
-// CHECK-NEXT:     [[ptr:%\d+]] = OpAccessChain %_ptr_Private_v4float %private_struct %uint_0
-// CHECK-NEXT:                    OpStore [[ptr]] [[vec]]
+// CHECK-NEXT:  [[struct:%\d+]] = OpCompositeConstruct %S_0 [[vec]]
+// CHECK-NEXT:                    OpStore %private_struct [[struct]]
 static const S private_struct = uniform_struct; // Unifrom -> Private
 static const S private_struct = uniform_struct; // Unifrom -> Private
 
 
 float4 foo();
 float4 foo();
@@ -42,8 +42,8 @@ float4 foo()
 // CHECK:          [[ptr:%\d+]] = OpAccessChain %_ptr_Uniform_S %Constants %int_0
 // CHECK:          [[ptr:%\d+]] = OpAccessChain %_ptr_Uniform_S %Constants %int_0
 // CHECK-NEXT: [[uniform:%\d+]] = OpLoad %S [[ptr]]
 // CHECK-NEXT: [[uniform:%\d+]] = OpLoad %S [[ptr]]
 // CHECK-NEXT:     [[vec:%\d+]] = OpCompositeExtract %v4float [[uniform]] 0
 // CHECK-NEXT:     [[vec:%\d+]] = OpCompositeExtract %v4float [[uniform]] 0
-// CHECK-NEXT:     [[ptr:%\d+]] = OpAccessChain %_ptr_Private_v4float %fn_private_struct %uint_0
-// CHECK-NEXT:                    OpStore [[ptr]] [[vec]]
+// CHECK-NEXT:  [[struct:%\d+]] = OpCompositeConstruct %S_0 [[vec]]
+// CHECK-NEXT:                    OpStore %fn_private_struct [[struct]]
     static S fn_private_struct = uniform_struct; // Uniform -> Private
     static S fn_private_struct = uniform_struct; // Uniform -> Private
     return fn_private_struct.pos;
     return fn_private_struct.pos;
 }
 }

+ 2 - 4
tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.zpc.hlsl

@@ -36,10 +36,8 @@ void main() {
 // CHECK-NEXT:   [[ptr_matrices4_1:%\d+]] = OpAccessChain %_ptr_Uniform__arr_v3int_uint_2 [[ptr_matrices4]] %int_1
 // CHECK-NEXT:   [[ptr_matrices4_1:%\d+]] = OpAccessChain %_ptr_Uniform__arr_v3int_uint_2 [[ptr_matrices4]] %int_1
 // CHECK-NEXT:       [[matrices4_1:%\d+]] = OpLoad %_arr_v3int_uint_2 [[ptr_matrices4_1]]
 // CHECK-NEXT:       [[matrices4_1:%\d+]] = OpLoad %_arr_v3int_uint_2 [[ptr_matrices4_1]]
 // CHECK-NEXT:  [[matrices4_1_row0:%\d+]] = OpCompositeExtract %v3int [[matrices4_1]] 0
 // CHECK-NEXT:  [[matrices4_1_row0:%\d+]] = OpCompositeExtract %v3int [[matrices4_1]] 0
-// CHECK-NEXT:       [[ptr_m4_row0:%\d+]] = OpAccessChain %_ptr_Function_v3int %m4 %uint_0
-// CHECK-NEXT:                              OpStore [[ptr_m4_row0]] [[matrices4_1_row0]]
 // CHECK-NEXT:  [[matrices4_1_row1:%\d+]] = OpCompositeExtract %v3int [[matrices4_1]] 1
 // CHECK-NEXT:  [[matrices4_1_row1:%\d+]] = OpCompositeExtract %v3int [[matrices4_1]] 1
-// CHECK-NEXT:       [[ptr_m4_row1:%\d+]] = OpAccessChain %_ptr_Function_v3int %m4 %uint_1
-// CHECK-NEXT:                              OpStore [[ptr_m4_row1]] [[matrices4_1_row1]]
+// CHECK-NEXT:               [[tmp:%\d+]] = OpCompositeConstruct %_arr_v3int_uint_2_0 [[matrices4_1_row0]] [[matrices4_1_row1]]
+// CHECK-NEXT:                              OpStore %m4 [[tmp]]
     int2x3 m4 = matrices4[1];
     int2x3 m4 = matrices4[1];
 }
 }

+ 4 - 8
tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.zpr.hlsl

@@ -37,20 +37,16 @@ void main() {
 // CHECK-NEXT:   [[ptr_matrices4_1:%\d+]] = OpAccessChain %_ptr_Uniform__arr_v3int_uint_2 [[ptr_matrices4]] %int_1
 // CHECK-NEXT:   [[ptr_matrices4_1:%\d+]] = OpAccessChain %_ptr_Uniform__arr_v3int_uint_2 [[ptr_matrices4]] %int_1
 // CHECK-NEXT:       [[matrices4_1:%\d+]] = OpLoad %_arr_v3int_uint_2 [[ptr_matrices4_1]]
 // CHECK-NEXT:       [[matrices4_1:%\d+]] = OpLoad %_arr_v3int_uint_2 [[ptr_matrices4_1]]
 // CHECK-NEXT:  [[matrices4_1_row0:%\d+]] = OpCompositeExtract %v3int [[matrices4_1]] 0
 // CHECK-NEXT:  [[matrices4_1_row0:%\d+]] = OpCompositeExtract %v3int [[matrices4_1]] 0
-// CHECK-NEXT:       [[ptr_m4_row0:%\d+]] = OpAccessChain %_ptr_Function_v3int %m4 %uint_0
-// CHECK-NEXT:                              OpStore [[ptr_m4_row0]] [[matrices4_1_row0]]
 // CHECK-NEXT:  [[matrices4_1_row1:%\d+]] = OpCompositeExtract %v3int [[matrices4_1]] 1
 // CHECK-NEXT:  [[matrices4_1_row1:%\d+]] = OpCompositeExtract %v3int [[matrices4_1]] 1
-// CHECK-NEXT:       [[ptr_m4_row1:%\d+]] = OpAccessChain %_ptr_Function_v3int %m4 %uint_1
-// CHECK-NEXT:                              OpStore [[ptr_m4_row1]] [[matrices4_1_row1]]
+// CHECK-NEXT:               [[tmp:%\d+]] = OpCompositeConstruct %_arr_v3int_uint_2_0 [[matrices4_1_row0]] [[matrices4_1_row1]]
+// CHECK-NEXT:                              OpStore %m4 [[tmp]]
     int2x3 m4 = matrices4[1];
     int2x3 m4 = matrices4[1];
 // CHECK:          [[ptr_matrices5:%\d+]] = OpAccessChain %_ptr_Uniform__arr__arr_v3int_uint_2_uint_5 %MyCBuffer %int_4
 // CHECK:          [[ptr_matrices5:%\d+]] = OpAccessChain %_ptr_Uniform__arr__arr_v3int_uint_2_uint_5 %MyCBuffer %int_4
 // CHECK-NEXT:   [[ptr_matrices5_2:%\d+]] = OpAccessChain %_ptr_Uniform__arr_v3int_uint_2 [[ptr_matrices5]] %int_2
 // CHECK-NEXT:   [[ptr_matrices5_2:%\d+]] = OpAccessChain %_ptr_Uniform__arr_v3int_uint_2 [[ptr_matrices5]] %int_2
 // CHECK-NEXT:       [[matrices5_2:%\d+]] = OpLoad %_arr_v3int_uint_2 [[ptr_matrices5_2]]
 // CHECK-NEXT:       [[matrices5_2:%\d+]] = OpLoad %_arr_v3int_uint_2 [[ptr_matrices5_2]]
 // CHECK-NEXT: [[matrices_5_2_row0:%\d+]] = OpCompositeExtract %v3int [[matrices5_2]] 0
 // CHECK-NEXT: [[matrices_5_2_row0:%\d+]] = OpCompositeExtract %v3int [[matrices5_2]] 0
-// CHECK-NEXT:       [[ptr_m5_row0:%\d+]] = OpAccessChain %_ptr_Function_v3int %m5 %uint_0
-// CHECK-NEXT:                              OpStore [[ptr_m5_row0]] [[matrices_5_2_row0]]
 // CHECK-NEXT: [[matrices_5_2_row1:%\d+]] = OpCompositeExtract %v3int [[matrices5_2]] 1
 // CHECK-NEXT: [[matrices_5_2_row1:%\d+]] = OpCompositeExtract %v3int [[matrices5_2]] 1
-// CHECK-NEXT:       [[ptr_m5_row1:%\d+]] = OpAccessChain %_ptr_Function_v3int %m5 %uint_1
-// CHECK-NEXT:                              OpStore [[ptr_m5_row1]] [[matrices_5_2_row1]]
+// CHECK-NEXT:               [[tmp:%\d+]] = OpCompositeConstruct %_arr_v3int_uint_2_0 [[matrices_5_2_row0]] [[matrices_5_2_row1]]
+// CHECK-NEXT:                              OpStore %m5 [[tmp]]
     int2x3 m5 = matrices5[2];
     int2x3 m5 = matrices5[2];
 }
 }