Prechádzať zdrojové kódy

[spirv] Update the handling of literal types. (#954)

* [spirv] Update the handling of literal types.

Try to figure out what is the intended usage for a literal type (e.g.
'literal int' or 'literal float').

Provide a hint to the TypeTranslator and translateAP{Int|Float} methods
so they better reflect the usage of literal types.
Ehsan 7 rokov pred
rodič
commit
5f0b2c7dc1

+ 88 - 92
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -388,6 +388,19 @@ const ValueDecl *getReferencedDef(const Expr *expr) {
   return nullptr;
 }
 
+bool isLiteralType(QualType type) {
+  if (type->isSpecificBuiltinType(BuiltinType::LitInt) ||
+      type->isSpecificBuiltinType(BuiltinType::LitFloat))
+    return true;
+
+  // For cases such as 'vector<literal int, 2>'
+  QualType elemType = {};
+  if (TypeTranslator::isVectorType(type, &elemType))
+    return isLiteralType(elemType);
+
+  return false;
+}
+
 } // namespace
 
 SPIRVEmitter::SPIRVEmitter(CompilerInstance &ci,
@@ -591,86 +604,65 @@ SpirvEvalInfo SPIRVEmitter::doDeclRefExpr(const DeclRefExpr *expr) {
 }
 
 SpirvEvalInfo SPIRVEmitter::doExpr(const Expr *expr) {
-  expr = expr->IgnoreParens();
+  SpirvEvalInfo result(/*id*/ 0);
 
-  if (const auto *declRefExpr = dyn_cast<DeclRefExpr>(expr)) {
-    return doDeclRefExpr(declRefExpr);
-  }
-
-  if (const auto *memberExpr = dyn_cast<MemberExpr>(expr)) {
-    return doMemberExpr(memberExpr);
-  }
+  const bool isNonLiteralType = !isLiteralType(expr->getType());
+  if (isNonLiteralType)
+    typeTranslator.pushIntendedLiteralType(expr->getType());
 
-  if (const auto *castExpr = dyn_cast<CastExpr>(expr)) {
-    return doCastExpr(castExpr);
-  }
-
-  if (const auto *initListExpr = dyn_cast<InitListExpr>(expr)) {
-    return doInitListExpr(initListExpr);
-  }
+  expr = expr->IgnoreParens();
 
-  if (const auto *boolLiteral = dyn_cast<CXXBoolLiteralExpr>(expr)) {
+  if (const auto *declRefExpr = dyn_cast<DeclRefExpr>(expr)) {
+    result = doDeclRefExpr(declRefExpr);
+  } else if (const auto *memberExpr = dyn_cast<MemberExpr>(expr)) {
+    result = doMemberExpr(memberExpr);
+  } else if (const auto *castExpr = dyn_cast<CastExpr>(expr)) {
+    result = doCastExpr(castExpr);
+  } else if (const auto *initListExpr = dyn_cast<InitListExpr>(expr)) {
+    result = doInitListExpr(initListExpr);
+  } else if (const auto *boolLiteral = dyn_cast<CXXBoolLiteralExpr>(expr)) {
     const auto value = theBuilder.getConstantBool(boolLiteral->getValue());
-    return SpirvEvalInfo(value).setConstant().setRValue();
-  }
-
-  if (const auto *intLiteral = dyn_cast<IntegerLiteral>(expr)) {
+    result = SpirvEvalInfo(value).setConstant().setRValue();
+  } else if (const auto *intLiteral = dyn_cast<IntegerLiteral>(expr)) {
     const auto value = translateAPInt(intLiteral->getValue(), expr->getType());
-    return SpirvEvalInfo(value).setConstant().setRValue();
-  }
-
-  if (const auto *floatLiteral = dyn_cast<FloatingLiteral>(expr)) {
+    result = SpirvEvalInfo(value).setConstant().setRValue();
+  } else if (const auto *floatLiteral = dyn_cast<FloatingLiteral>(expr)) {
     const auto value =
         translateAPFloat(floatLiteral->getValue(), expr->getType());
-    return SpirvEvalInfo(value).setConstant().setRValue();
-  }
-
-  // CompoundAssignOperator is a subclass of BinaryOperator. It should be
-  // checked before BinaryOperator.
-  if (const auto *compoundAssignOp = dyn_cast<CompoundAssignOperator>(expr)) {
-    return doCompoundAssignOperator(compoundAssignOp);
-  }
-
-  if (const auto *binOp = dyn_cast<BinaryOperator>(expr)) {
-    return doBinaryOperator(binOp);
-  }
-
-  if (const auto *unaryOp = dyn_cast<UnaryOperator>(expr)) {
-    return doUnaryOperator(unaryOp);
-  }
-
-  if (const auto *vecElemExpr = dyn_cast<HLSLVectorElementExpr>(expr)) {
-    return doHLSLVectorElementExpr(vecElemExpr);
-  }
-
-  if (const auto *matElemExpr = dyn_cast<ExtMatrixElementExpr>(expr)) {
-    return doExtMatrixElementExpr(matElemExpr);
-  }
-
-  if (const auto *funcCall = dyn_cast<CallExpr>(expr)) {
-    return doCallExpr(funcCall);
-  }
-
-  if (const auto *subscriptExpr = dyn_cast<ArraySubscriptExpr>(expr)) {
-    return doArraySubscriptExpr(subscriptExpr);
-  }
-
-  if (const auto *condExpr = dyn_cast<ConditionalOperator>(expr)) {
-    return doConditionalOperator(condExpr);
-  }
-
-  if (const auto *defaultArgExpr = dyn_cast<CXXDefaultArgExpr>(expr)) {
-    return doExpr(defaultArgExpr->getParam()->getDefaultArg());
-  }
-
-  if (isa<CXXThisExpr>(expr)) {
+    result = SpirvEvalInfo(value).setConstant().setRValue();
+  } else if (const auto *compoundAssignOp =
+                 dyn_cast<CompoundAssignOperator>(expr)) {
+    // CompoundAssignOperator is a subclass of BinaryOperator. It should be
+    // checked before BinaryOperator.
+    result = doCompoundAssignOperator(compoundAssignOp);
+  } else if (const auto *binOp = dyn_cast<BinaryOperator>(expr)) {
+    result = doBinaryOperator(binOp);
+  } else if (const auto *unaryOp = dyn_cast<UnaryOperator>(expr)) {
+    result = doUnaryOperator(unaryOp);
+  } else if (const auto *vecElemExpr = dyn_cast<HLSLVectorElementExpr>(expr)) {
+    result = doHLSLVectorElementExpr(vecElemExpr);
+  } else if (const auto *matElemExpr = dyn_cast<ExtMatrixElementExpr>(expr)) {
+    result = doExtMatrixElementExpr(matElemExpr);
+  } else if (const auto *funcCall = dyn_cast<CallExpr>(expr)) {
+    result = doCallExpr(funcCall);
+  } else if (const auto *subscriptExpr = dyn_cast<ArraySubscriptExpr>(expr)) {
+    result = doArraySubscriptExpr(subscriptExpr);
+  } else if (const auto *condExpr = dyn_cast<ConditionalOperator>(expr)) {
+    result = doConditionalOperator(condExpr);
+  } else if (const auto *defaultArgExpr = dyn_cast<CXXDefaultArgExpr>(expr)) {
+    result = doExpr(defaultArgExpr->getParam()->getDefaultArg());
+  } else if (isa<CXXThisExpr>(expr)) {
     assert(curThis);
-    return curThis;
+    result = curThis;
+  } else {
+    emitError("expression class '%0' unimplemented", expr->getExprLoc())
+        << expr->getStmtClassName() << expr->getSourceRange();
   }
 
-  emitError("expression class '%0' unimplemented", expr->getExprLoc())
-      << expr->getStmtClassName() << expr->getSourceRange();
-  return 0;
+  if (isNonLiteralType)
+    typeTranslator.popIntendedLiteralType();
+
+  return result;
 }
 
 SpirvEvalInfo SPIRVEmitter::loadIfGLValue(const Expr *expr,
@@ -4703,7 +4695,7 @@ uint32_t SPIRVEmitter::castToInt(const uint32_t fromVal, QualType fromType,
   uint32_t intType = typeTranslator.translateType(toIntType);
 
   // AST may include a 'literal int' to 'int' conversion. No-op.
-  if (fromType->isLiteralType(astContext) && fromType->isIntegerType() &&
+  if (fromType->isSpecificBuiltinType(BuiltinType::LitInt) &&
       typeTranslator.translateType(fromType) == intType)
     return fromVal;
 
@@ -6624,37 +6616,39 @@ uint32_t SPIRVEmitter::getMatElemValueOne(QualType type) {
 
 uint32_t SPIRVEmitter::translateAPValue(const APValue &value,
                                         const QualType targetType) {
-  if (targetType->isBooleanType()) {
-    const bool boolValue = value.getInt().getBoolValue();
-    return theBuilder.getConstantBool(boolValue);
-  }
+  uint32_t result = 0;
+  const bool isNonLiteralType = !isLiteralType(targetType);
 
-  if (targetType->isIntegerType()) {
-    const llvm::APInt &intValue = value.getInt();
-    return translateAPInt(intValue, targetType);
-  }
+  if (isNonLiteralType)
+    typeTranslator.pushIntendedLiteralType(targetType);
 
-  if (targetType->isFloatingType()) {
-    return translateAPFloat(value.getFloat(), targetType);
-  }
-
-  if (hlsl::IsHLSLVecType(targetType)) {
+  if (targetType->isBooleanType()) {
+    result = theBuilder.getConstantBool(value.getInt().getBoolValue());
+  } else if (targetType->isIntegerType()) {
+    result = translateAPInt(value.getInt(), targetType);
+  } else if (targetType->isFloatingType()) {
+    result = translateAPFloat(value.getFloat(), targetType);
+  } else if (hlsl::IsHLSLVecType(targetType)) {
     const uint32_t vecType = typeTranslator.translateType(targetType);
     const QualType elemType = hlsl::GetHLSLVecElementType(targetType);
-
     const auto numElements = value.getVectorLength();
     // Special case for vectors of size 1. SPIR-V doesn't support this vector
     // size so we need to translate it to scalar values.
     if (numElements == 1) {
-      return translateAPValue(value.getVectorElt(0), elemType);
-    }
-
-    llvm::SmallVector<uint32_t, 4> elements;
-    for (uint32_t i = 0; i < numElements; ++i) {
-      elements.push_back(translateAPValue(value.getVectorElt(i), elemType));
+      result = translateAPValue(value.getVectorElt(0), elemType);
+    } else {
+      llvm::SmallVector<uint32_t, 4> elements;
+      for (uint32_t i = 0; i < numElements; ++i) {
+        elements.push_back(translateAPValue(value.getVectorElt(i), elemType));
+      }
+      result = theBuilder.getConstantComposite(vecType, elements);
     }
+  }
 
-    return theBuilder.getConstantComposite(vecType, elements);
+  if (result) {
+    if (isNonLiteralType)
+      typeTranslator.popIntendedLiteralType();
+    return result;
   }
 
   emitError("APValue of type %0 unimplemented", {}) << value.getKind();
@@ -6664,6 +6658,7 @@ uint32_t SPIRVEmitter::translateAPValue(const APValue &value,
 
 uint32_t SPIRVEmitter::translateAPInt(const llvm::APInt &intValue,
                                       QualType targetType) {
+  targetType = typeTranslator.getIntendedLiteralType(targetType);
   if (targetType->isSignedIntegerType()) {
     // Try to see if this integer can be represented in 32-bit.
     if (intValue.isSignedIntN(32)) {
@@ -6723,6 +6718,7 @@ uint32_t SPIRVEmitter::tryToEvaluateAsFloat32(const llvm::APFloat &floatValue) {
 
 uint32_t SPIRVEmitter::translateAPFloat(const llvm::APFloat &floatValue,
                                         QualType targetType) {
+  targetType = typeTranslator.getIntendedLiteralType(targetType);
   const auto &semantics = astContext.getFloatTypeSemantics(targetType);
   const auto bitwidth = llvm::APFloat::getSizeInBits(semantics);
   switch (bitwidth) {

+ 47 - 8
tools/clang/lib/SPIRV/TypeTranslator.cpp

@@ -108,6 +108,31 @@ bool TypeTranslator::isOpaqueStructType(QualType type) {
   return false;
 }
 
+void TypeTranslator::pushIntendedLiteralType(QualType type) {
+  QualType elemType = {};
+  if (isVectorType(type, &elemType)) {
+    type = elemType;
+  } else if (isMxNMatrix(type, &elemType)) {
+    type = elemType;
+  }
+  assert(!type->isSpecificBuiltinType(BuiltinType::LitInt) &&
+         !type->isSpecificBuiltinType(BuiltinType::LitFloat));
+  intendedLiteralTypes.push(type);
+}
+
+QualType TypeTranslator::getIntendedLiteralType(QualType type) {
+  if (!intendedLiteralTypes.empty())
+    return intendedLiteralTypes.top();
+
+  // We don't have any useful hints, return the given type itself.
+  return type;
+}
+
+void TypeTranslator::popIntendedLiteralType() {
+  if (!intendedLiteralTypes.empty())
+    intendedLiteralTypes.pop();
+}
+
 uint32_t TypeTranslator::translateType(QualType type, LayoutRule rule,
                                        bool isRowMajor) {
   // We can only apply row_major to matrices or arrays of matrices.
@@ -122,21 +147,21 @@ uint32_t TypeTranslator::translateType(QualType type, LayoutRule rule,
   // Primitive types
   {
     QualType ty = {};
-    if (isScalarType(type, &ty))
-      if (const auto *builtinType = ty->getAs<BuiltinType>())
+    if (isScalarType(type, &ty)) {
+      if (const auto *builtinType = ty->getAs<BuiltinType>()) {
         switch (builtinType->getKind()) {
         case BuiltinType::Void:
           return theBuilder.getVoidType();
         case BuiltinType::Bool:
           return theBuilder.getBoolType();
-        // int, min16int (short), and min12int are all translated to 32-bit
-        // signed integers in SPIR-V.
+          // int, min16int (short), and min12int are all translated to 32-bit
+          // signed integers in SPIR-V.
         case BuiltinType::Int:
         case BuiltinType::Short:
         case BuiltinType::Min12Int:
           return theBuilder.getInt32Type();
-        // uint and min16uint (ushort) are both translated to 32-bit unsigned
-        // integers in SPIR-V.
+          // uint and min16uint (ushort) are both translated to 32-bit unsigned
+          // integers in SPIR-V.
         case BuiltinType::UShort:
         case BuiltinType::UInt:
           return theBuilder.getUint32Type();
@@ -144,8 +169,8 @@ uint32_t TypeTranslator::translateType(QualType type, LayoutRule rule,
           return theBuilder.getInt64Type();
         case BuiltinType::ULongLong:
           return theBuilder.getUint64Type();
-        // float, min16float (half), and min10float are all translated to 32-bit
-        // float in SPIR-V.
+          // float, min16float (half), and min10float are all translated to
+          // 32-bit float in SPIR-V.
         case BuiltinType::Float:
         case BuiltinType::Half:
         case BuiltinType::Min10Float:
@@ -153,6 +178,12 @@ uint32_t TypeTranslator::translateType(QualType type, LayoutRule rule,
         case BuiltinType::Double:
           return theBuilder.getFloat64Type();
         case BuiltinType::LitFloat: {
+          // First try to see if there are any hints about how this literal type
+          // is going to be used. If so, use the hint.
+          if (getIntendedLiteralType(ty) != ty) {
+            return translateType(getIntendedLiteralType(ty));
+          }
+
           const auto &semantics = astContext.getFloatTypeSemantics(type);
           const auto bitwidth = llvm::APFloat::getSizeInBits(semantics);
           if (bitwidth <= 32)
@@ -161,6 +192,12 @@ uint32_t TypeTranslator::translateType(QualType type, LayoutRule rule,
             return theBuilder.getFloat64Type();
         }
         case BuiltinType::LitInt: {
+          // First try to see if there are any hints about how this literal type
+          // is going to be used. If so, use the hint.
+          if (getIntendedLiteralType(ty) != ty) {
+            return translateType(getIntendedLiteralType(ty));
+          }
+
           const auto bitwidth = astContext.getIntWidth(type);
           // All integer variants with bitwidth larger than 32 are represented
           // as 64-bit int in SPIR-V.
@@ -178,6 +215,8 @@ uint32_t TypeTranslator::translateType(QualType type, LayoutRule rule,
               << builtinType->getTypeClassName();
           return 0;
         }
+      }
+    }
   }
 
   // Typedefs

+ 21 - 0
tools/clang/lib/SPIRV/TypeTranslator.h

@@ -230,10 +230,31 @@ public:
                                                     bool isRowMajor,
                                                     uint32_t *stride);
 
+public:
+  /// \brief Adds the given type to the intendedLiteralTypes stack. This will be
+  /// used as a hint regarding usage of literal types.
+  void pushIntendedLiteralType(QualType type);
+
+  /// \brief If a hint exists regarding the usage of literal types, it
+  /// is returned. Otherwise, the given type itself is returned.
+  /// The hint is the type on top of the intendedLiteralTypes stack. This is the
+  /// type we suspect the literal under question should be interpreted as.
+  QualType getIntendedLiteralType(QualType type);
+
+  /// \brief Removes the type at the top of the intendedLiteralTypes stack.
+  void popIntendedLiteralType();
+
 private:
   ASTContext &astContext;
   ModuleBuilder &theBuilder;
   DiagnosticsEngine &diags;
+
+  /// \brief This is a stack which is used to track the intended usage type for
+  /// literals. For example: while a floating literal is being visited, if the
+  /// top of the stack is a float type, the literal should be evaluated as
+  /// float; but if the top of the stack is a double type, the literal should be
+  /// evaluated as a double.
+  std::stack<QualType> intendedLiteralTypes;
 };
 
 } // end namespace spirv

+ 23 - 25
tools/clang/test/CodeGenSPIRV/bezier.hull.hlsl2spv

@@ -176,7 +176,7 @@ BEZIER_CONTROL_POINT SubDToBezierHS(InputPatch<VS_CONTROL_POINT_OUTPUT, MAX_POIN
 // %95 = OpTypeFunction %HS_CONSTANT_DATA_OUTPUT %_ptr_Function__arr_VS_CONTROL_POINT_OUTPUT_uint_3 %_ptr_Function_uint
 // %_ptr_Function_HS_CONSTANT_DATA_OUTPUT = OpTypePointer Function %HS_CONSTANT_DATA_OUTPUT
 // %_ptr_Function_float = OpTypePointer Function %float
-// %120 = OpTypeFunction %BEZIER_CONTROL_POINT %_ptr_Function__arr_VS_CONTROL_POINT_OUTPUT_uint_3 %_ptr_Function_uint %_ptr_Function_uint
+// %118 = OpTypeFunction %BEZIER_CONTROL_POINT %_ptr_Function__arr_VS_CONTROL_POINT_OUTPUT_uint_3 %_ptr_Function_uint %_ptr_Function_uint
 // %_ptr_Function_VS_CONTROL_POINT_OUTPUT = OpTypePointer Function %VS_CONTROL_POINT_OUTPUT
 // %_ptr_Function_BEZIER_CONTROL_POINT = OpTypePointer Function %BEZIER_CONTROL_POINT
 // %_ptr_Function_v3float = OpTypePointer Function %v3float
@@ -184,12 +184,10 @@ BEZIER_CONTROL_POINT SubDToBezierHS(InputPatch<VS_CONTROL_POINT_OUTPUT, MAX_POIN
 // %float_1 = OpConstant %float 1
 // %int_0 = OpConstant %int 0
 // %float_2 = OpConstant %float 2
-// %int_1 = OpConstant %int 1
 // %float_3 = OpConstant %float 3
-// %int_2 = OpConstant %int 2
 // %float_4 = OpConstant %float 4
-// %int_3 = OpConstant %int 3
 // %float_5 = OpConstant %float 5
+// %int_1 = OpConstant %int 1
 // %float_6 = OpConstant %float 6
 // %gl_PerVertexIn = OpVariable %_ptr_Input__arr_type_gl_PerVertex_uint_3 Input
 // %gl_PerVertexOut = OpVariable %_ptr_Output__arr_type_gl_PerVertex_uint_3 Output
@@ -265,32 +263,32 @@ BEZIER_CONTROL_POINT SubDToBezierHS(InputPatch<VS_CONTROL_POINT_OUTPUT, MAX_POIN
 // %PatchID = OpFunctionParameter %_ptr_Function_uint
 // %bb_entry = OpLabel
 // %Output = OpVariable %_ptr_Function_HS_CONSTANT_DATA_OUTPUT Function
-// %105 = OpAccessChain %_ptr_Function_float %Output %int_0 %int_0
+// %105 = OpAccessChain %_ptr_Function_float %Output %int_0 %uint_0
 // OpStore %105 %float_1
-// %108 = OpAccessChain %_ptr_Function_float %Output %int_0 %int_1
-// OpStore %108 %float_2
-// %111 = OpAccessChain %_ptr_Function_float %Output %int_0 %int_2
-// OpStore %111 %float_3
-// %114 = OpAccessChain %_ptr_Function_float %Output %int_0 %int_3
-// OpStore %114 %float_4
-// %116 = OpAccessChain %_ptr_Function_float %Output %int_1 %int_0
-// OpStore %116 %float_5
-// %118 = OpAccessChain %_ptr_Function_float %Output %int_1 %int_1
-// OpStore %118 %float_6
-// %119 = OpLoad %HS_CONSTANT_DATA_OUTPUT %Output
-// OpReturnValue %119
+// %107 = OpAccessChain %_ptr_Function_float %Output %int_0 %uint_1
+// OpStore %107 %float_2
+// %109 = OpAccessChain %_ptr_Function_float %Output %int_0 %uint_2
+// OpStore %109 %float_3
+// %111 = OpAccessChain %_ptr_Function_float %Output %int_0 %uint_3
+// OpStore %111 %float_4
+// %114 = OpAccessChain %_ptr_Function_float %Output %int_1 %uint_0
+// OpStore %114 %float_5
+// %116 = OpAccessChain %_ptr_Function_float %Output %int_1 %uint_1
+// OpStore %116 %float_6
+// %117 = OpLoad %HS_CONSTANT_DATA_OUTPUT %Output
+// OpReturnValue %117
 // OpFunctionEnd
-// %src_SubDToBezierHS = OpFunction %BEZIER_CONTROL_POINT None %120
+// %src_SubDToBezierHS = OpFunction %BEZIER_CONTROL_POINT None %118
 // %ip_0 = OpFunctionParameter %_ptr_Function__arr_VS_CONTROL_POINT_OUTPUT_uint_3
 // %cpid = OpFunctionParameter %_ptr_Function_uint
 // %PatchID_0 = OpFunctionParameter %_ptr_Function_uint
 // %bb_entry_0 = OpLabel
 // %vsOutput = OpVariable %_ptr_Function_VS_CONTROL_POINT_OUTPUT Function
 // %result = OpVariable %_ptr_Function_BEZIER_CONTROL_POINT Function
-// %130 = OpAccessChain %_ptr_Function_v3float %vsOutput %int_0
-// %131 = OpLoad %v3float %130
-// %132 = OpAccessChain %_ptr_Function_v3float %result %int_0
-// OpStore %132 %131
-// %133 = OpLoad %BEZIER_CONTROL_POINT %result
-// OpReturnValue %133
-// OpFunctionEnd
+// %128 = OpAccessChain %_ptr_Function_v3float %vsOutput %int_0
+// %129 = OpLoad %v3float %128
+// %130 = OpAccessChain %_ptr_Function_v3float %result %int_0
+// OpStore %130 %129
+// %131 = OpLoad %BEZIER_CONTROL_POINT %result
+// OpReturnValue %131
+// OpFunctionEnd

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

@@ -74,7 +74,7 @@ void main(uint index: A) {
     BufferType lbuf;                  // %BufferType_0                   & %SubBuffer_1
     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 %uint_0
 // CHECK-NEXT: [[cbuf_d0:%\d+]] = OpLoad %SubBuffer_0 [[ptr]]
 
     // sub.a[0] <- cbuf.d[0].a[0]

+ 1 - 1
tools/clang/test/CodeGenSPIRV/cs.groupshared.hlsl

@@ -20,7 +20,7 @@ groupshared              S        s;
 void main(uint2 tid : SV_DispatchThreadID, uint2 gid : SV_GroupID) {
 // Make sure pointers have the correct storage class
 // CHECK:    {{%\d+}} = OpAccessChain %_ptr_Workgroup_float %s %int_0
-// CHECK: [[d0:%\d+]] = OpAccessChain %_ptr_Workgroup_v2float %d %int_0
+// CHECK: [[d0:%\d+]] = OpAccessChain %_ptr_Workgroup_v2float %d %uint_0
 // CHECK:    {{%\d+}} = OpAccessChain %_ptr_Workgroup_float [[d0]] %int_1
     d[0].y = s.f1;
 }

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

@@ -49,7 +49,7 @@ float4 main() : A {
 // CHECK-NEXT: [[prev:%\d+]] = OpAtomicISub %int [[counter]] %uint_1 %uint_0 %int_1
 // CHECK-NEXT: [[index:%\d+]] = OpISub %int [[prev]] %int_1
 // CHECK-NEXT: [[buffer3:%\d+]] = OpAccessChain %_ptr_Uniform_T %buffer3 %uint_0 [[index]]
-// CHECK-NEXT: [[ac:%\d+]] = OpAccessChain %_ptr_Uniform_v3float [[buffer3]] %int_0 %int_3 %int_1
+// CHECK-NEXT: [[ac:%\d+]] = OpAccessChain %_ptr_Uniform_v3float [[buffer3]] %int_0 %uint_3 %int_1
 // CHECK-NEXT: [[val:%\d+]] = OpLoad %v3float [[ac]]
 // CHECK-NEXT: OpStore %val [[val]]
     float3 val = buffer3.Consume().s[3].b;

+ 1 - 1
tools/clang/test/CodeGenSPIRV/method.structured-buffer.load.hlsl

@@ -31,7 +31,7 @@ float4 main(int index: A) : SV_Target {
 // CHECK-NEXT: {{%\d+}} = OpLoad %float [[x]]
 
 // CHECK:      [[index:%\d+]] = OpLoad %int %index
-// CHECK-NEXT: [[f012:%\d+]] = OpAccessChain %_ptr_Uniform_float %mySBuffer2 %int_0 [[index]] %int_1 %int_0 %uint_1 %uint_2
+// CHECK-NEXT: [[f012:%\d+]] = OpAccessChain %_ptr_Uniform_float %mySBuffer2 %int_0 [[index]] %int_1 %uint_0 %uint_1 %uint_2
 // CHECK-NEXT: {{%\d+}} = OpLoad %float [[f012]]
     return mySBuffer1.Load(5).f1.x + mySBuffer2.Load(index).f2[0][1][2];
 }

+ 6 - 6
tools/clang/test/CodeGenSPIRV/op.array.access.hlsl

@@ -17,32 +17,32 @@ float main(float val: A, uint index: B) : C {
 
 // CHECK:       [[val:%\d+]] = OpLoad %float %val
 // CHECK-NEXT:  [[idx:%\d+]] = OpLoad %uint %index
-// CHECK-NEXT: [[ptr0:%\d+]] = OpAccessChain %_ptr_Function_float %var [[idx]] %int_1 %int_0 %int_2
+// CHECK-NEXT: [[ptr0:%\d+]] = OpAccessChain %_ptr_Function_float %var [[idx]] %uint_1 %int_0 %uint_2
 // CHECK-NEXT:                 OpStore [[ptr0]] [[val]]
 
     var[index][1].f[2] = val;
 // CHECK-NEXT: [[idx0:%\d+]] = OpLoad %uint %index
 // CHECK-NEXT: [[idx1:%\d+]] = OpLoad %uint %index
-// CHECK:      [[ptr0:%\d+]] = OpAccessChain %_ptr_Function_float %var %int_0 [[idx0]] %int_1 [[idx1]]
+// CHECK:      [[ptr0:%\d+]] = OpAccessChain %_ptr_Function_float %var %uint_0 [[idx0]] %int_1 [[idx1]]
 // CHECK-NEXT: [[load:%\d+]] = OpLoad %float [[ptr0]]
 // CHECK-NEXT:                 OpStore %r [[load]]
     r = var[0][index].g[index];
 
 // CHECK:       [[val:%\d+]] = OpLoad %float %val
 // CHECK-NEXT: [[vec2:%\d+]] = OpCompositeConstruct %v2float [[val]] [[val]]
-// CHECK-NEXT: [[ptr0:%\d+]] = OpAccessChain %_ptr_Function_v4float %vecvar %int_3
+// CHECK-NEXT: [[ptr0:%\d+]] = OpAccessChain %_ptr_Function_v4float %vecvar %uint_3
 // CHECK-NEXT: [[vec4:%\d+]] = OpLoad %v4float [[ptr0]]
 // CHECK-NEXT:  [[res:%\d+]] = OpVectorShuffle %v4float [[vec4]] [[vec2]] 0 1 5 4
 // CHECK-NEXT:                 OpStore [[ptr0]] [[res]]
     vecvar[3].ab = val;
-// CHECK-NEXT: [[ptr2:%\d+]] = OpAccessChain %_ptr_Function_float %vecvar %int_2 %uint_1
+// CHECK-NEXT: [[ptr2:%\d+]] = OpAccessChain %_ptr_Function_float %vecvar %uint_2 %uint_1
 // CHECK-NEXT: [[load:%\d+]] = OpLoad %float [[ptr2]]
 // CHECK-NEXT:                 OpStore %r [[load]]
     r = vecvar[2][1];
 
 // CHECK:       [[val:%\d+]] = OpLoad %float %val
 // CHECK-NEXT: [[vec2:%\d+]] = OpCompositeConstruct %v2float [[val]] [[val]]
-// CHECK-NEXT: [[ptr0:%\d+]] = OpAccessChain %_ptr_Function_mat2v3float %matvar %int_2
+// CHECK-NEXT: [[ptr0:%\d+]] = OpAccessChain %_ptr_Function_mat2v3float %matvar %uint_2
 // CHECK-NEXT: [[val0:%\d+]] = OpCompositeExtract %float [[vec2]] 0
 // CHECK-NEXT: [[ptr1:%\d+]] = OpAccessChain %_ptr_Function_float [[ptr0]] %int_0 %int_1
 // CHECK-NEXT:                 OpStore [[ptr1]] [[val0]]
@@ -50,7 +50,7 @@ float main(float val: A, uint index: B) : C {
 // CHECK-NEXT: [[ptr2:%\d+]] = OpAccessChain %_ptr_Function_float [[ptr0]] %int_1 %int_2
 // CHECK-NEXT:                 OpStore [[ptr2]] [[val1]]
     matvar[2]._12_23 = val;
-// CHECK-NEXT: [[ptr4:%\d+]] = OpAccessChain %_ptr_Function_float %matvar %int_0 %uint_1 %uint_2
+// CHECK-NEXT: [[ptr4:%\d+]] = OpAccessChain %_ptr_Function_float %matvar %uint_0 %uint_1 %uint_2
 // CHECK-NEXT: [[load:%\d+]] = OpLoad %float [[ptr4]]
 // CHECK-NEXT:                 OpStore %r [[load]]
     r = matvar[0][1][2];

+ 1 - 1
tools/clang/test/CodeGenSPIRV/op.cbuffer.access.hlsl

@@ -29,7 +29,7 @@ float main() : A {
 // CHECK-NEXT: {{%\d+}} = OpLoad %float [[s0]]
 
 // CHECK:      [[t:%\d+]] = OpAccessChain %_ptr_Uniform__arr_float_uint_4 %var_MyCbuffer %int_4
-// CHECK-NEXT: [[t3:%\d+]] = OpAccessChain %_ptr_Uniform_float [[t]] %int_3
+// CHECK-NEXT: [[t3:%\d+]] = OpAccessChain %_ptr_Uniform_float [[t]] %uint_3
 // CHECK-NEXT: {{%\d+}} = OpLoad %float [[t3]]
     return a + b.x + c[1][2] + s.f + t[3];
 }

+ 1 - 1
tools/clang/test/CodeGenSPIRV/op.constant-buffer.access.hlsl

@@ -29,7 +29,7 @@ float main() : A {
 // CHECK:      [[s:%\d+]] = OpAccessChain %_ptr_Uniform_float %MyCbuffer %int_3 %int_0
 // CHECK-NEXT: {{%\d+}} = OpLoad %float [[s]]
 
-// CHECK:      [[t:%\d+]] = OpAccessChain %_ptr_Uniform_float %MyCbuffer %int_4 %int_3
+// CHECK:      [[t:%\d+]] = OpAccessChain %_ptr_Uniform_float %MyCbuffer %int_4 %uint_3
 // CHECK-NEXT: {{%\d+}} = OpLoad %float [[t]]
     return MyCbuffer.a + MyCbuffer.b.x + MyCbuffer.c[1][2] + MyCbuffer.s.f + MyCbuffer.t[3];
 }

+ 6 - 6
tools/clang/test/CodeGenSPIRV/op.rw-structured-buffer.access.hlsl

@@ -16,26 +16,26 @@ struct T {
 RWStructuredBuffer<T> MySbuffer;
 
 void main(uint index: A) {
-// CHECK:      [[c12:%\d+]] = OpAccessChain %_ptr_Uniform_float %MySbuffer %int_0 %uint_2 %int_2 %int_2 %uint_1 %uint_2
+// CHECK:      [[c12:%\d+]] = OpAccessChain %_ptr_Uniform_float %MySbuffer %int_0 %uint_2 %int_2 %uint_2 %uint_1 %uint_2
 // CHECK-NEXT: {{%\d+}} = OpLoad %float [[c12]]
 
-// CHECK:      [[s:%\d+]] = OpAccessChain %_ptr_Uniform_float %MySbuffer %int_0 %uint_3 %int_3 %int_0 %int_0
+// CHECK:      [[s:%\d+]] = OpAccessChain %_ptr_Uniform_float %MySbuffer %int_0 %uint_3 %int_3 %uint_0 %int_0
 // CHECK-NEXT: {{%\d+}} = OpLoad %float [[s]]
     float val = MySbuffer[2].c[2][1][2] + MySbuffer[3].s[0].f;
 
 // CHECK:       [[val:%\d+]] = OpLoad %float %val
 // CHECK-NEXT:  [[index:%\d+]] = OpLoad %uint %index
 
-// CHECK-NEXT:  [[t3:%\d+]] = OpAccessChain %_ptr_Uniform_float %MySbuffer %int_0 [[index]] %int_4 %int_3
+// CHECK-NEXT:  [[t3:%\d+]] = OpAccessChain %_ptr_Uniform_float %MySbuffer %int_0 [[index]] %int_4 %uint_3
 // CHECK-NEXT:  OpStore [[t3]] [[val]]
 
-// CHECK:       [[f:%\d+]] = OpAccessChain %_ptr_Uniform_float %MySbuffer %int_0 %uint_3 %int_3 %int_0 %int_0
+// CHECK:       [[f:%\d+]] = OpAccessChain %_ptr_Uniform_float %MySbuffer %int_0 %uint_3 %int_3 %uint_0 %int_0
 // CHECK-NEXT:  OpStore [[f]] [[val]]
 
-// CHECK-NEXT:  [[c212:%\d+]] = OpAccessChain %_ptr_Uniform_float %MySbuffer %int_0 %uint_2 %int_2 %int_2 %uint_1 %uint_2
+// CHECK-NEXT:  [[c212:%\d+]] = OpAccessChain %_ptr_Uniform_float %MySbuffer %int_0 %uint_2 %int_2 %uint_2 %uint_1 %uint_2
 // CHECK-NEXT:  OpStore [[c212]] [[val]]
 
-// CHECK-NEXT:  [[b1:%\d+]] = OpAccessChain %_ptr_Uniform_v2float %MySbuffer %int_0 %uint_1 %int_1 %int_1
+// CHECK-NEXT:  [[b1:%\d+]] = OpAccessChain %_ptr_Uniform_v2float %MySbuffer %int_0 %uint_1 %int_1 %uint_1
 // CHECK-NEXT:  [[x:%\d+]] = OpAccessChain %_ptr_Uniform_float [[b1]] %int_0
 // CHECK-NEXT:  OpStore [[x]] [[val]]
 

+ 4 - 4
tools/clang/test/CodeGenSPIRV/op.structured-buffer.access.hlsl

@@ -19,18 +19,18 @@ float4 main(uint index: A) : SV_Target {
 // CHECK:      [[a:%\d+]] = OpAccessChain %_ptr_Uniform_float %MySbuffer %int_0 %uint_0 %int_0
 // CHECK-NEXT: {{%\d+}} = OpLoad %float [[a]]
 
-// CHECK:      [[b1:%\d+]] = OpAccessChain %_ptr_Uniform_v2float %MySbuffer %int_0 %uint_1 %int_1 %int_1
+// CHECK:      [[b1:%\d+]] = OpAccessChain %_ptr_Uniform_v2float %MySbuffer %int_0 %uint_1 %int_1 %uint_1
 // CHECK-NEXT: [[x:%\d+]] = OpAccessChain %_ptr_Uniform_float [[b1]] %int_0
 // CHECK-NEXT: {{%\d+}} = OpLoad %float [[x]]
 
-// CHECK:      [[c12:%\d+]] = OpAccessChain %_ptr_Uniform_float %MySbuffer %int_0 %uint_2 %int_2 %int_2 %uint_1 %uint_2
+// CHECK:      [[c12:%\d+]] = OpAccessChain %_ptr_Uniform_float %MySbuffer %int_0 %uint_2 %int_2 %uint_2 %uint_1 %uint_2
 // CHECK-NEXT: {{%\d+}} = OpLoad %float [[c12]]
 
-// CHECK:      [[s:%\d+]] = OpAccessChain %_ptr_Uniform_float %MySbuffer %int_0 %uint_3 %int_3 %int_0 %int_0
+// CHECK:      [[s:%\d+]] = OpAccessChain %_ptr_Uniform_float %MySbuffer %int_0 %uint_3 %int_3 %uint_0 %int_0
 // CHECK-NEXT: {{%\d+}} = OpLoad %float [[s]]
 
 // CHECK:      [[index:%\d+]] = OpLoad %uint %index
-// CHECK-NEXT: [[t:%\d+]] = OpAccessChain %_ptr_Uniform_float %MySbuffer %int_0 [[index]] %int_4 %int_3
+// CHECK-NEXT: [[t:%\d+]] = OpAccessChain %_ptr_Uniform_float %MySbuffer %int_0 [[index]] %int_4 %uint_3
 // CHECK-NEXT: {{%\d+}} = OpLoad %float [[t]]
     return MySbuffer[0].a + MySbuffer[1].b[1].x + MySbuffer[2].c[2][1][2] +
            MySbuffer[3].s[0].f + MySbuffer[index].t[3];

+ 1 - 1
tools/clang/test/CodeGenSPIRV/op.tbuffer.access.hlsl

@@ -29,7 +29,7 @@ float main() : A {
 // CHECK-NEXT: {{%\d+}} = OpLoad %float [[s0]]
 
 // CHECK:      [[t:%\d+]] = OpAccessChain %_ptr_Uniform__arr_float_uint_4 %var_MyTbuffer %int_4
-// CHECK-NEXT: [[t3:%\d+]] = OpAccessChain %_ptr_Uniform_float [[t]] %int_3
+// CHECK-NEXT: [[t3:%\d+]] = OpAccessChain %_ptr_Uniform_float [[t]] %uint_3
 // CHECK-NEXT: {{%\d+}} = OpLoad %float [[t3]]
     return a + b.x + c[1][2] + s.f + t[3];
 }

+ 1 - 1
tools/clang/test/CodeGenSPIRV/op.texture-buffer.access.hlsl

@@ -29,7 +29,7 @@ float main() : A {
 // CHECK:      [[s:%\d+]] = OpAccessChain %_ptr_Uniform_float %MyTB %int_3 %int_0
 // CHECK-NEXT: {{%\d+}} = OpLoad %float [[s]]
 
-// CHECK:      [[t:%\d+]] = OpAccessChain %_ptr_Uniform_float %MyTB %int_4 %int_3
+// CHECK:      [[t:%\d+]] = OpAccessChain %_ptr_Uniform_float %MyTB %int_4 %uint_3
 // CHECK-NEXT: {{%\d+}} = OpLoad %float [[t]]
   return MyTB.a + MyTB.b.x + MyTB.c[1][2] + MyTB.s.f + MyTB.t[3];
 }

+ 4 - 4
tools/clang/test/CodeGenSPIRV/var.init.array.hlsl

@@ -67,19 +67,19 @@ void main() {
     T2 val2[2] = {val1};
 
 // val3[0]: Construct T3.h from T1.c.b[0]
-// CHECK-NEXT:     [[b_0:%\d+]] = OpAccessChain %_ptr_Function_v2float %val1 %int_0 %int_0 %int_0 %uint_0
+// CHECK-NEXT:     [[b_0:%\d+]] = OpAccessChain %_ptr_Function_v2float %val1 %uint_0 %int_0 %int_0 %uint_0
 // CHECK-NEXT:   [[h_val:%\d+]] = OpLoad %v2float [[b_0]]
 
 // val3[0]: Construct T3.i from T1.c.b[1]
-// CHECK-NEXT:     [[b_1:%\d+]] = OpAccessChain %_ptr_Function_v2float %val1 %int_0 %int_0 %int_0 %uint_1
+// CHECK-NEXT:     [[b_1:%\d+]] = OpAccessChain %_ptr_Function_v2float %val1 %uint_0 %int_0 %int_0 %uint_1
 // CHECK-NEXT:   [[i_val:%\d+]] = OpLoad %v2float [[b_1]]
 
 // val3[0]: Construct T3.j from T1.d.b[0]
-// CHECK-NEXT:     [[b_0:%\d+]] = OpAccessChain %_ptr_Function_v2float %val1 %int_0 %int_1 %int_0 %uint_0
+// CHECK-NEXT:     [[b_0:%\d+]] = OpAccessChain %_ptr_Function_v2float %val1 %uint_0 %int_1 %int_0 %uint_0
 // CHECK-NEXT:   [[j_val:%\d+]] = OpLoad %v2float [[b_0]]
 
 // val3[0]: Construct T3.k from T1.d.b[1]
-// CHECK-NEXT:     [[b_1:%\d+]] = OpAccessChain %_ptr_Function_v2float %val1 %int_0 %int_1 %int_0 %uint_1
+// CHECK-NEXT:     [[b_1:%\d+]] = OpAccessChain %_ptr_Function_v2float %val1 %uint_0 %int_1 %int_0 %uint_1
 // CHECK-NEXT:   [[k_val:%\d+]] = OpLoad %v2float [[b_1]]
 
 // CHECK-NEXT:  [[val3_0:%\d+]] = OpCompositeConstruct %T3 [[h_val]] [[i_val]] [[j_val]] [[k_val]]

+ 1 - 1
tools/clang/test/CodeGenSPIRV/vk.push-constant.hlsl

@@ -32,7 +32,7 @@ float main() : A {
         pcs.f2.z +
 // CHECK:     {{%\d+}} = OpAccessChain %_ptr_PushConstant_float %pcs %int_2 %uint_1 %uint_2
         pcs.f3[1][2] +
-// CHECK: [[ptr:%\d+]] = OpAccessChain %_ptr_PushConstant_v2float %pcs %int_3 %int_0 %int_2
+// CHECK: [[ptr:%\d+]] = OpAccessChain %_ptr_PushConstant_v2float %pcs %int_3 %int_0 %uint_2
 // CHECK:     {{%\d+}} = OpAccessChain %_ptr_PushConstant_float [[ptr]] %int_1
         pcs.f4.val[2].y;
 }