2
0
Эх сурвалжийг харах

Merge fixes to release branch (#3611)

Cherry-pick changes to release branch:
cd3ef21b8 Roll back llvm::ArrayRef dependency in ExecutionTest (#3613)
2791c5197 Generate descriptions for resources with no names (#3598)
22fa20938 Fix LifetimeIntrinsicTest issues (#3609)
203961019 Fix Dxil validator compat and test issues (#3610)
220e88456 Rename payload qualifier field to not match type (#3607)
0e892065b Correct exception handler sprintf for 32-bit (#3608)
9b475a7fa Add dxc exception handler (#3604)
e8372b9b9 Fixed arg pairs not correct for old source in module pdbs (#3599)
2bda44fc0 Add constant evaluation for clamp() (#3581)
640c9af74 Added way for caller to replace args in PDB utils (#3595)
de00b014a Fix const error check for object subscript operator (#3580)
Tex Riddell 4 жил өмнө
parent
commit
3d5e8b9f6c
39 өөрчлөгдсөн 912 нэмэгдсэн , 306 устгасан
  1. 4 0
      include/dxc/Support/FileIOHelper.h
  2. 1 0
      include/dxc/Support/HLSLOptions.h
  3. 2 0
      include/dxc/Support/HLSLOptions.td
  4. 7 0
      include/dxc/dxcapi.h
  5. 2 2
      include/llvm/Support/ErrorHandling.h
  6. 2 1
      lib/DXIL/DxilShaderFlags.cpp
  7. 8 0
      lib/DxcSupport/FileIOHelper.cpp
  8. 2 0
      lib/DxcSupport/HLSLOptions.cpp
  9. 46 5
      lib/HLSL/DxilValidation.cpp
  10. 92 0
      tools/clang/lib/CodeGen/CGHLSLMSFinishCodeGen.cpp
  11. 5 5
      tools/clang/lib/Sema/SemaDXR.cpp
  12. 4 1
      tools/clang/lib/Sema/SemaExpr.cpp
  13. 2 2
      tools/clang/test/HLSL/array-index-out-of-bounds-HV-2016.hlsl
  14. 52 52
      tools/clang/test/HLSL/attributes.hlsl
  15. 13 13
      tools/clang/test/HLSL/builtin-types-no-inheritance.hlsl
  16. 6 6
      tools/clang/test/HLSL/conversions-non-numeric-aggregates.hlsl
  17. 7 7
      tools/clang/test/HLSL/incomp_array_err.hlsl
  18. 214 28
      tools/clang/test/HLSL/indexing-operator.hlsl
  19. 14 0
      tools/clang/test/HLSLFileCheck/hlsl/intrinsics/basic/clamp_const_prop.hlsl
  20. 2 2
      tools/clang/test/HLSLFileCheck/hlsl/intrinsics/helper/IsHelperLane.hlsl
  21. 4 3
      tools/clang/test/HLSLFileCheck/hlsl/intrinsics/pixel/attr/attributeAtVertex.hlsl
  22. 4 3
      tools/clang/test/HLSLFileCheck/hlsl/intrinsics/pixel/attr/attributeAtVertexNoOpt.hlsl
  23. 1 1
      tools/clang/test/HLSLFileCheck/hlsl/lifetimes/lifetimes_lib_6_3.hlsl
  24. 1 1
      tools/clang/test/HLSLFileCheck/hlsl/objects/CbufferLegacy/cbufferSize1.hlsl
  25. 1 1
      tools/clang/test/HLSLFileCheck/hlsl/objects/CbufferLegacy/cbufferSize3.hlsl
  26. 1 1
      tools/clang/test/HLSLFileCheck/hlsl/objects/CbufferLegacy/cbufferSize5.hlsl
  27. 1 1
      tools/clang/test/HLSLFileCheck/hlsl/objects/CbufferLegacy/cbufferSize6.hlsl
  28. 4 3
      tools/clang/test/HLSLFileCheck/hlsl/semantics/sv_barycentrics/barycentrics.hlsl
  29. 4 3
      tools/clang/test/HLSLFileCheck/hlsl/semantics/sv_barycentrics/barycentrics1.hlsl
  30. 1 1
      tools/clang/test/HLSLFileCheck/hlsl/types/conversions/semantics_Mod.hlsl
  31. 9 9
      tools/clang/test/HLSLFileCheck/hlsl/types/modifiers/groupshared/groupshared_shadermodels.hlsl
  32. 1 1
      tools/clang/test/HLSLFileCheck/validation/rawbufferstore_uav.hlsl
  33. 59 0
      tools/clang/tools/dxclib/dxc.cpp
  34. 168 112
      tools/clang/tools/dxcompiler/dxcpdbutils.cpp
  35. 64 0
      tools/clang/unittests/HLSL/CompilerTest.cpp
  36. 3 0
      tools/clang/unittests/HLSL/DxilModuleTest.cpp
  37. 86 38
      tools/clang/unittests/HLSL/ExecutionTest.cpp
  38. 1 0
      tools/clang/unittests/HLSL/LinkerTest.cpp
  39. 14 4
      utils/hct/VerifierHelper.py

+ 4 - 0
include/dxc/Support/FileIOHelper.h

@@ -190,6 +190,10 @@ HRESULT DxcCreateBlobWithEncodingFromPinned(
     _In_bytecount_(size) LPCVOID pText, UINT32 size, UINT32 codePage,
     _In_bytecount_(size) LPCVOID pText, UINT32 size, UINT32 codePage,
     _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) throw();
     _COM_Outptr_ IDxcBlobEncoding **pBlobEncoding) throw();
 
 
+HRESULT DxcCreateBlobFromPinned(
+    _In_bytecount_(size) LPCVOID pText, UINT32 size,
+    _COM_Outptr_ IDxcBlob **pBlob) throw();
+
 HRESULT
 HRESULT
 DxcCreateBlobWithEncodingFromStream(
 DxcCreateBlobWithEncodingFromStream(
     IStream *pStream, bool newInstanceAlways, UINT32 codePage,
     IStream *pStream, bool newInstanceAlways, UINT32 codePage,

+ 1 - 0
include/dxc/Support/HLSLOptions.h

@@ -201,6 +201,7 @@ public:
 
 
   bool PrintAfterAll; // OPT_print_after_all
   bool PrintAfterAll; // OPT_print_after_all
   bool EnablePayloadQualifiers = false; // OPT_enable_payload_qualifiers
   bool EnablePayloadQualifiers = false; // OPT_enable_payload_qualifiers
+  bool HandleExceptions = false; // OPT_disable_exception_handling
 
 
   // Rewriter Options
   // Rewriter Options
   RewriterOpts RWOpt;
   RewriterOpts RWOpt;

+ 2 - 0
include/dxc/Support/HLSLOptions.td

@@ -281,6 +281,8 @@ def enable_payload_qualifiers : Flag<["-", "/"], "enable-payload-qualifiers">, G
   HelpText<"Enables support for payload access qualifiers for raytracing payloads in SM 6.6.">;
   HelpText<"Enables support for payload access qualifiers for raytracing payloads in SM 6.6.">;
 def disable_payload_qualifiers : Flag<["-", "/"], "disable-payload-qualifiers">, Group<hlslcomp_Group>, Flags<[CoreOption, RewriteOption, DriverOption]>,
 def disable_payload_qualifiers : Flag<["-", "/"], "disable-payload-qualifiers">, Group<hlslcomp_Group>, Flags<[CoreOption, RewriteOption, DriverOption]>,
   HelpText<"Disables support for payload access qualifiers for raytracing payloads in SM 6.7.">;
   HelpText<"Disables support for payload access qualifiers for raytracing payloads in SM 6.7.">;
+def disable_exception_handling : Flag<["-", "/"], "disable-exception-handling">, Group<hlslcomp_Group>, Flags<[DriverOption, HelpHidden]>,
+  HelpText<"Disable dxc handling of exceptions">;
 
 
 // Used with API only
 // Used with API only
 def skip_serialization : Flag<["-", "/"], "skip-serialization">, Group<hlslcore_Group>, Flags<[CoreOption, HelpHidden]>,
 def skip_serialization : Flag<["-", "/"], "skip-serialization">, Group<hlslcore_Group>, Flags<[CoreOption, HelpHidden]>,

+ 7 - 0
include/dxc/dxcapi.h

@@ -582,6 +582,11 @@ struct IDxcVersionInfo3 : public IUnknown {
   ) = 0;
   ) = 0;
 };
 };
 
 
+struct DxcArgPair {
+  const WCHAR *pName;
+  const WCHAR *pValue;
+};
+
 CROSS_PLATFORM_UUIDOF(IDxcPdbUtils, "E6C9647E-9D6A-4C3B-B94C-524B5A6C343D")
 CROSS_PLATFORM_UUIDOF(IDxcPdbUtils, "E6C9647E-9D6A-4C3B-B94C-524B5A6C343D")
 struct IDxcPdbUtils : public IUnknown {
 struct IDxcPdbUtils : public IUnknown {
   virtual HRESULT STDMETHODCALLTYPE Load(_In_ IDxcBlob *pPdbOrDxil) = 0;
   virtual HRESULT STDMETHODCALLTYPE Load(_In_ IDxcBlob *pPdbOrDxil) = 0;
@@ -616,6 +621,8 @@ struct IDxcPdbUtils : public IUnknown {
 
 
   virtual HRESULT STDMETHODCALLTYPE SetCompiler(_In_ IDxcCompiler3 *pCompiler) = 0;
   virtual HRESULT STDMETHODCALLTYPE SetCompiler(_In_ IDxcCompiler3 *pCompiler) = 0;
   virtual HRESULT STDMETHODCALLTYPE CompileForFullPDB(_COM_Outptr_ IDxcResult **ppResult) = 0;
   virtual HRESULT STDMETHODCALLTYPE CompileForFullPDB(_COM_Outptr_ IDxcResult **ppResult) = 0;
+  virtual HRESULT STDMETHODCALLTYPE OverrideArgs(_In_ DxcArgPair *pArgPairs, UINT32 uNumArgPairs) = 0;
+  virtual HRESULT STDMETHODCALLTYPE OverrideRootSignature(_In_ const WCHAR *pRootSignature) = 0;
 };
 };
 
 
 // Note: __declspec(selectany) requires 'extern'
 // Note: __declspec(selectany) requires 'extern'

+ 2 - 2
include/llvm/Support/ErrorHandling.h

@@ -97,8 +97,8 @@ namespace llvm {
 #ifndef NDEBUG
 #ifndef NDEBUG
 #define llvm_unreachable(msg) \
 #define llvm_unreachable(msg) \
   ::llvm::llvm_unreachable_internal(msg, __FILE__, __LINE__)
   ::llvm::llvm_unreachable_internal(msg, __FILE__, __LINE__)
-#elif defined(LLVM_BUILTIN_UNREACHABLE)
-#define llvm_unreachable(msg) LLVM_BUILTIN_UNREACHABLE
+//#elif defined(LLVM_BUILTIN_UNREACHABLE) // HLSL Change - always throw exception for unreachable
+//#define llvm_unreachable(msg) LLVM_BUILTIN_UNREACHABLE
 #else
 #else
 #define llvm_unreachable(msg) ::llvm::llvm_unreachable_internal()
 #define llvm_unreachable(msg) ::llvm::llvm_unreachable_internal()
 #endif
 #endif

+ 2 - 1
lib/DXIL/DxilShaderFlags.cpp

@@ -373,6 +373,7 @@ ShaderFlags ShaderFlags::CollectShaderFlags(const Function *F,
   M->GetValidatorVersion(valMajor, valMinor);
   M->GetValidatorVersion(valMajor, valMinor);
   bool hasMulticomponentUAVLoadsBackCompat = valMajor == 1 && valMinor == 0;
   bool hasMulticomponentUAVLoadsBackCompat = valMajor == 1 && valMinor == 0;
   bool hasViewportOrRTArrayIndexBackCombat = valMajor == 1 && valMinor < 4;
   bool hasViewportOrRTArrayIndexBackCombat = valMajor == 1 && valMinor < 4;
+  bool hasBarycentricsBackCompat = valMajor == 1 && valMinor < 6;
 
 
   Type *int16Ty = Type::getInt16Ty(F->getContext());
   Type *int16Ty = Type::getInt16Ty(F->getContext());
   Type *int64Ty = Type::getInt64Ty(F->getContext());
   Type *int64Ty = Type::getInt64Ty(F->getContext());
@@ -630,7 +631,7 @@ ShaderFlags ShaderFlags::CollectShaderFlags(const Function *F,
   flag.SetViewID(hasViewID);
   flag.SetViewID(hasViewID);
   flag.SetViewportAndRTArrayIndex(hasViewportOrRTArrayIndex);
   flag.SetViewportAndRTArrayIndex(hasViewportOrRTArrayIndex);
   flag.SetShadingRate(hasShadingRate);
   flag.SetShadingRate(hasShadingRate);
-  flag.SetBarycentrics(hasBarycentrics);
+  flag.SetBarycentrics(hasBarycentricsBackCompat ? false : hasBarycentrics);
   flag.SetSamplerFeedback(hasSamplerFeedback);
   flag.SetSamplerFeedback(hasSamplerFeedback);
   flag.SetRaytracingTier1_1(hasRaytracingTier1_1);
   flag.SetRaytracingTier1_1(hasRaytracingTier1_1);
   flag.SetAtomicInt64OnTypedResource(hasAtomicInt64OnTypedResource);
   flag.SetAtomicInt64OnTypedResource(hasAtomicInt64OnTypedResource);

+ 8 - 0
lib/DxcSupport/FileIOHelper.cpp

@@ -778,6 +778,14 @@ HRESULT DxcCreateBlobWithEncodingFromPinned(LPCVOID pText, UINT32 size,
   return DxcCreateBlob(pText, size, true, false, true, codePage, nullptr, pBlobEncoding);
   return DxcCreateBlob(pText, size, true, false, true, codePage, nullptr, pBlobEncoding);
 }
 }
 
 
+HRESULT DxcCreateBlobFromPinned(
+    _In_bytecount_(size) LPCVOID pText, UINT32 size,
+    _COM_Outptr_ IDxcBlob **pBlob) throw() {
+  CComPtr<IDxcBlobEncoding> pBlobEncoding;
+  DxcCreateBlob(pText, size, true, false, false, CP_ACP, nullptr, &pBlobEncoding);
+  return pBlobEncoding.QueryInterface(pBlob);
+}
+
 _Use_decl_annotations_
 _Use_decl_annotations_
 HRESULT
 HRESULT
 DxcCreateBlobWithEncodingFromStream(IStream *pStream, bool newInstanceAlways,
 DxcCreateBlobWithEncodingFromStream(IStream *pStream, bool newInstanceAlways,

+ 2 - 0
lib/DxcSupport/HLSLOptions.cpp

@@ -663,6 +663,8 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
     return 1;
     return 1;
   }
   }
 
 
+  opts.HandleExceptions = !Args.hasFlag(OPT_disable_exception_handling, OPT_INVALID, false);
+
   if (opts.DefaultColMajor && opts.DefaultRowMajor) {
   if (opts.DefaultColMajor && opts.DefaultRowMajor) {
     errors << "Cannot specify /Zpr and /Zpc together, use /? to get usage information";
     errors << "Cannot specify /Zpr and /Zpc together, use /? to get usage information";
     return 1;
     return 1;

+ 46 - 5
lib/HLSL/DxilValidation.cpp

@@ -687,8 +687,49 @@ struct ValidationContext {
     Failed = true;
     Failed = true;
   }
   }
 
 
+  // Use this instead of DxilResourceBase::GetGlobalName
+  std::string GetResourceName(const hlsl::DxilResourceBase *Res) {
+    if (!Res)
+      return "nullptr";
+    std::string resName = Res->GetGlobalName();
+    if (!resName.empty())
+      return resName;
+    if (pDebugModule) {
+      DxilModule &DM = pDebugModule->GetOrCreateDxilModule();
+      switch (Res->GetClass()) {
+      case DXIL::ResourceClass::CBuffer:  return DM.GetCBuffer(Res->GetID()).GetGlobalName();
+      case DXIL::ResourceClass::Sampler:  return DM.GetSampler(Res->GetID()).GetGlobalName();
+      case DXIL::ResourceClass::SRV:      return DM.GetSRV(Res->GetID()).GetGlobalName();
+      case DXIL::ResourceClass::UAV:      return DM.GetUAV(Res->GetID()).GetGlobalName();
+      default: return "Invalid Resource";
+      }
+    }
+    // When names have been stripped, use class and binding location to
+    // identify the resource.  Format is roughly:
+    // Allocated:   (CB|T|U|S)<ID>: <ResourceKind> ((cb|t|u|s)<LB>[<RangeSize>] space<SpaceID>)
+    // Unallocated: (CB|T|U|S)<ID>: <ResourceKind> (no bind location)
+    // Example: U0: TypedBuffer (u5[2] space1)
+    // [<RangeSize>] and space<SpaceID> skipped if 1 and 0 respectively.
+    return (Twine(Res->GetResIDPrefix()) + Twine(Res->GetID()) + ": " +
+            Twine(Res->GetResKindName()) +
+            (Res->IsAllocated()
+                 ? (" (" + Twine(Res->GetResBindPrefix()) +
+                    Twine(Res->GetLowerBound()) +
+                    (Res->IsUnbounded()
+                         ? Twine("[unbounded]")
+                         : (Res->GetRangeSize() != 1)
+                               ? "[" + Twine(Res->GetRangeSize()) + "]"
+                               : Twine()) +
+                    ((Res->GetSpaceID() != 0)
+                         ? " space" + Twine(Res->GetSpaceID())
+                         : Twine()) +
+                    ")")
+                 : Twine(" (no bind location)")))
+        .str();
+  }
+
   void EmitResourceError(const hlsl::DxilResourceBase *Res, ValidationRule rule) {
   void EmitResourceError(const hlsl::DxilResourceBase *Res, ValidationRule rule) {
-    std::string QuotedRes = " '" + Res->GetGlobalName() + "'";
+    std::string QuotedRes = " '" + GetResourceName(Res) + "'";
     dxilutil::EmitErrorOnContext(M.getContext(), GetValidationRuleText(rule) + QuotedRes);
     dxilutil::EmitErrorOnContext(M.getContext(), GetValidationRuleText(rule) + QuotedRes);
     Failed = true;
     Failed = true;
   }
   }
@@ -696,7 +737,7 @@ struct ValidationContext {
   void EmitResourceFormatError(const hlsl::DxilResourceBase *Res,
   void EmitResourceFormatError(const hlsl::DxilResourceBase *Res,
                                ValidationRule rule,
                                ValidationRule rule,
                                ArrayRef<StringRef> args) {
                                ArrayRef<StringRef> args) {
-    std::string QuotedRes = " '" + Res->GetGlobalName() + "'";
+    std::string QuotedRes = " '" + GetResourceName(Res) + "'";
     std::string ruleText = GetValidationRuleText(rule);
     std::string ruleText = GetValidationRuleText(rule);
     FormatRuleText(ruleText, args);
     FormatRuleText(ruleText, args);
     dxilutil::EmitErrorOnContext(M.getContext(), ruleText + QuotedRes);
     dxilutil::EmitErrorOnContext(M.getContext(), ruleText + QuotedRes);
@@ -3996,7 +4037,7 @@ static void ValidateResourceOverlap(
   if (conflictRes) {
   if (conflictRes) {
     ValCtx.EmitFormatError(
     ValCtx.EmitFormatError(
         ValidationRule::SmResourceRangeOverlap,
         ValidationRule::SmResourceRangeOverlap,
-        {res.GetGlobalName(), std::to_string(base),
+        {ValCtx.GetResourceName(&res), std::to_string(base),
          std::to_string(size),
          std::to_string(size),
          std::to_string(conflictRes->GetLowerBound()),
          std::to_string(conflictRes->GetLowerBound()),
          std::to_string(conflictRes->GetRangeSize()),
          std::to_string(conflictRes->GetRangeSize()),
@@ -4208,7 +4249,7 @@ static void ValidateCBuffer(DxilCBuffer &cb, ValidationContext &ValCtx) {
       DXIL::kMaxCBufferSize << 4);
       DXIL::kMaxCBufferSize << 4);
   CollectCBufferRanges(annotation, constAllocator,
   CollectCBufferRanges(annotation, constAllocator,
                        0, typeSys,
                        0, typeSys,
-                       cb.GetGlobalName(), ValCtx);
+                       ValCtx.GetResourceName(&cb), ValCtx);
 }
 }
 
 
 static void ValidateResources(ValidationContext &ValCtx) {
 static void ValidateResources(ValidationContext &ValCtx) {
@@ -4240,7 +4281,7 @@ static void ValidateResources(ValidationContext &ValCtx) {
     if (uav->HasCounter() && uav->IsGloballyCoherent())
     if (uav->HasCounter() && uav->IsGloballyCoherent())
       ValCtx.EmitResourceFormatError(uav.get(),
       ValCtx.EmitResourceFormatError(uav.get(),
                                      ValidationRule::MetaGlcNotOnAppendConsume,
                                      ValidationRule::MetaGlcNotOnAppendConsume,
-                                     {uav.get()->GetGlobalName()});
+                                     {ValCtx.GetResourceName(uav.get())});
 
 
     ValidateResource(*uav, ValCtx);
     ValidateResource(*uav, ValCtx);
     ValidateResourceOverlap(*uav, uavAllocator, ValCtx);
     ValidateResourceOverlap(*uav, uavAllocator, ValCtx);

+ 92 - 0
tools/clang/lib/CodeGen/CGHLSLMSFinishCodeGen.cpp

@@ -1460,6 +1460,10 @@ typedef APInt(__cdecl *IntBinaryEvalFuncType)(const APInt &, const APInt &);
 typedef float(__cdecl *FloatBinaryEvalFuncType)(float, float);
 typedef float(__cdecl *FloatBinaryEvalFuncType)(float, float);
 typedef double(__cdecl *DoubleBinaryEvalFuncType)(double, double);
 typedef double(__cdecl *DoubleBinaryEvalFuncType)(double, double);
 
 
+typedef APInt(__cdecl *IntTernaryEvalFuncType)(const APInt &, const APInt &, const APInt &);
+typedef float(__cdecl *FloatTernaryEvalFuncType)(float, float, float);
+typedef double(__cdecl *DoubleTernaryEvalFuncType)(double, double, double);
+
 Value *EvalUnaryIntrinsic(ConstantFP *fpV, FloatUnaryEvalFuncType floatEvalFunc,
 Value *EvalUnaryIntrinsic(ConstantFP *fpV, FloatUnaryEvalFuncType floatEvalFunc,
                           DoubleUnaryEvalFuncType doubleEvalFunc) {
                           DoubleUnaryEvalFuncType doubleEvalFunc) {
   llvm::Type *Ty = fpV->getType();
   llvm::Type *Ty = fpV->getType();
@@ -1510,6 +1514,45 @@ Value *EvalBinaryIntrinsic(Constant *cV0, Constant *cV1,
   return Result;
   return Result;
 }
 }
 
 
+Value *EvalTernaryIntrinsic(Constant *cV0, Constant *cV1, Constant *cV2,
+                             FloatTernaryEvalFuncType floatEvalFunc,
+                             DoubleTernaryEvalFuncType doubleEvalFunc,
+                             IntTernaryEvalFuncType intEvalFunc) {
+  llvm::Type *Ty = cV0->getType();
+  Value *Result = nullptr;
+  if (Ty->isDoubleTy()) {
+    ConstantFP *fpV0 = cast<ConstantFP>(cV0);
+    ConstantFP *fpV1 = cast<ConstantFP>(cV1);
+    ConstantFP *fpV2 = cast<ConstantFP>(cV2);
+    double dV0 = fpV0->getValueAPF().convertToDouble();
+    double dV1 = fpV1->getValueAPF().convertToDouble();
+    double dV2 = fpV2->getValueAPF().convertToDouble();
+    Value *dResult = ConstantFP::get(Ty, doubleEvalFunc(dV0, dV1, dV2));
+    Result = dResult;
+  } else if (Ty->isFloatTy()) {
+    ConstantFP *fpV0 = cast<ConstantFP>(cV0);
+    ConstantFP *fpV1 = cast<ConstantFP>(cV1);
+    ConstantFP *fpV2 = cast<ConstantFP>(cV2);
+    float fV0 = fpV0->getValueAPF().convertToFloat();
+    float fV1 = fpV1->getValueAPF().convertToFloat();
+    float fV2 = fpV2->getValueAPF().convertToFloat();
+    Value *dResult = ConstantFP::get(Ty, floatEvalFunc(fV0, fV1, fV2));
+    Result = dResult;
+  } else {
+    DXASSERT_NOMSG(Ty->isIntegerTy());
+    DXASSERT_NOMSG(intEvalFunc);
+    ConstantInt *ciV0 = cast<ConstantInt>(cV0);
+    ConstantInt *ciV1 = cast<ConstantInt>(cV1);
+    ConstantInt *ciV2 = cast<ConstantInt>(cV2);
+    const APInt &iV0 = ciV0->getValue();
+    const APInt &iV1 = ciV1->getValue();
+    const APInt &iV2 = ciV2->getValue();
+    Value *dResult = ConstantInt::get(Ty, intEvalFunc(iV0, iV1, iV2));
+    Result = dResult;
+  }
+  return Result;
+}
+
 Value *EvalUnaryIntrinsic(CallInst *CI, FloatUnaryEvalFuncType floatEvalFunc,
 Value *EvalUnaryIntrinsic(CallInst *CI, FloatUnaryEvalFuncType floatEvalFunc,
                           DoubleUnaryEvalFuncType doubleEvalFunc) {
                           DoubleUnaryEvalFuncType doubleEvalFunc) {
   Value *V = CI->getArgOperand(0);
   Value *V = CI->getArgOperand(0);
@@ -1566,6 +1609,43 @@ Value *EvalBinaryIntrinsic(CallInst *CI, FloatBinaryEvalFuncType floatEvalFunc,
   return Result;
   return Result;
 }
 }
 
 
+Value *EvalTernaryIntrinsic(CallInst *CI, FloatTernaryEvalFuncType floatEvalFunc,
+                             DoubleTernaryEvalFuncType doubleEvalFunc,
+                             IntTernaryEvalFuncType intEvalFunc = nullptr) {
+  Value *V0 = CI->getArgOperand(0);
+  Value *V1 = CI->getArgOperand(1);
+  Value *V2 = CI->getArgOperand(2);
+  llvm::Type *Ty = CI->getType();
+  Value *Result = nullptr;
+  if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(Ty)) {
+    Result = UndefValue::get(Ty);
+    Constant *CV0 = cast<Constant>(V0);
+    Constant *CV1 = cast<Constant>(V1);
+    Constant *CV2 = cast<Constant>(V2);
+    IRBuilder<> Builder(CI);
+    for (unsigned i = 0; i < VT->getNumElements(); i++) {
+      Constant *cV0 = cast<Constant>(CV0->getAggregateElement(i));
+      Constant *cV1 = cast<Constant>(CV1->getAggregateElement(i));
+      Constant *cV2 = cast<Constant>(CV2->getAggregateElement(i));
+      Value *EltResult = EvalTernaryIntrinsic(cV0, cV1, cV2, floatEvalFunc,
+                                             doubleEvalFunc, intEvalFunc);
+      Result = Builder.CreateInsertElement(Result, EltResult, i);
+    }
+  } else {
+    Constant *cV0 = cast<Constant>(V0);
+    Constant *cV1 = cast<Constant>(V1);
+    Constant *cV2 = cast<Constant>(V2);
+    Result = EvalTernaryIntrinsic(cV0, cV1, cV2, floatEvalFunc, doubleEvalFunc,
+                                 intEvalFunc);
+  }
+  CI->replaceAllUsesWith(Result);
+  CI->eraseFromParent();
+  return Result;
+
+  CI->eraseFromParent();
+  return Result;
+}
+
 void SimpleTransformForHLDXIRInst(Instruction *I, SmallInstSet &deadInsts) {
 void SimpleTransformForHLDXIRInst(Instruction *I, SmallInstSet &deadInsts) {
 
 
   unsigned opcode = I->getOpcode();
   unsigned opcode = I->getOpcode();
@@ -1789,6 +1869,18 @@ Value *TryEvalIntrinsic(CallInst *CI, IntrinsicOp intriOp,
     CI->eraseFromParent();
     CI->eraseFromParent();
     return cNan;
     return cNan;
   } break;
   } break;
+  case IntrinsicOp::IOP_clamp: {
+    auto clampF = [](float a, float b, float c) {
+      return a < b ? b : a > c ? c : a;
+    };
+    auto clampD = [](double a, double b, double c) {
+      return a < b ? b : a > c ? c : a;
+    };
+    auto clampI = [](const APInt &a, const APInt &b, const APInt &c) -> APInt {
+      return a.slt(b) ? b : a.sgt(c) ? c : a;
+    };
+    return EvalTernaryIntrinsic(CI, clampF, clampD, clampI);
+  } break;
   default:
   default:
     return nullptr;
     return nullptr;
   }
   }

+ 5 - 5
tools/clang/lib/Sema/SemaDXR.cpp

@@ -67,7 +67,7 @@ struct PayloadAccessInfo {
 };
 };
 
 
 struct DxrShaderDiagnoseInfo {
 struct DxrShaderDiagnoseInfo {
-  const FunctionDecl *FunctionDecl;
+  const FunctionDecl *funcDecl;
   const VarDecl *Payload;
   const VarDecl *Payload;
   DXIL::PayloadAccessShaderStage Stage;
   DXIL::PayloadAccessShaderStage Stage;
   std::vector<TraceRayCall> TraceCalls;
   std::vector<TraceRayCall> TraceCalls;
@@ -689,7 +689,7 @@ DiagnosePayloadAsFunctionArg(
       }
       }
 
 
       if (CalleeInfo.Payload) {
       if (CalleeInfo.Payload) {
-        CalleeInfo.FunctionDecl = CalledFunction;
+        CalleeInfo.funcDecl = CalledFunction;
         CalleeInfo.Stage = Info.Stage;
         CalleeInfo.Stage = Info.Stage;
         auto FieldsToIgnoreRead = CollectDominatingWritesForCall(Use, Info, DT);
         auto FieldsToIgnoreRead = CollectDominatingWritesForCall(Use, Info, DT);
         auto FieldsToIgnoreWrite = CollectReachableWritesForCall(Use, Info);
         auto FieldsToIgnoreWrite = CollectReachableWritesForCall(Use, Info);
@@ -925,7 +925,7 @@ DiagnosePayloadAccess(Sema &S, DxrShaderDiagnoseInfo &Info,
   clang::DominatorTree DT;
   clang::DominatorTree DT;
   AnalysisDeclContextManager AnalysisManager;
   AnalysisDeclContextManager AnalysisManager;
   AnalysisDeclContext *AnalysisContext =
   AnalysisDeclContext *AnalysisContext =
-      AnalysisManager.getContext(Info.FunctionDecl);
+      AnalysisManager.getContext(Info.funcDecl);
 
 
   CFG &TheCFG = *AnalysisContext->getCFG();
   CFG &TheCFG = *AnalysisContext->getCFG();
   DT.buildDominatorTree(*AnalysisContext);
   DT.buildDominatorTree(*AnalysisContext);
@@ -1093,7 +1093,7 @@ public:
         DiagnosePayloadParameter(S, Payload, Decl, Stage);
         DiagnosePayloadParameter(S, Payload, Decl, Stage);
       }
       }
       DxrShaderDiagnoseInfo Info;
       DxrShaderDiagnoseInfo Info;
-      Info.FunctionDecl = Decl;
+      Info.funcDecl = Decl;
       Info.Payload = Payload;
       Info.Payload = Payload;
       Info.Stage = Stage;
       Info.Stage = Stage;
 
 
@@ -1116,4 +1116,4 @@ void DiagnoseRaytracingPayloadAccess(clang::Sema &S,
   visitor.diagnose(TU);
   visitor.diagnose(TU);
 }
 }
 
 
-} // namespace hlsl
+} // namespace hlsl

+ 4 - 1
tools/clang/lib/Sema/SemaExpr.cpp

@@ -9460,7 +9460,10 @@ bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) { // HLSL Ch
   assert(!E->hasPlaceholderType(BuiltinType::PseudoObject));
   assert(!E->hasPlaceholderType(BuiltinType::PseudoObject));
   // HLSL Change Starts - check const for array subscript operator for HLSL vector/matrix
   // HLSL Change Starts - check const for array subscript operator for HLSL vector/matrix
   if (S.Context.getLangOpts().HLSL && E->getStmtClass() == Stmt::CXXOperatorCallExprClass) {
   if (S.Context.getLangOpts().HLSL && E->getStmtClass() == Stmt::CXXOperatorCallExprClass) {
-      // check if it's a vector or matrix
+    // check if it's a vector or matrix
+    const CXXOperatorCallExpr *expr = cast<CXXOperatorCallExpr>(E);
+    QualType qt = expr->getArg(0)->getType();
+    if ((hlsl::IsMatrixType(&S, qt) || hlsl::IsVectorType(&S, qt)))
       return HLSLCheckForModifiableLValue(E, Loc, S);
       return HLSLCheckForModifiableLValue(E, Loc, S);
   }
   }
   // HLSL Change Ends
   // HLSL Change Ends

+ 2 - 2
tools/clang/test/HLSL/array-index-out-of-bounds-HV-2016.hlsl

@@ -3,10 +3,10 @@
 void dead()
 void dead()
 {
 {
     int array[2];
     int array[2];
-    array[-1] = 0;                                          /* expected-warning {{array index -1 is before the beginning of the array}} fxc-pass */
+    array[-1] = 0;                                          /* expected-warning {{array index -1 is before the beginning of the array}} fxc-pass {{}} */
     array[0] = 0;
     array[0] = 0;
     array[1] = 0;
     array[1] = 0;
-    array[2] = 0;                                           /* expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}} fxc-pass */
+    array[2] = 0;                                           /* expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}} fxc-pass {{}} */
 }
 }
 
 
 void main() {}
 void main() {}

+ 52 - 52
tools/clang/test/HLSL/attributes.hlsl

@@ -20,13 +20,13 @@ int loop_before_return() {
 }
 }
 
 
 int loop_before_if(int a) {
 int loop_before_if(int a) {
-  [loop] // expected-warning {{attribute 'loop' can only be applied to 'for', 'while' and 'do' loop statements}}
+  [loop] // expected-warning {{attribute 'loop' can only be applied to 'for', 'while' and 'do' loop statements}} fxc-pass {{}}
   if (a > 0) return -a;
   if (a > 0) return -a;
   return a;
   return a;
 }
 }
 
 
 int loop_before_switch(int a) {
 int loop_before_switch(int a) {
-  [loop] // expected-warning {{attribute 'loop' can only be applied to 'for', 'while' and 'do' loop statements}}
+  [loop] // expected-warning {{attribute 'loop' can only be applied to 'for', 'while' and 'do' loop statements}} fxc-pass {{}}
   switch (a) {
   switch (a) {
     case 0:
     case 0:
       return 1;
       return 1;
@@ -36,13 +36,13 @@ int loop_before_switch(int a) {
 }
 }
 
 
 int fastopt_before_if(int a) {
 int fastopt_before_if(int a) {
-  [fastopt] // expected-warning {{attribute 'fastopt' can only be applied to 'for', 'while' and 'do' loop statements}}
+  [fastopt] // expected-warning {{attribute 'fastopt' can only be applied to 'for', 'while' and 'do' loop statements}} fxc-pass {{}}
   if (a > 0) return -a;
   if (a > 0) return -a;
   return a;
   return a;
 }
 }
 
 
 int fastopt_before_switch(int a) {
 int fastopt_before_switch(int a) {
-  [fastopt] // expected-warning {{attribute 'fastopt' can only be applied to 'for', 'while' and 'do' loop statements}}
+  [fastopt] // expected-warning {{attribute 'fastopt' can only be applied to 'for', 'while' and 'do' loop statements}} fxc-pass {{}}
   switch (a) {
   switch (a) {
     case 0:
     case 0:
       return 1;
       return 1;
@@ -52,13 +52,13 @@ int fastopt_before_switch(int a) {
 }
 }
 
 
 int unroll_before_if(int a) {
 int unroll_before_if(int a) {
-  [unroll] // expected-warning {{attribute 'unroll' can only be applied to 'for', 'while' and 'do' loop statements}}
+  [unroll] // expected-warning {{attribute 'unroll' can only be applied to 'for', 'while' and 'do' loop statements}} fxc-pass {{}}
   if (a > 0) return -a;
   if (a > 0) return -a;
   return a;
   return a;
 }
 }
 
 
 int unroll_before_switch(int a) {
 int unroll_before_switch(int a) {
-  [unroll] // expected-warning {{attribute 'unroll' can only be applied to 'for', 'while' and 'do' loop statements}}
+  [unroll] // expected-warning {{attribute 'unroll' can only be applied to 'for', 'while' and 'do' loop statements}} fxc-pass {{}}
   switch (a) {
   switch (a) {
     case 0:
     case 0:
       return 1;
       return 1;
@@ -68,13 +68,13 @@ int unroll_before_switch(int a) {
 }
 }
 
 
 int allow_uav_condition_before_if(int a) {
 int allow_uav_condition_before_if(int a) {
-  [allow_uav_condition] // expected-warning {{attribute 'allow_uav_condition' can only be applied to 'for', 'while' and 'do' loop statements}}
+  [allow_uav_condition] // expected-warning {{attribute 'allow_uav_condition' can only be applied to 'for', 'while' and 'do' loop statements}} fxc-pass {{}}
   if (a > 0) return -a;
   if (a > 0) return -a;
   return a;
   return a;
 }
 }
 
 
 int allow_uav_condition_before_switch(int a) {
 int allow_uav_condition_before_switch(int a) {
-  [allow_uav_condition] // expected-warning {{attribute 'allow_uav_condition' can only be applied to 'for', 'while' and 'do' loop statements}}
+  [allow_uav_condition] // expected-warning {{attribute 'allow_uav_condition' can only be applied to 'for', 'while' and 'do' loop statements}} fxc-pass {{}}
   switch (a) {
   switch (a) {
     case 0:
     case 0:
       return 1;
       return 1;
@@ -85,7 +85,7 @@ int allow_uav_condition_before_switch(int a) {
 
 
 int branch_before_for() {
 int branch_before_for() {
   int result = 0;
   int result = 0;
-  [branch] // expected-warning {{attribute 'branch' can only be applied to 'if' and 'switch' statements}}
+  [branch] // expected-warning {{attribute 'branch' can only be applied to 'if' and 'switch' statements}} fxc-pass {{}}
   for (int i = 0; i < 10; i++) result++;
   for (int i = 0; i < 10; i++) result++;
   return result;
   return result;
 }
 }
@@ -93,7 +93,7 @@ int branch_before_for() {
 int branch_before_while() {
 int branch_before_while() {
   int result = 0;
   int result = 0;
   int i = 0;
   int i = 0;
-  [branch] // expected-warning {{attribute 'branch' can only be applied to 'if' and 'switch' statements}}
+  [branch] // expected-warning {{attribute 'branch' can only be applied to 'if' and 'switch' statements}} fxc-pass {{}}
   while(i < 10) {
   while(i < 10) {
     result++;
     result++;
     i++;
     i++;
@@ -104,7 +104,7 @@ int branch_before_while() {
 int branch_before_do() {
 int branch_before_do() {
   int result = 0;
   int result = 0;
   int i = 0;
   int i = 0;
-  [branch] // expected-warning {{attribute 'branch' can only be applied to 'if' and 'switch' statements}}
+  [branch] // expected-warning {{attribute 'branch' can only be applied to 'if' and 'switch' statements}} fxc-pass {{}}
   do {
   do {
     result++;
     result++;
     i++;
     i++;
@@ -114,7 +114,7 @@ int branch_before_do() {
 
 
 int flatten_before_for() {
 int flatten_before_for() {
   int result = 0;
   int result = 0;
-  [flatten] // expected-warning {{attribute 'flatten' can only be applied to 'if' and 'switch' statements}}
+  [flatten] // expected-warning {{attribute 'flatten' can only be applied to 'if' and 'switch' statements}} fxc-pass {{}}
   for (int i = 0; i < 10; i++) result++;
   for (int i = 0; i < 10; i++) result++;
   return result;
   return result;
 }
 }
@@ -122,7 +122,7 @@ int flatten_before_for() {
 int flatten_before_while() {
 int flatten_before_while() {
   int result = 0;
   int result = 0;
   int i = 0;
   int i = 0;
-  [flatten] // expected-warning {{attribute 'flatten' can only be applied to 'if' and 'switch' statements}}
+  [flatten] // expected-warning {{attribute 'flatten' can only be applied to 'if' and 'switch' statements}} fxc-pass {{}}
   while(i < 10) {
   while(i < 10) {
     result++;
     result++;
     i++;
     i++;
@@ -133,7 +133,7 @@ int flatten_before_while() {
 int flatten_before_do() {
 int flatten_before_do() {
   int result = 0;
   int result = 0;
   int i = 0;
   int i = 0;
-  [flatten] // expected-warning {{attribute 'flatten' can only be applied to 'if' and 'switch' statements}}
+  [flatten] // expected-warning {{attribute 'flatten' can only be applied to 'if' and 'switch' statements}} fxc-pass {{}}
   do {
   do {
     result++;
     result++;
     i++;
     i++;
@@ -143,7 +143,7 @@ int flatten_before_do() {
 
 
 int forcecase_before_for() {
 int forcecase_before_for() {
   int result = 0;
   int result = 0;
-  [forcecase] // expected-warning {{attribute 'forcecase' can only be applied to 'switch' statements}}
+  [forcecase] // expected-warning {{attribute 'forcecase' can only be applied to 'switch' statements}} fxc-pass {{}}
   for (int i = 0; i < 10; i++) result++;
   for (int i = 0; i < 10; i++) result++;
   return result;
   return result;
 }
 }
@@ -151,7 +151,7 @@ int forcecase_before_for() {
 int forcecase_before_while() {
 int forcecase_before_while() {
   int result = 0;
   int result = 0;
   int i = 0;
   int i = 0;
-  [forcecase] // expected-warning {{attribute 'forcecase' can only be applied to 'switch' statements}}
+  [forcecase] // expected-warning {{attribute 'forcecase' can only be applied to 'switch' statements}} fxc-pass {{}}
   while(i < 10) {
   while(i < 10) {
     result++;
     result++;
     i++;
     i++;
@@ -162,7 +162,7 @@ int forcecase_before_while() {
 int forcecase_before_do() {
 int forcecase_before_do() {
   int result = 0;
   int result = 0;
   int i = 0;
   int i = 0;
-  [forcecase] // expected-warning {{attribute 'forcecase' can only be applied to 'switch' statements}}
+  [forcecase] // expected-warning {{attribute 'forcecase' can only be applied to 'switch' statements}} fxc-pass {{}}
   do {
   do {
     result++;
     result++;
     i++;
     i++;
@@ -171,14 +171,14 @@ int forcecase_before_do() {
 }
 }
 
 
 int forcecase_before_if(int a) {
 int forcecase_before_if(int a) {
-  [forcecase] // expected-warning {{attribute 'forcecase' can only be applied to 'switch' statements}}
+  [forcecase] // expected-warning {{attribute 'forcecase' can only be applied to 'switch' statements}} fxc-pass {{}}
   if (a > 0) return -a;
   if (a > 0) return -a;
   return a;
   return a;
 }
 }
 
 
 int call_before_for() {
 int call_before_for() {
   int result = 0;
   int result = 0;
-  [call] // expected-warning {{attribute 'call' can only be applied to 'switch' statements}}
+  [call] // expected-warning {{attribute 'call' can only be applied to 'switch' statements}} fxc-pass {{}}
   for (int i = 0; i < 10; i++) result++;
   for (int i = 0; i < 10; i++) result++;
   return result;
   return result;
 }
 }
@@ -186,7 +186,7 @@ int call_before_for() {
 int call_before_while() {
 int call_before_while() {
   int result = 0;
   int result = 0;
   int i = 0;
   int i = 0;
-  [call] // expected-warning {{attribute 'call' can only be applied to 'switch' statements}}
+  [call] // expected-warning {{attribute 'call' can only be applied to 'switch' statements}} fxc-pass {{}}
   while(i < 10) {
   while(i < 10) {
     result++;
     result++;
     i++;
     i++;
@@ -197,7 +197,7 @@ int call_before_while() {
 int call_before_do() {
 int call_before_do() {
   int result = 0;
   int result = 0;
   int i = 0;
   int i = 0;
-  [call] // expected-warning {{attribute 'call' can only be applied to 'switch' statements}}
+  [call] // expected-warning {{attribute 'call' can only be applied to 'switch' statements}} fxc-pass {{}}
   do {
   do {
     result++;
     result++;
     i++;
     i++;
@@ -206,7 +206,7 @@ int call_before_do() {
 }
 }
 
 
 int call_before_if(int a) {
 int call_before_if(int a) {
-  [call] // expected-warning {{attribute 'call' can only be applied to 'switch' statements}}
+  [call] // expected-warning {{attribute 'call' can only be applied to 'switch' statements}} fxc-pass {{}}
   if (a > 0) return -a;
   if (a > 0) return -a;
   return a;
   return a;
 }
 }
@@ -256,9 +256,9 @@ int neg_unroll() {
   // fxc error X3084: cannot match attribute unroll, non-uint parameters found
   // fxc error X3084: cannot match attribute unroll, non-uint parameters found
   [unroll(-1)] // expected-warning {{attribute 'unroll' must have a uint literal argument}} fxc-error {{X3084: cannot match attribute unroll, non-uint parameters found}}
   [unroll(-1)] // expected-warning {{attribute 'unroll' must have a uint literal argument}} fxc-error {{X3084: cannot match attribute unroll, non-uint parameters found}}
   /*verify-ast
   /*verify-ast
-    AttributedStmt <col:3, line:85:39>
+    AttributedStmt <col:3, line:277:39>
     |-HLSLUnrollAttr <col:4, col:13> -1
     |-HLSLUnrollAttr <col:4, col:13> -1
-    `-ForStmt <line:85:3, col:39>
+    `-ForStmt <line:277:3, col:39>
       |-DeclStmt <col:8, col:17>
       |-DeclStmt <col:8, col:17>
       | `-VarDecl <col:8, col:16> col:12 used i 'int' cinit
       | `-VarDecl <col:8, col:16> col:12 used i 'int' cinit
       |   `-ImplicitCastExpr <col:16> 'int' <IntegralCast>
       |   `-ImplicitCastExpr <col:16> 'int' <IntegralCast>
@@ -286,9 +286,9 @@ int flt_unroll() {
   // fxc warning X3554: unknown attribute unroll, or attribute invalid for this statement, valid attributes are: loop, fastopt, unroll, allow_uav_condition
   // fxc warning X3554: unknown attribute unroll, or attribute invalid for this statement, valid attributes are: loop, fastopt, unroll, allow_uav_condition
   [unroll(1.5)] // expected-warning {{attribute 'unroll' must have a uint literal argument}} fxc-warning {{X3554: cannot match attribute unroll, parameter 1 is expected to be of type int}} fxc-warning {{X3554: unknown attribute unroll, or attribute invalid for this statement, valid attributes are: loop, fastopt, unroll, allow_uav_condition}}
   [unroll(1.5)] // expected-warning {{attribute 'unroll' must have a uint literal argument}} fxc-warning {{X3554: cannot match attribute unroll, parameter 1 is expected to be of type int}} fxc-warning {{X3554: unknown attribute unroll, or attribute invalid for this statement, valid attributes are: loop, fastopt, unroll, allow_uav_condition}}
   /*verify-ast
   /*verify-ast
-    AttributedStmt <col:3, line:115:39>
+    AttributedStmt <col:3, line:307:39>
     |-HLSLUnrollAttr <col:4, col:14> 0
     |-HLSLUnrollAttr <col:4, col:14> 0
-    `-ForStmt <line:115:3, col:39>
+    `-ForStmt <line:307:3, col:39>
       |-DeclStmt <col:8, col:17>
       |-DeclStmt <col:8, col:17>
       | `-VarDecl <col:8, col:16> col:12 used i 'int' cinit
       | `-VarDecl <col:8, col:16> col:12 used i 'int' cinit
       |   `-ImplicitCastExpr <col:16> 'int' <IntegralCast>
       |   `-ImplicitCastExpr <col:16> 'int' <IntegralCast>
@@ -327,9 +327,9 @@ int uav() {
   uint i;
   uint i;
   [allow_uav_condition]
   [allow_uav_condition]
   /*verify-ast
   /*verify-ast
-    AttributedStmt <col:3, line:156:3>
+    AttributedStmt <col:3, line:348:3>
     |-HLSLAllowUAVConditionAttr <col:4>
     |-HLSLAllowUAVConditionAttr <col:4>
-    `-ForStmt <line:155:3, line:156:3>
+    `-ForStmt <line:347:3, line:348:3>
       |-BinaryOperator <col:8, col:12> 'uint':'unsigned int' '='
       |-BinaryOperator <col:8, col:12> 'uint':'unsigned int' '='
       | |-DeclRefExpr <col:8> 'uint':'unsigned int' lvalue Var 'i' 'uint':'unsigned int'
       | |-DeclRefExpr <col:8> 'uint':'unsigned int' lvalue Var 'i' 'uint':'unsigned int'
       | `-ImplicitCastExpr <col:12> 'uint':'unsigned int' <LValueToRValue>
       | `-ImplicitCastExpr <col:12> 'uint':'unsigned int' <LValueToRValue>
@@ -342,7 +342,7 @@ int uav() {
       |   `-DeclRefExpr <col:38> 'const uint':'const unsigned int' lvalue Var 'g_dealiasTableSize' 'const uint':'const unsigned int'
       |   `-DeclRefExpr <col:38> 'const uint':'const unsigned int' lvalue Var 'g_dealiasTableSize' 'const uint':'const unsigned int'
       |-UnaryOperator <col:58, col:60> 'uint':'unsigned int' lvalue prefix '++'
       |-UnaryOperator <col:58, col:60> 'uint':'unsigned int' lvalue prefix '++'
       | `-DeclRefExpr <col:60> 'uint':'unsigned int' lvalue Var 'i' 'uint':'unsigned int'
       | `-DeclRefExpr <col:60> 'uint':'unsigned int' lvalue Var 'i' 'uint':'unsigned int'
-      `-CompoundStmt <col:63, line:156:3>
+      `-CompoundStmt <col:63, line:348:3>
   */
   */
   for (i = g_dealiasTableOffset; i < g_dealiasTableSize; ++i) {
   for (i = g_dealiasTableOffset; i < g_dealiasTableSize; ++i) {
   }
   }
@@ -393,16 +393,16 @@ void all_wrong() { }
 [patchconstantfunc("PatchFoo")]
 [patchconstantfunc("PatchFoo")]
 HSFoo HSMain( InputPatch<HSFoo, 16> p,
 HSFoo HSMain( InputPatch<HSFoo, 16> p,
 /*verify-ast
 /*verify-ast
-  FunctionDecl <col:1, line:276:1> line:202:7 HSMain 'HSFoo (InputPatch<HSFoo, 16>, uint, uint)'
+  FunctionDecl <col:1, line:468:1> line:394:7 HSMain 'HSFoo (InputPatch<HSFoo, 16>, uint, uint)'
   |-ParmVarDecl <col:15, col:37> col:37 used p 'InputPatch<HSFoo, 16>':'InputPatch<HSFoo, 16>'
   |-ParmVarDecl <col:15, col:37> col:37 used p 'InputPatch<HSFoo, 16>':'InputPatch<HSFoo, 16>'
-  |-ParmVarDecl <line:268:15, col:20> col:20 used i 'uint':'unsigned int'
+  |-ParmVarDecl <line:460:15, col:20> col:20 used i 'uint':'unsigned int'
   | `-SemanticDecl <col:24> "SV_OutputControlPointID"
   | `-SemanticDecl <col:24> "SV_OutputControlPointID"
-  |-ParmVarDecl <line:269:15, col:20> col:20 used PatchID 'uint':'unsigned int'
+  |-ParmVarDecl <line:461:15, col:20> col:20 used PatchID 'uint':'unsigned int'
   | `-SemanticDecl <col:30> "SV_PrimitiveID"
   | `-SemanticDecl <col:30> "SV_PrimitiveID"
-  |-CompoundStmt <line:270:1, line:276:1>
-  | |-DeclStmt <line:271:5, col:17>
+  |-CompoundStmt <line:462:1, line:468:1>
+  | |-DeclStmt <line:463:5, col:17>
   | | `-VarDecl <col:5, col:11> col:11 used output 'HSFoo' nrvo
   | | `-VarDecl <col:5, col:11> col:11 used output 'HSFoo' nrvo
-  | |-DeclStmt <line:272:5, col:41>
+  | |-DeclStmt <line:464:5, col:41>
   | | `-VarDecl <col:5, col:40> col:12 used r 'float4':'vector<float, 4>' cinit
   | | `-VarDecl <col:5, col:40> col:12 used r 'float4':'vector<float, 4>' cinit
   | |   `-CXXFunctionalCastExpr <col:16, col:40> 'float4':'vector<float, 4>' functional cast to float4 <NoOp>
   | |   `-CXXFunctionalCastExpr <col:16, col:40> 'float4':'vector<float, 4>' functional cast to float4 <NoOp>
   | |     `-InitListExpr <col:23, col:39> 'float4':'vector<float, 4>'
   | |     `-InitListExpr <col:23, col:39> 'float4':'vector<float, 4>'
@@ -417,7 +417,7 @@ HSFoo HSMain( InputPatch<HSFoo, 16> p,
   | |       |       `-DeclRefExpr <col:25> 'uint':'unsigned int' lvalue ParmVar 'PatchID' 'uint':'unsigned int'
   | |       |       `-DeclRefExpr <col:25> 'uint':'unsigned int' lvalue ParmVar 'PatchID' 'uint':'unsigned int'
   | |       `-ImplicitCastExpr <col:39> 'float' <IntegralToFloating>
   | |       `-ImplicitCastExpr <col:39> 'float' <IntegralToFloating>
   | |         `-IntegerLiteral <col:39> 'literal int' 1
   | |         `-IntegerLiteral <col:39> 'literal int' 1
-  | |-CompoundAssignOperator <line:273:5, col:30> 'float4':'vector<float, 4>' lvalue '+=' ComputeLHSTy='float4':'vector<float, 4>' ComputeResultTy='float4':'vector<float, 4>'
+  | |-CompoundAssignOperator <line:465:5, col:30> 'float4':'vector<float, 4>' lvalue '+=' ComputeLHSTy='float4':'vector<float, 4>' ComputeResultTy='float4':'vector<float, 4>'
   | | |-DeclRefExpr <col:5> 'float4':'vector<float, 4>' lvalue Var 'r' 'float4':'vector<float, 4>'
   | | |-DeclRefExpr <col:5> 'float4':'vector<float, 4>' lvalue Var 'r' 'float4':'vector<float, 4>'
   | | `-CXXMemberCallExpr <col:10, col:30> 'vector<float, 4>'
   | | `-CXXMemberCallExpr <col:10, col:30> 'vector<float, 4>'
   | |   |-MemberExpr <col:10, col:20> '<bound member function type>' .Load
   | |   |-MemberExpr <col:10, col:20> '<bound member function type>' .Load
@@ -432,7 +432,7 @@ HSFoo HSMain( InputPatch<HSFoo, 16> p,
   | |     `-ImplicitCastExpr <col:25, col:27> 'vector<float, 3>':'vector<float, 3>' <LValueToRValue>
   | |     `-ImplicitCastExpr <col:25, col:27> 'vector<float, 3>':'vector<float, 3>' <LValueToRValue>
   | |       `-HLSLVectorElementExpr <col:25, col:27> 'vector<float, 3>':'vector<float, 3>' lvalue vectorcomponent xyz
   | |       `-HLSLVectorElementExpr <col:25, col:27> 'vector<float, 3>':'vector<float, 3>' lvalue vectorcomponent xyz
   | |         `-DeclRefExpr <col:25> 'float4':'vector<float, 4>' lvalue Var 'r' 'float4':'vector<float, 4>'
   | |         `-DeclRefExpr <col:25> 'float4':'vector<float, 4>' lvalue Var 'r' 'float4':'vector<float, 4>'
-  | |-BinaryOperator <line:274:5, col:31> 'float3':'vector<float, 3>' '='
+  | |-BinaryOperator <line:466:5, col:31> 'float3':'vector<float, 3>' '='
   | | |-MemberExpr <col:5, col:12> 'float3':'vector<float, 3>' lvalue .pos
   | | |-MemberExpr <col:5, col:12> 'float3':'vector<float, 3>' lvalue .pos
   | | | `-DeclRefExpr <col:5> 'HSFoo' lvalue Var 'output' 'HSFoo'
   | | | `-DeclRefExpr <col:5> 'HSFoo' lvalue Var 'output' 'HSFoo'
   | | `-BinaryOperator <col:18, col:31> 'float3':'vector<float, 3>' '+'
   | | `-BinaryOperator <col:18, col:31> 'float3':'vector<float, 3>' '+'
@@ -448,14 +448,14 @@ HSFoo HSMain( InputPatch<HSFoo, 16> p,
   | |   `-ImplicitCastExpr <col:29, col:31> 'vector<float, 3>':'vector<float, 3>' <LValueToRValue>
   | |   `-ImplicitCastExpr <col:29, col:31> 'vector<float, 3>':'vector<float, 3>' <LValueToRValue>
   | |     `-HLSLVectorElementExpr <col:29, col:31> 'vector<float, 3>':'vector<float, 3>' lvalue vectorcomponent xyz
   | |     `-HLSLVectorElementExpr <col:29, col:31> 'vector<float, 3>':'vector<float, 3>' lvalue vectorcomponent xyz
   | |       `-DeclRefExpr <col:29> 'float4':'vector<float, 4>' lvalue Var 'r' 'float4':'vector<float, 4>'
   | |       `-DeclRefExpr <col:29> 'float4':'vector<float, 4>' lvalue Var 'r' 'float4':'vector<float, 4>'
-  | `-ReturnStmt <line:275:5, col:12>
+  | `-ReturnStmt <line:467:5, col:12>
   |   `-ImplicitCastExpr <col:12> 'HSFoo' <LValueToRValue>
   |   `-ImplicitCastExpr <col:12> 'HSFoo' <LValueToRValue>
   |     `-DeclRefExpr <col:12> 'HSFoo' lvalue Var 'output' 'HSFoo'
   |     `-DeclRefExpr <col:12> 'HSFoo' lvalue Var 'output' 'HSFoo'
-  |-HLSLPatchConstantFuncAttr <line:201:2, col:30> "PatchFoo"
-  |-HLSLOutputControlPointsAttr <line:200:2, col:24> 16
-  |-HLSLOutputTopologyAttr <line:199:2, col:30> "triangle_cw"
-  |-HLSLPartitioningAttr <line:198:2, col:24> "integer"
-  `-HLSLDomainAttr <line:194:2, col:15> "quad"
+  |-HLSLPatchConstantFuncAttr <line:393:2, col:30> "PatchFoo"
+  |-HLSLOutputControlPointsAttr <line:392:2, col:24> 16
+  |-HLSLOutputTopologyAttr <line:391:2, col:30> "triangle_cw"
+  |-HLSLPartitioningAttr <line:390:2, col:24> "integer"
+  `-HLSLDomainAttr <line:386:2, col:15> "quad"
 */
 */
               uint i : SV_OutputControlPointID,
               uint i : SV_OutputControlPointID,
               uint PatchID : SV_PrimitiveID )
               uint PatchID : SV_PrimitiveID )
@@ -561,13 +561,13 @@ void clipplanes_bad_scalar_swizzle();
 
 
 [clipplanes(
 [clipplanes(
 /*verify-ast
 /*verify-ast
-  HLSLClipPlanesAttr <col:2, line:390:3>
-  |-DeclRefExpr <line:387:3> 'const float4':'const vector<float, 4>' lvalue Var 'f4' 'const float4':'const vector<float, 4>'
-  |-ArraySubscriptExpr <line:388:3, col:8> 'const float4':'const vector<float, 4>' lvalue
+  HLSLClipPlanesAttr <col:2, line:582:3>
+  |-DeclRefExpr <line:579:3> 'const float4':'const vector<float, 4>' lvalue Var 'f4' 'const float4':'const vector<float, 4>'
+  |-ArraySubscriptExpr <line:580:3, col:8> 'const float4':'const vector<float, 4>' lvalue
   | |-ImplicitCastExpr <col:3> 'const float4 [2]' <LValueToRValue>
   | |-ImplicitCastExpr <col:3> 'const float4 [2]' <LValueToRValue>
   | | `-DeclRefExpr <col:3> 'const float4 [2]' lvalue Var 'cp4' 'const float4 [2]'
   | | `-DeclRefExpr <col:3> 'const float4 [2]' lvalue Var 'cp4' 'const float4 [2]'
   | `-IntegerLiteral <col:7> 'literal int' 0
   | `-IntegerLiteral <col:7> 'literal int' 0
-  |-ArraySubscriptExpr <line:389:3, col:11> 'float4':'vector<float, 4>' lvalue
+  |-ArraySubscriptExpr <line:581:3, col:11> 'float4':'vector<float, 4>' lvalue
   | |-ImplicitCastExpr <col:3, col:6> 'float4 [5]' <LValueToRValue>
   | |-ImplicitCastExpr <col:3, col:6> 'float4 [5]' <LValueToRValue>
   | | `-MemberExpr <col:3, col:6> 'float4 const[5]' lvalue .cp5
   | | `-MemberExpr <col:3, col:6> 'float4 const[5]' lvalue .cp5
   | |   `-DeclRefExpr <col:3> 'const global_struct' lvalue Var 'gs' 'const global_struct'
   | |   `-DeclRefExpr <col:3> 'const global_struct' lvalue Var 'gs' 'const global_struct'
@@ -585,21 +585,21 @@ float4 clipplanes_good();
 
 
 [clipplanes(
 [clipplanes(
 /*verify-ast
 /*verify-ast
-  HLSLClipPlanesAttr <col:2, line:424:3>
-  |-ParenExpr <line:420:3, col:6> 'const float4':'const vector<float, 4>' lvalue
+  HLSLClipPlanesAttr <col:2, line:616:3>
+  |-ParenExpr <line:612:3, col:6> 'const float4':'const vector<float, 4>' lvalue
   | `-DeclRefExpr <col:4> 'const float4':'const vector<float, 4>' lvalue Var 'f4' 'const float4':'const vector<float, 4>'
   | `-DeclRefExpr <col:4> 'const float4':'const vector<float, 4>' lvalue Var 'f4' 'const float4':'const vector<float, 4>'
-  |-ArraySubscriptExpr <line:421:3, col:10> 'const float4':'const vector<float, 4>' lvalue
+  |-ArraySubscriptExpr <line:613:3, col:10> 'const float4':'const vector<float, 4>' lvalue
   | |-ImplicitCastExpr <col:3> 'const float4 [2]' <LValueToRValue>
   | |-ImplicitCastExpr <col:3> 'const float4 [2]' <LValueToRValue>
   | | `-DeclRefExpr <col:3> 'const float4 [2]' lvalue Var 'cp4' 'const float4 [2]'
   | | `-DeclRefExpr <col:3> 'const float4 [2]' lvalue Var 'cp4' 'const float4 [2]'
   | `-ParenExpr <col:7, col:9> 'literal int'
   | `-ParenExpr <col:7, col:9> 'literal int'
   |   `-IntegerLiteral <col:8> 'literal int' 0
   |   `-IntegerLiteral <col:8> 'literal int' 0
-  |-ArraySubscriptExpr <line:422:3, col:13> 'float4':'vector<float, 4>' lvalue
+  |-ArraySubscriptExpr <line:614:3, col:13> 'float4':'vector<float, 4>' lvalue
   | |-ImplicitCastExpr <col:3, col:8> 'float4 [5]' <LValueToRValue>
   | |-ImplicitCastExpr <col:3, col:8> 'float4 [5]' <LValueToRValue>
   | | `-MemberExpr <col:3, col:8> 'float4 const[5]' lvalue .cp5
   | | `-MemberExpr <col:3, col:8> 'float4 const[5]' lvalue .cp5
   | |   `-ParenExpr <col:3, col:6> 'const global_struct' lvalue
   | |   `-ParenExpr <col:3, col:6> 'const global_struct' lvalue
   | |     `-DeclRefExpr <col:4> 'const global_struct' lvalue Var 'gs' 'const global_struct'
   | |     `-DeclRefExpr <col:4> 'const global_struct' lvalue Var 'gs' 'const global_struct'
   | `-IntegerLiteral <col:12> 'literal int' 2
   | `-IntegerLiteral <col:12> 'literal int' 2
-  |-ParenExpr <line:423:3, col:15> 'float4':'vector<float, 4>' lvalue
+  |-ParenExpr <line:615:3, col:15> 'float4':'vector<float, 4>' lvalue
   | `-ArraySubscriptExpr <col:4, col:14> 'float4':'vector<float, 4>' lvalue
   | `-ArraySubscriptExpr <col:4, col:14> 'float4':'vector<float, 4>' lvalue
   |   |-ImplicitCastExpr <col:4, col:9> 'float4 [5]' <LValueToRValue>
   |   |-ImplicitCastExpr <col:4, col:9> 'float4 [5]' <LValueToRValue>
   |   | `-MemberExpr <col:4, col:9> 'float4 const[5]' lvalue .cp5
   |   | `-MemberExpr <col:4, col:9> 'float4 const[5]' lvalue .cp5

+ 13 - 13
tools/clang/test/HLSL/builtin-types-no-inheritance.hlsl

@@ -1,20 +1,20 @@
 // RUN: %clang_cc1 -Wno-unused-value -fsyntax-only -ffreestanding -verify -verify-ignore-unexpected=note %s
 // RUN: %clang_cc1 -Wno-unused-value -fsyntax-only -ffreestanding -verify -verify-ignore-unexpected=note %s
 
 
-struct F2 : float2 {}; // expected-error {{base 'vector' is marked 'final'}}
-struct F4x4 : float4x4 {}; // expected-error {{base 'matrix' is marked 'final'}}
-struct Tex3D : Texture3D<float> {};  // expected-error {{base 'Texture3D' is marked 'final'}}
-struct BABuf : ByteAddressBuffer {}; // expected-error {{base 'ByteAddressBuffer' is marked 'final'}}
-struct StructBuf : StructuredBuffer<int> {}; // expected-error {{base 'StructuredBuffer' is marked 'final'}}
-struct Samp : SamplerState {}; // expected-error {{base 'SamplerState' is marked 'final'}}
+struct F2 : float2 {}; // expected-error {{base 'vector' is marked 'final'}} fxc-error {{X3094: base type is not a struct, class or interface}}
+struct F4x4 : float4x4 {}; // expected-error {{base 'matrix' is marked 'final'}} fxc-error {{X3094: base type is not a struct, class or interface}}
+struct Tex3D : Texture3D<float> {};  // expected-error {{base 'Texture3D' is marked 'final'}} fxc-error {{X3000: syntax error: unexpected token 'Texture3D'}}
+struct BABuf : ByteAddressBuffer {}; // expected-error {{base 'ByteAddressBuffer' is marked 'final'}} fxc-error {{X3000: syntax error: unexpected token 'ByteAddressBuffer'}}
+struct StructBuf : StructuredBuffer<int> {}; // expected-error {{base 'StructuredBuffer' is marked 'final'}} fxc-error {{X3000: syntax error: unexpected token 'StructuredBuffer'}}
+struct Samp : SamplerState {}; // expected-error {{base 'SamplerState' is marked 'final'}} fxc-error {{X3000: syntax error: unexpected token 'SamplerState'}}
 
 
 struct Vertex { float3 pos : POSITION; };
 struct Vertex { float3 pos : POSITION; };
-struct GSTS : TriangleStream<Vertex> {}; // expected-error {{base 'TriangleStream' is marked 'final'}}
-struct HSIP : InputPatch<Vertex, 16> {}; // expected-error {{base 'InputPatch' is marked 'final'}}
-struct HSOP : OutputPatch<Vertex, 16> {}; // expected-error {{base 'OutputPatch' is marked 'final'}}
+struct GSTS : TriangleStream<Vertex> {}; // expected-error {{base 'TriangleStream' is marked 'final'}} fxc-error {{X3000: syntax error: unexpected token 'TriangleStream'}}
+struct HSIP : InputPatch<Vertex, 16> {}; // expected-error {{base 'InputPatch' is marked 'final'}} fxc-error {{X3000: syntax error: unexpected token 'InputPatch'}}
+struct HSOP : OutputPatch<Vertex, 16> {}; // expected-error {{base 'OutputPatch' is marked 'final'}} fxc-error {{X3000: syntax error: unexpected token 'OutputPatch'}}
 
 
-struct RD : RayDesc {}; // expected-error {{base 'RayDesc' is marked 'final'}}
-struct BITIA : BuiltInTriangleIntersectionAttributes {}; // expected-error {{base 'BuiltInTriangleIntersectionAttributes' is marked 'final'}}
-struct RTAS : RaytracingAccelerationStructure {}; // expected-error {{base 'RaytracingAccelerationStructure' is marked 'final'}}
-struct GRS : GlobalRootSignature {}; // expected-error {{base 'GlobalRootSignature' is marked 'final'}}
+struct RD : RayDesc {}; // expected-error {{base 'RayDesc' is marked 'final'}} fxc-error {{X3000: syntax error: unexpected token 'RayDesc'}}
+struct BITIA : BuiltInTriangleIntersectionAttributes {}; // expected-error {{base 'BuiltInTriangleIntersectionAttributes' is marked 'final'}} fxc-error {{X3000: syntax error: unexpected token 'BuiltInTriangleIntersectionAttributes'}}
+struct RTAS : RaytracingAccelerationStructure {}; // expected-error {{base 'RaytracingAccelerationStructure' is marked 'final'}} fxc-error {{X3000: syntax error: unexpected token 'RaytracingAccelerationStructure'}}
+struct GRS : GlobalRootSignature {}; // expected-error {{base 'GlobalRootSignature' is marked 'final'}} fxc-error {{X3000: syntax error: unexpected token 'GlobalRootSignature'}}
 
 
 void main() {}
 void main() {}

+ 6 - 6
tools/clang/test/HLSL/conversions-non-numeric-aggregates.hlsl

@@ -7,13 +7,13 @@ struct ObjStruct { Buffer a; };
 
 
 void main()
 void main()
 {
 {
-  (Buffer[1])0; /* expected-error {{cannot convert from 'literal int' to 'Buffer [1]'}} */
-  (ObjStruct)0; /* expected-error {{cannot convert from 'literal int' to 'ObjStruct'}} */
-  (Buffer[1])(int[1])0; /* expected-error {{cannot convert from 'int [1]' to 'Buffer [1]'}} */
-  (ObjStruct)(NumStruct)0; /* expected-error {{cannot convert from 'NumStruct' to 'ObjStruct'}} */
+  (Buffer[1])0; /* expected-error {{cannot convert from 'literal int' to 'Buffer [1]'}} fxc-error {{X3017: cannot convert from 'int' to 'Buffer<float4>[1]'}} */
+  (ObjStruct)0; /* expected-error {{cannot convert from 'literal int' to 'ObjStruct'}} fxc-error {{X3017: cannot convert from 'int' to 'struct ObjStruct'}} */
+  (Buffer[1])(int[1])0; /* expected-error {{cannot convert from 'int [1]' to 'Buffer [1]'}} fxc-error {{X3017: cannot convert from 'const int[1]' to 'Buffer<float4>[1]'}} */
+  (ObjStruct)(NumStruct)0; /* expected-error {{cannot convert from 'NumStruct' to 'ObjStruct'}} fxc-error {{X3017: cannot convert from 'const struct NumStruct' to 'struct ObjStruct'}} */
 
 
   Buffer oa1[1];
   Buffer oa1[1];
   ObjStruct os1;
   ObjStruct os1;
-  (int)oa1; /* expected-error {{cannot convert from 'Buffer [1]' to 'int'}} */
-  (int)os1; /* expected-error {{cannot convert from 'ObjStruct' to 'int'}} */
+  (int)oa1; /* expected-error {{cannot convert from 'Buffer [1]' to 'int'}} fxc-error {{X3017: cannot convert from 'Buffer<float4>[1]' to 'int'}} */
+  (int)os1; /* expected-error {{cannot convert from 'ObjStruct' to 'int'}} fxc-error {{X3017: cannot convert from 'struct ObjStruct' to 'int'}} */
 }
 }

+ 7 - 7
tools/clang/test/HLSL/incomp_array_err.hlsl

@@ -2,28 +2,28 @@
 
 
 // Verify error on on incomplete array in a struct or class
 // Verify error on on incomplete array in a struct or class
 
 
-typedef const int inta[];
+typedef const int inta[];                                   /* fxc-error {{X3072: array dimensions of type must be explicit}} */
 
 
-static inta s_test1 = {1, 2, 3};
+static inta s_test1 = {1, 2, 3};                            /* fxc-error {{X3000: unrecognized identifier 'inta'}} */
 
 
 static int s_test2[] = { 4, 5, 6 };
 static int s_test2[] = { 4, 5, 6 };
 
 
 struct foo1 {
 struct foo1 {
   float4 member;
   float4 member;
-  inta a;   // expected-error {{array dimensions of struct/class members must be explicit}}
+  inta a;   // expected-error {{array dimensions of struct/class members must be explicit}} fxc-error {{X3000: unrecognized identifier 'inta'}}
 };
 };
 
 
 struct foo2 {
 struct foo2 {
-  int a[];  // expected-error {{array dimensions of struct/class members must be explicit}}
+  int a[];  // expected-error {{array dimensions of struct/class members must be explicit}} fxc-error {{X3072: 'foo2::a': array dimensions of struct/class members must be explicit}}
   float4 member;
   float4 member;
 };
 };
 
 
 class foo3 {
 class foo3 {
   float4 member;
   float4 member;
-  inta a;   // expected-error {{array dimensions of struct/class members must be explicit}}
+  inta a;   // expected-error {{array dimensions of struct/class members must be explicit}} fxc-error {{X3000: unrecognized identifier 'inta'}}
 };
 };
 
 
 class foo4 {
 class foo4 {
   float4 member;
   float4 member;
-  int a[];  // expected-error {{array dimensions of struct/class members must be explicit}}
-};
+  int a[];  // expected-error {{array dimensions of struct/class members must be explicit}} fxc-error {{X3072: 'foo4::a': array dimensions of struct/class members must be explicit}}
+};

+ 214 - 28
tools/clang/test/HLSL/indexing-operator.hlsl

@@ -3,6 +3,25 @@
 // To test with the classic compiler, run
 // To test with the classic compiler, run
 // %sdxroot%\tools\x86\fxc.exe /T vs_5_1 indexing-operator.hlsl
 // %sdxroot%\tools\x86\fxc.exe /T vs_5_1 indexing-operator.hlsl
 
 
+/* Expected notes with no locations (implicit built-in):
+  expected-note@? {{function 'operator[]<const vector<float, 4> &>' which returns const-qualified type 'const vector<float, 4> &' declared here}}
+  expected-note@? {{function 'operator[]<const vector<float, 4> &>' which returns const-qualified type 'const vector<float, 4> &' declared here}}
+  expected-note@? {{function 'operator[]<const vector<float, 4> &>' which returns const-qualified type 'const vector<float, 4> &' declared here}}
+  expected-note@? {{function 'operator[]<const vector<float, 4> &>' which returns const-qualified type 'const vector<float, 4> &' declared here}}
+  expected-note@? {{function 'operator[]<const vector<float, 4> &>' which returns const-qualified type 'const vector<float, 4> &' declared here}}
+  expected-note@? {{function 'operator[]<const vector<float, 4> &>' which returns const-qualified type 'const vector<float, 4> &' declared here}}
+  expected-note@? {{function 'operator[]<const vector<float, 4> &>' which returns const-qualified type 'const vector<float, 4> &' declared here}}
+  expected-note@? {{function 'operator[]<const vector<float, 4> &>' which returns const-qualified type 'const vector<float, 4> &' declared here}}
+  expected-note@? {{function 'operator[]<const vector<float, 4> &>' which returns const-qualified type 'const vector<float, 4> &' declared here}}
+  expected-note@? {{function 'operator[]<const vector<float, 4> &>' which returns const-qualified type 'const vector<float, 4> &' declared here}}
+  expected-note@? {{function 'operator[]<const vector<float, 4> &>' which returns const-qualified type 'const vector<float, 4> &' declared here}}
+  expected-note@? {{function 'operator[]<const vector<float, 4> &>' which returns const-qualified type 'const vector<float, 4> &' declared here}}
+  expected-note@? {{function 'operator[]<const vector<float, 4> &>' which returns const-qualified type 'const vector<float, 4> &' declared here}}
+  expected-note@? {{function 'operator[]<const vector<float, 4> &>' which returns const-qualified type 'const vector<float, 4> &' declared here}}
+  expected-note@? {{function 'operator[]<const vector<float, 4> &>' which returns const-qualified type 'const vector<float, 4> &' declared here}}
+  expected-note@? {{function 'operator[]<const vector<float, 4> &>' which returns const-qualified type 'const vector<float, 4> &' declared here}}
+*/
+
 Buffer g_b;
 Buffer g_b;
 StructuredBuffer<float4> g_sb;
 StructuredBuffer<float4> g_sb;
 Texture1D g_t1d;
 Texture1D g_t1d;
@@ -123,6 +142,55 @@ float4 test_scalar_indexing()
   f4 += g_tc[0]; // expected-error {{type 'TextureCube' does not provide a subscript operator}} fxc-error {{X3121: array, matrix, vector, or indexable object type expected in index expression}}
   f4 += g_tc[0]; // expected-error {{type 'TextureCube' does not provide a subscript operator}} fxc-error {{X3121: array, matrix, vector, or indexable object type expected in index expression}}
   // fxc  error X3121: array, matrix, vector, or indexable object type expected in index expression
   // fxc  error X3121: array, matrix, vector, or indexable object type expected in index expression
   f4 += g_tca[0]; // expected-error {{type 'TextureCubeArray' does not provide a subscript operator}} fxc-error {{X3121: array, matrix, vector, or indexable object type expected in index expression}}
   f4 += g_tca[0]; // expected-error {{type 'TextureCubeArray' does not provide a subscript operator}} fxc-error {{X3121: array, matrix, vector, or indexable object type expected in index expression}}
+
+  g_b[0] = f4;          /* expected-error {{cannot assign to return value because function 'operator[]<const vector<float, 4> &>' returns a const value}} fxc-error {{X3025: l-value specifies const object}} */
+  g_t1d[0] = f4;        /* expected-error {{cannot assign to return value because function 'operator[]<const vector<float, 4> &>' returns a const value}} fxc-error {{X3025: l-value specifies const object}} */
+  g_sb[0] = f4;         /* expected-error {{cannot assign to return value because function 'operator[]<const vector<float, 4> &>' returns a const value}} fxc-error {{X3025: l-value specifies const object}} */
+
+  g_rw_sb[0] = f4;
+  /*verify-ast
+    BinaryOperator <col:3, col:16> 'vector<float, 4>' '='
+    |-CXXOperatorCallExpr <col:3, col:12> 'vector<float, 4>' lvalue
+    | |-ImplicitCastExpr <col:10, col:12> 'vector<float, 4> &(*)(unsigned int) const' <FunctionToPointerDecay>
+    | | `-DeclRefExpr <col:10, col:12> 'vector<float, 4> &(unsigned int) const' lvalue CXXMethod 'operator[]' 'vector<float, 4> &(unsigned int) const'
+    | |-ImplicitCastExpr <col:3> 'const RWStructuredBuffer<vector<float, 4> >' lvalue <NoOp>
+    | | `-DeclRefExpr <col:3> 'RWStructuredBuffer<float4>':'RWStructuredBuffer<vector<float, 4> >' lvalue Var 'g_rw_sb' 'RWStructuredBuffer<float4>':'RWStructuredBuffer<vector<float, 4> >'
+    | `-ImplicitCastExpr <col:11> 'unsigned int' <IntegralCast>
+    |   `-IntegerLiteral <col:11> 'literal int' 0
+    `-ImplicitCastExpr <col:16> 'float4':'vector<float, 4>' <LValueToRValue>
+      `-DeclRefExpr <col:16> 'float4':'vector<float, 4>' lvalue Var 'f4' 'float4':'vector<float, 4>'
+  */
+  g_rw_b[0] = f4;
+  /*verify-ast
+    BinaryOperator <col:3, col:15> 'vector<float, 4>' '='
+    |-CXXOperatorCallExpr <col:3, col:11> 'vector<float, 4>' lvalue
+    | |-ImplicitCastExpr <col:9, col:11> 'vector<float, 4> &(*)(unsigned int) const' <FunctionToPointerDecay>
+    | | `-DeclRefExpr <col:9, col:11> 'vector<float, 4> &(unsigned int) const' lvalue CXXMethod 'operator[]' 'vector<float, 4> &(unsigned int) const'
+    | |-ImplicitCastExpr <col:3> 'const RWBuffer<vector<float, 4> >' lvalue <NoOp>
+    | | `-DeclRefExpr <col:3> 'RWBuffer<float4>':'RWBuffer<vector<float, 4> >' lvalue Var 'g_rw_b' 'RWBuffer<float4>':'RWBuffer<vector<float, 4> >'
+    | `-ImplicitCastExpr <col:10> 'unsigned int' <IntegralCast>
+    |   `-IntegerLiteral <col:10> 'literal int' 0
+    `-ImplicitCastExpr <col:15> 'float4':'vector<float, 4>' <LValueToRValue>
+      `-DeclRefExpr <col:15> 'float4':'vector<float, 4>' lvalue Var 'f4' 'float4':'vector<float, 4>'
+  */
+  g_rw_t1d[0] = f4;
+  /*verify-ast
+    BinaryOperator <col:3, col:17> 'vector<float, 4>' '='
+    |-CXXOperatorCallExpr <col:3, col:13> 'vector<float, 4>' lvalue
+    | |-ImplicitCastExpr <col:11, col:13> 'vector<float, 4> &(*)(unsigned int) const' <FunctionToPointerDecay>
+    | | `-DeclRefExpr <col:11, col:13> 'vector<float, 4> &(unsigned int) const' lvalue CXXMethod 'operator[]' 'vector<float, 4> &(unsigned int) const'
+    | |-ImplicitCastExpr <col:3> 'const RWTexture1D<vector<float, 4> >' lvalue <NoOp>
+    | | `-DeclRefExpr <col:3> 'RWTexture1D<float4>':'RWTexture1D<vector<float, 4> >' lvalue Var 'g_rw_t1d' 'RWTexture1D<float4>':'RWTexture1D<vector<float, 4> >'
+    | `-ImplicitCastExpr <col:12> 'unsigned int' <IntegralCast>
+    |   `-IntegerLiteral <col:12> 'literal int' 0
+    `-ImplicitCastExpr <col:17> 'float4':'vector<float, 4>' <LValueToRValue>
+      `-DeclRefExpr <col:17> 'float4':'vector<float, 4>' lvalue Var 'f4' 'float4':'vector<float, 4>'
+  */
+  g_rw_t1da[0] = f4;    /* expected-error {{no viable overloaded operator[] for type 'RWTexture1DArray<float4>'}} expected-note {{candidate function [with element = vector<float, 4> &] not viable: no known conversion from 'literal int' to 'vector<uint, 2>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
+  g_rw_t2d[0] = f4;     /* expected-error {{no viable overloaded operator[] for type 'RWTexture2D<float4>'}} expected-note {{candidate function [with element = vector<float, 4> &] not viable: no known conversion from 'literal int' to 'vector<uint, 2>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
+  g_rw_t2da[0] = f4;    /* expected-error {{no viable overloaded operator[] for type 'RWTexture2DArray<float4>'}} expected-note {{candidate function [with element = vector<float, 4> &] not viable: no known conversion from 'literal int' to 'vector<uint, 3>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
+  g_rw_t3d[0] = f4;     /* expected-error {{no viable overloaded operator[] for type 'RWTexture3D<float4>'}} expected-note {{candidate function [with element = vector<float, 4> &] not viable: no known conversion from 'literal int' to 'vector<uint, 3>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
+
   return f4;
   return f4;
 }
 }
 
 
@@ -175,6 +243,45 @@ float4 test_vector2_indexing()
   f4 += g_tc[offset]; // expected-error {{type 'TextureCube' does not provide a subscript operator}} fxc-error {{X3121: array, matrix, vector, or indexable object type expected in index expression}}
   f4 += g_tc[offset]; // expected-error {{type 'TextureCube' does not provide a subscript operator}} fxc-error {{X3121: array, matrix, vector, or indexable object type expected in index expression}}
   // fxc error X3121: array, matrix, vector, or indexable object type expected in index expression
   // fxc error X3121: array, matrix, vector, or indexable object type expected in index expression
   f4 += g_tca[offset]; // expected-error {{type 'TextureCubeArray' does not provide a subscript operator}} fxc-error {{X3121: array, matrix, vector, or indexable object type expected in index expression}}
   f4 += g_tca[offset]; // expected-error {{type 'TextureCubeArray' does not provide a subscript operator}} fxc-error {{X3121: array, matrix, vector, or indexable object type expected in index expression}}
+
+  g_t1da[offset] = f4;    /* expected-error {{cannot assign to return value because function 'operator[]<const vector<float, 4> &>' returns a const value}} fxc-error {{X3025: l-value specifies const object}} */
+  g_t2d[offset] = f4;     /* expected-error {{cannot assign to return value because function 'operator[]<const vector<float, 4> &>' returns a const value}} fxc-error {{X3025: l-value specifies const object}} */
+  g_t2dms[offset] = f4;   /* expected-error {{cannot assign to return value because function 'operator[]<const vector<float, 4> &>' returns a const value}} fxc-error {{X3025: l-value specifies const object}} */
+
+  g_rw_sb[offset] = f4;   /* expected-error {{no viable overloaded operator[] for type 'RWStructuredBuffer<float4>'}} expected-note {{candidate function [with element = vector<float, 4> &] not viable: no known conversion from 'int2' to 'unsigned int' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
+  g_rw_b[offset] = f4;    /* expected-error {{no viable overloaded operator[] for type 'RWBuffer<float4>'}} expected-note {{candidate function [with element = vector<float, 4> &] not viable: no known conversion from 'int2' to 'unsigned int' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
+  g_rw_t1d[offset] = f4;  /* expected-error {{no viable overloaded operator[] for type 'RWTexture1D<float4>'}} expected-note {{candidate function [with element = vector<float, 4> &] not viable: no known conversion from 'int2' to 'unsigned int' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
+  g_rw_t1da[offset] = f4;
+  /*verify-ast
+    BinaryOperator <col:3, col:23> 'vector<float, 4>' '='
+    |-CXXOperatorCallExpr <col:3, col:19> 'vector<float, 4>' lvalue
+    | |-ImplicitCastExpr <col:12, col:19> 'vector<float, 4> &(*)(vector<uint, 2>) const' <FunctionToPointerDecay>
+    | | `-DeclRefExpr <col:12, col:19> 'vector<float, 4> &(vector<uint, 2>) const' lvalue CXXMethod 'operator[]' 'vector<float, 4> &(vector<uint, 2>) const'
+    | |-ImplicitCastExpr <col:3> 'const RWTexture1DArray<vector<float, 4> >' lvalue <NoOp>
+    | | `-DeclRefExpr <col:3> 'RWTexture1DArray<float4>':'RWTexture1DArray<vector<float, 4> >' lvalue Var 'g_rw_t1da' 'RWTexture1DArray<float4>':'RWTexture1DArray<vector<float, 4> >'
+    | `-ImplicitCastExpr <col:13> 'vector<unsigned int, 2>' <HLSLCC_IntegralCast>
+    |   `-ImplicitCastExpr <col:13> 'int2':'vector<int, 2>' <LValueToRValue>
+    |     `-DeclRefExpr <col:13> 'int2':'vector<int, 2>' lvalue Var 'offset' 'int2':'vector<int, 2>'
+    `-ImplicitCastExpr <col:23> 'float4':'vector<float, 4>' <LValueToRValue>
+      `-DeclRefExpr <col:23> 'float4':'vector<float, 4>' lvalue Var 'f4' 'float4':'vector<float, 4>'
+  */
+  g_rw_t2d[offset] = f4;
+  /*verify-ast
+    BinaryOperator <col:3, col:22> 'vector<float, 4>' '='
+    |-CXXOperatorCallExpr <col:3, col:18> 'vector<float, 4>' lvalue
+    | |-ImplicitCastExpr <col:11, col:18> 'vector<float, 4> &(*)(vector<uint, 2>) const' <FunctionToPointerDecay>
+    | | `-DeclRefExpr <col:11, col:18> 'vector<float, 4> &(vector<uint, 2>) const' lvalue CXXMethod 'operator[]' 'vector<float, 4> &(vector<uint, 2>) const'
+    | |-ImplicitCastExpr <col:3> 'const RWTexture2D<vector<float, 4> >' lvalue <NoOp>
+    | | `-DeclRefExpr <col:3> 'RWTexture2D<float4>':'RWTexture2D<vector<float, 4> >' lvalue Var 'g_rw_t2d' 'RWTexture2D<float4>':'RWTexture2D<vector<float, 4> >'
+    | `-ImplicitCastExpr <col:12> 'vector<unsigned int, 2>' <HLSLCC_IntegralCast>
+    |   `-ImplicitCastExpr <col:12> 'int2':'vector<int, 2>' <LValueToRValue>
+    |     `-DeclRefExpr <col:12> 'int2':'vector<int, 2>' lvalue Var 'offset' 'int2':'vector<int, 2>'
+    `-ImplicitCastExpr <col:22> 'float4':'vector<float, 4>' <LValueToRValue>
+      `-DeclRefExpr <col:22> 'float4':'vector<float, 4>' lvalue Var 'f4' 'float4':'vector<float, 4>'
+  */
+  g_rw_t2da[offset] = f4; /* expected-error {{no viable overloaded operator[] for type 'RWTexture2DArray<float4>'}} expected-note {{candidate function [with element = vector<float, 4> &] not viable: no known conversion from 'vector<int, 2>' to 'vector<uint, 3>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
+  g_rw_t3d[offset] = f4;  /* expected-error {{no viable overloaded operator[] for type 'RWTexture3D<float4>'}} expected-note {{candidate function [with element = vector<float, 4> &] not viable: no known conversion from 'vector<int, 2>' to 'vector<uint, 3>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
+
   return f4;
   return f4;
 }
 }
 
 
@@ -240,6 +347,45 @@ float4 test_vector3_indexing()
   f4 += g_tc[offset]; // expected-error {{type 'TextureCube' does not provide a subscript operator}} fxc-error {{X3121: array, matrix, vector, or indexable object type expected in index expression}}
   f4 += g_tc[offset]; // expected-error {{type 'TextureCube' does not provide a subscript operator}} fxc-error {{X3121: array, matrix, vector, or indexable object type expected in index expression}}
   // fxc error X3121: array, matrix, vector, or indexable object type expected in index expression
   // fxc error X3121: array, matrix, vector, or indexable object type expected in index expression
   f4 += g_tca[offset]; // expected-error {{type 'TextureCubeArray' does not provide a subscript operator}} fxc-error {{X3121: array, matrix, vector, or indexable object type expected in index expression}}
   f4 += g_tca[offset]; // expected-error {{type 'TextureCubeArray' does not provide a subscript operator}} fxc-error {{X3121: array, matrix, vector, or indexable object type expected in index expression}}
+
+  g_t2da[offset] = f4;      /* expected-error {{cannot assign to return value because function 'operator[]<const vector<float, 4> &>' returns a const value}} fxc-error {{X3025: l-value specifies const object}} */
+  g_t2dmsa[offset] = f4;    /* expected-error {{cannot assign to return value because function 'operator[]<const vector<float, 4> &>' returns a const value}} fxc-error {{X3025: l-value specifies const object}} */
+  g_t3d[offset] = f4;       /* expected-error {{cannot assign to return value because function 'operator[]<const vector<float, 4> &>' returns a const value}} fxc-error {{X3025: l-value specifies const object}} */
+
+  g_rw_sb[offset] = f4;     /* expected-error {{no viable overloaded operator[] for type 'RWStructuredBuffer<float4>'}} expected-note {{candidate function [with element = vector<float, 4> &] not viable: no known conversion from 'int3' to 'unsigned int' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
+  g_rw_b[offset] = f4;      /* expected-error {{no viable overloaded operator[] for type 'RWBuffer<float4>'}} expected-note {{candidate function [with element = vector<float, 4> &] not viable: no known conversion from 'int3' to 'unsigned int' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
+  g_rw_t1d[offset] = f4;    /* expected-error {{no viable overloaded operator[] for type 'RWTexture1D<float4>'}} expected-note {{candidate function [with element = vector<float, 4> &] not viable: no known conversion from 'int3' to 'unsigned int' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
+  g_rw_t1da[offset] = f4;   /* expected-error {{no viable overloaded operator[] for type 'RWTexture1DArray<float4>'}} expected-note {{candidate function [with element = vector<float, 4> &] not viable: no known conversion from 'vector<int, 3>' to 'vector<uint, 2>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
+  g_rw_t2d[offset] = f4;    /* expected-error {{no viable overloaded operator[] for type 'RWTexture2D<float4>'}} expected-note {{candidate function [with element = vector<float, 4> &] not viable: no known conversion from 'vector<int, 3>' to 'vector<uint, 2>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
+  g_rw_t2da[offset] = f4;
+  /*verify-ast
+    BinaryOperator <col:3, col:23> 'vector<float, 4>' '='
+    |-CXXOperatorCallExpr <col:3, col:19> 'vector<float, 4>' lvalue
+    | |-ImplicitCastExpr <col:12, col:19> 'vector<float, 4> &(*)(vector<uint, 3>) const' <FunctionToPointerDecay>
+    | | `-DeclRefExpr <col:12, col:19> 'vector<float, 4> &(vector<uint, 3>) const' lvalue CXXMethod 'operator[]' 'vector<float, 4> &(vector<uint, 3>) const'
+    | |-ImplicitCastExpr <col:3> 'const RWTexture2DArray<vector<float, 4> >' lvalue <NoOp>
+    | | `-DeclRefExpr <col:3> 'RWTexture2DArray<float4>':'RWTexture2DArray<vector<float, 4> >' lvalue Var 'g_rw_t2da' 'RWTexture2DArray<float4>':'RWTexture2DArray<vector<float, 4> >'
+    | `-ImplicitCastExpr <col:13> 'vector<unsigned int, 3>' <HLSLCC_IntegralCast>
+    |   `-ImplicitCastExpr <col:13> 'int3':'vector<int, 3>' <LValueToRValue>
+    |     `-DeclRefExpr <col:13> 'int3':'vector<int, 3>' lvalue Var 'offset' 'int3':'vector<int, 3>'
+    `-ImplicitCastExpr <col:23> 'float4':'vector<float, 4>' <LValueToRValue>
+      `-DeclRefExpr <col:23> 'float4':'vector<float, 4>' lvalue Var 'f4' 'float4':'vector<float, 4>'
+  */
+  g_rw_t3d[offset] = f4;
+  /*verify-ast
+    BinaryOperator <col:3, col:22> 'vector<float, 4>' '='
+    |-CXXOperatorCallExpr <col:3, col:18> 'vector<float, 4>' lvalue
+    | |-ImplicitCastExpr <col:11, col:18> 'vector<float, 4> &(*)(vector<uint, 3>) const' <FunctionToPointerDecay>
+    | | `-DeclRefExpr <col:11, col:18> 'vector<float, 4> &(vector<uint, 3>) const' lvalue CXXMethod 'operator[]' 'vector<float, 4> &(vector<uint, 3>) const'
+    | |-ImplicitCastExpr <col:3> 'const RWTexture3D<vector<float, 4> >' lvalue <NoOp>
+    | | `-DeclRefExpr <col:3> 'RWTexture3D<float4>':'RWTexture3D<vector<float, 4> >' lvalue Var 'g_rw_t3d' 'RWTexture3D<float4>':'RWTexture3D<vector<float, 4> >'
+    | `-ImplicitCastExpr <col:12> 'vector<unsigned int, 3>' <HLSLCC_IntegralCast>
+    |   `-ImplicitCastExpr <col:12> 'int3':'vector<int, 3>' <LValueToRValue>
+    |     `-DeclRefExpr <col:12> 'int3':'vector<int, 3>' lvalue Var 'offset' 'int3':'vector<int, 3>'
+    `-ImplicitCastExpr <col:22> 'float4':'vector<float, 4>' <LValueToRValue>
+      `-DeclRefExpr <col:22> 'float4':'vector<float, 4>' lvalue Var 'f4' 'float4':'vector<float, 4>'
+  */
+
   return f4;
   return f4;
 }
 }
 
 
@@ -270,6 +416,21 @@ float4 test_mips_indexing()
   f4 += g_tc.mips[offset]; // expected-error {{no member named 'mips' in 'TextureCube<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'mips'}}
   f4 += g_tc.mips[offset]; // expected-error {{no member named 'mips' in 'TextureCube<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'mips'}}
   // fxc error X3018: invalid subscript 'mips'
   // fxc error X3018: invalid subscript 'mips'
   f4 += g_tca.mips[offset]; // expected-error {{no member named 'mips' in 'TextureCubeArray<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'mips'}}
   f4 += g_tca.mips[offset]; // expected-error {{no member named 'mips' in 'TextureCubeArray<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'mips'}}
+
+  g_t1d.mips[offset] = f4;      /* expected-error {{cannot convert from 'float4' to 'Texture1D<vector<float, 4> >::mips_slice_type'}} fxc-error {{X3025: global variables are implicitly constant, enable compatibility mode to allow modification}} */
+  g_t1da.mips[offset] = f4;     /* expected-error {{cannot convert from 'float4' to 'Texture1DArray<vector<float, 4> >::mips_slice_type'}} fxc-error {{X3025: global variables are implicitly constant, enable compatibility mode to allow modification}} */
+  g_t2d.mips[offset] = f4;      /* expected-error {{cannot convert from 'float4' to 'Texture2D<vector<float, 4> >::mips_slice_type'}} fxc-error {{X3025: global variables are implicitly constant, enable compatibility mode to allow modification}} */
+  g_t2da.mips[offset] = f4;     /* expected-error {{cannot convert from 'float4' to 'Texture2DArray<vector<float, 4> >::mips_slice_type'}} fxc-error {{X3025: global variables are implicitly constant, enable compatibility mode to allow modification}} */
+  g_t3d.mips[offset] = f4;      /* expected-error {{cannot convert from 'float4' to 'Texture3D<vector<float, 4> >::mips_slice_type'}} fxc-error {{X3025: global variables are implicitly constant, enable compatibility mode to allow modification}} */
+
+  g_rw_sb.mips[offset] = f4;    /* expected-error {{no member named 'mips' in 'RWStructuredBuffer<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'mips'}} */
+  g_rw_b.mips[offset] = f4;     /* expected-error {{no member named 'mips' in 'RWBuffer<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'mips'}} */
+  g_rw_t1d.mips[offset] = f4;   /* expected-error {{no member named 'mips' in 'RWTexture1D<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'mips'}} */
+  g_rw_t1da.mips[offset] = f4;  /* expected-error {{no member named 'mips' in 'RWTexture1DArray<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'mips'}} */
+  g_rw_t2d.mips[offset] = f4;   /* expected-error {{no member named 'mips' in 'RWTexture2D<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'mips'}} */
+  g_rw_t2da.mips[offset] = f4;  /* expected-error {{no member named 'mips' in 'RWTexture2DArray<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'mips'}} */
+  g_rw_t3d.mips[offset] = f4;   /* expected-error {{no member named 'mips' in 'RWTexture3D<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'mips'}} */
+
   return f4;
   return f4;
 }
 }
 
 
@@ -280,6 +441,7 @@ float4 test_mips_double_indexing()
   uint pos = 1;
   uint pos = 1;
   uint2 pos2 = { 1, 2 };
   uint2 pos2 = { 1, 2 };
   uint3 pos3 = { 1, 2, 3 };
   uint3 pos3 = { 1, 2, 3 };
+  uint4 pos4 = { 1, 2, 3, 4 };
   float4 f4;
   float4 f4;
   // fxc error X3018: invalid subscript 'mips'
   // fxc error X3018: invalid subscript 'mips'
   f4 += g_b.mips[mipSlice][pos]; // expected-error {{no member named 'mips' in 'Buffer<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'mips'}}
   f4 += g_b.mips[mipSlice][pos]; // expected-error {{no member named 'mips' in 'Buffer<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'mips'}}
@@ -291,10 +453,10 @@ float4 test_mips_double_indexing()
       `-CXXOperatorCallExpr <col:9, col:33> 'const vector<float, 4>' lvalue
       `-CXXOperatorCallExpr <col:9, col:33> 'const vector<float, 4>' lvalue
         |-ImplicitCastExpr <col:29, col:33> 'const vector<float, 4> &(*)(unsigned int) const' <FunctionToPointerDecay>
         |-ImplicitCastExpr <col:29, col:33> 'const vector<float, 4> &(*)(unsigned int) const' <FunctionToPointerDecay>
         | `-DeclRefExpr <col:29, col:33> 'const vector<float, 4> &(unsigned int) const' lvalue CXXMethod 'operator[]' 'const vector<float, 4> &(unsigned int) const'
         | `-DeclRefExpr <col:29, col:33> 'const vector<float, 4> &(unsigned int) const' lvalue CXXMethod 'operator[]' 'const vector<float, 4> &(unsigned int) const'
-        |-ImplicitCastExpr <col:9, col:28> 'const Texture1D<vector<float, 4> >::mips_slice_type' xvalue <NoOp>
-        | `-CXXOperatorCallExpr <col:9, col:28> 'Texture1D<vector<float, 4> >::mips_slice_type' xvalue
-        |   |-ImplicitCastExpr <col:19, col:28> 'Texture1D<vector<float, 4> >::mips_slice_type &&(*)(unsigned int) const' <FunctionToPointerDecay>
-        |   | `-DeclRefExpr <col:19, col:28> 'Texture1D<vector<float, 4> >::mips_slice_type &&(unsigned int) const' lvalue CXXMethod 'operator[]' 'Texture1D<vector<float, 4> >::mips_slice_type &&(unsigned int) const'
+        |-ImplicitCastExpr <col:9, col:28> 'const Texture1D<vector<float, 4> >::mips_slice_type' lvalue <NoOp>
+        | `-CXXOperatorCallExpr <col:9, col:28> 'Texture1D<vector<float, 4> >::mips_slice_type' lvalue
+        |   |-ImplicitCastExpr <col:19, col:28> 'Texture1D<vector<float, 4> >::mips_slice_type &(*)(unsigned int) const' <FunctionToPointerDecay>
+        |   | `-DeclRefExpr <col:19, col:28> 'Texture1D<vector<float, 4> >::mips_slice_type &(unsigned int) const' lvalue CXXMethod 'operator[]' 'Texture1D<vector<float, 4> >::mips_slice_type &(unsigned int) const'
         |   |-ImplicitCastExpr <col:9, col:15> 'const Texture1D<vector<float, 4> >::mips_type' lvalue <NoOp>
         |   |-ImplicitCastExpr <col:9, col:15> 'const Texture1D<vector<float, 4> >::mips_type' lvalue <NoOp>
         |   | `-MemberExpr <col:9, col:15> 'Texture1D<vector<float, 4> >::mips_type' lvalue .mips
         |   | `-MemberExpr <col:9, col:15> 'Texture1D<vector<float, 4> >::mips_type' lvalue .mips
         |   |   `-DeclRefExpr <col:9> 'Texture1D':'Texture1D<vector<float, 4> >' lvalue Var 'g_t1d' 'Texture1D':'Texture1D<vector<float, 4> >'
         |   |   `-DeclRefExpr <col:9> 'Texture1D':'Texture1D<vector<float, 4> >' lvalue Var 'g_t1d' 'Texture1D':'Texture1D<vector<float, 4> >'
@@ -303,6 +465,9 @@ float4 test_mips_double_indexing()
         `-ImplicitCastExpr <col:30> 'uint':'unsigned int' <LValueToRValue>
         `-ImplicitCastExpr <col:30> 'uint':'unsigned int' <LValueToRValue>
           `-DeclRefExpr <col:30> 'uint':'unsigned int' lvalue Var 'pos' 'uint':'unsigned int'
           `-DeclRefExpr <col:30> 'uint':'unsigned int' lvalue Var 'pos' 'uint':'unsigned int'
   */
   */
+  f4 += g_t1d.mips[mipSlice][pos2]; /* expected-error {{no viable overloaded operator[] for type 'Texture1D<vector<float, 4> >::mips_slice_type'}} expected-note {{candidate function [with element = const vector<float, 4> &] not viable: no known conversion from 'uint2' to 'unsigned int' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
+  f4 += g_t1d.mips[mipSlice][pos3]; /* expected-error {{no viable overloaded operator[] for type 'Texture1D<vector<float, 4> >::mips_slice_type'}} expected-note {{candidate function [with element = const vector<float, 4> &] not viable: no known conversion from 'uint3' to 'unsigned int' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
+  f4 += g_t1d.mips[mipSlice][pos4]; /* expected-error {{no viable overloaded operator[] for type 'Texture1D<vector<float, 4> >::mips_slice_type'}} expected-note {{candidate function [with element = const vector<float, 4> &] not viable: no known conversion from 'uint4' to 'unsigned int' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
   // fxc error X3018: invalid subscript 'mips'
   // fxc error X3018: invalid subscript 'mips'
   f4 += g_sb.mips[mipSlice][pos]; // expected-error {{no member named 'mips' in 'StructuredBuffer<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'mips'}}
   f4 += g_sb.mips[mipSlice][pos]; // expected-error {{no member named 'mips' in 'StructuredBuffer<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'mips'}}
   // fxc error X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions
   // fxc error X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions
@@ -315,10 +480,10 @@ float4 test_mips_double_indexing()
       `-CXXOperatorCallExpr <col:9, col:35> 'const vector<float, 4>' lvalue
       `-CXXOperatorCallExpr <col:9, col:35> 'const vector<float, 4>' lvalue
         |-ImplicitCastExpr <col:30, col:35> 'const vector<float, 4> &(*)(vector<uint, 2>) const' <FunctionToPointerDecay>
         |-ImplicitCastExpr <col:30, col:35> 'const vector<float, 4> &(*)(vector<uint, 2>) const' <FunctionToPointerDecay>
         | `-DeclRefExpr <col:30, col:35> 'const vector<float, 4> &(vector<uint, 2>) const' lvalue CXXMethod 'operator[]' 'const vector<float, 4> &(vector<uint, 2>) const'
         | `-DeclRefExpr <col:30, col:35> 'const vector<float, 4> &(vector<uint, 2>) const' lvalue CXXMethod 'operator[]' 'const vector<float, 4> &(vector<uint, 2>) const'
-        |-ImplicitCastExpr <col:9, col:29> 'const Texture1DArray<vector<float, 4> >::mips_slice_type' xvalue <NoOp>
-        | `-CXXOperatorCallExpr <col:9, col:29> 'Texture1DArray<vector<float, 4> >::mips_slice_type' xvalue
-        |   |-ImplicitCastExpr <col:20, col:29> 'Texture1DArray<vector<float, 4> >::mips_slice_type &&(*)(unsigned int) const' <FunctionToPointerDecay>
-        |   | `-DeclRefExpr <col:20, col:29> 'Texture1DArray<vector<float, 4> >::mips_slice_type &&(unsigned int) const' lvalue CXXMethod 'operator[]' 'Texture1DArray<vector<float, 4> >::mips_slice_type &&(unsigned int) const'
+        |-ImplicitCastExpr <col:9, col:29> 'const Texture1DArray<vector<float, 4> >::mips_slice_type' lvalue <NoOp>
+        | `-CXXOperatorCallExpr <col:9, col:29> 'Texture1DArray<vector<float, 4> >::mips_slice_type' lvalue
+        |   |-ImplicitCastExpr <col:20, col:29> 'Texture1DArray<vector<float, 4> >::mips_slice_type &(*)(unsigned int) const' <FunctionToPointerDecay>
+        |   | `-DeclRefExpr <col:20, col:29> 'Texture1DArray<vector<float, 4> >::mips_slice_type &(unsigned int) const' lvalue CXXMethod 'operator[]' 'Texture1DArray<vector<float, 4> >::mips_slice_type &(unsigned int) const'
         |   |-ImplicitCastExpr <col:9, col:16> 'const Texture1DArray<vector<float, 4> >::mips_type' lvalue <NoOp>
         |   |-ImplicitCastExpr <col:9, col:16> 'const Texture1DArray<vector<float, 4> >::mips_type' lvalue <NoOp>
         |   | `-MemberExpr <col:9, col:16> 'Texture1DArray<vector<float, 4> >::mips_type' lvalue .mips
         |   | `-MemberExpr <col:9, col:16> 'Texture1DArray<vector<float, 4> >::mips_type' lvalue .mips
         |   |   `-DeclRefExpr <col:9> 'Texture1DArray':'Texture1DArray<vector<float, 4> >' lvalue Var 'g_t1da' 'Texture1DArray':'Texture1DArray<vector<float, 4> >'
         |   |   `-DeclRefExpr <col:9> 'Texture1DArray':'Texture1DArray<vector<float, 4> >' lvalue Var 'g_t1da' 'Texture1DArray':'Texture1DArray<vector<float, 4> >'
@@ -327,6 +492,8 @@ float4 test_mips_double_indexing()
         `-ImplicitCastExpr <col:31> 'uint2':'vector<unsigned int, 2>' <LValueToRValue>
         `-ImplicitCastExpr <col:31> 'uint2':'vector<unsigned int, 2>' <LValueToRValue>
           `-DeclRefExpr <col:31> 'uint2':'vector<unsigned int, 2>' lvalue Var 'pos2' 'uint2':'vector<unsigned int, 2>'
           `-DeclRefExpr <col:31> 'uint2':'vector<unsigned int, 2>' lvalue Var 'pos2' 'uint2':'vector<unsigned int, 2>'
   */
   */
+  f4 += g_t1da.mips[mipSlice][pos3];  /* expected-error {{no viable overloaded operator[] for type 'Texture1DArray<vector<float, 4> >::mips_slice_type'}} expected-note {{candidate function [with element = const vector<float, 4> &] not viable: no known conversion from 'vector<[...], 3>' to 'vector<[...], 2>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
+  f4 += g_t1da.mips[mipSlice][pos4];  /* expected-error {{no viable overloaded operator[] for type 'Texture1DArray<vector<float, 4> >::mips_slice_type'}} expected-note {{candidate function [with element = const vector<float, 4> &] not viable: no known conversion from 'vector<[...], 4>' to 'vector<[...], 2>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
   // fxc error X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions
   // fxc error X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions
   f4 += g_t2d.mips[mipSlice][pos]; // expected-error {{no viable overloaded operator[] for type 'Texture2D<vector<float, 4> >::mips_slice_type'}} expected-note {{candidate function [with element = const vector<float, 4> &] not viable: no known conversion from 'uint' to 'vector<uint, 2>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}}
   f4 += g_t2d.mips[mipSlice][pos]; // expected-error {{no viable overloaded operator[] for type 'Texture2D<vector<float, 4> >::mips_slice_type'}} expected-note {{candidate function [with element = const vector<float, 4> &] not viable: no known conversion from 'uint' to 'vector<uint, 2>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}}
   f4 += g_t2d.mips[mipSlice][pos2];
   f4 += g_t2d.mips[mipSlice][pos2];
@@ -337,10 +504,10 @@ float4 test_mips_double_indexing()
       `-CXXOperatorCallExpr <col:9, col:34> 'const vector<float, 4>' lvalue
       `-CXXOperatorCallExpr <col:9, col:34> 'const vector<float, 4>' lvalue
         |-ImplicitCastExpr <col:29, col:34> 'const vector<float, 4> &(*)(vector<uint, 2>) const' <FunctionToPointerDecay>
         |-ImplicitCastExpr <col:29, col:34> 'const vector<float, 4> &(*)(vector<uint, 2>) const' <FunctionToPointerDecay>
         | `-DeclRefExpr <col:29, col:34> 'const vector<float, 4> &(vector<uint, 2>) const' lvalue CXXMethod 'operator[]' 'const vector<float, 4> &(vector<uint, 2>) const'
         | `-DeclRefExpr <col:29, col:34> 'const vector<float, 4> &(vector<uint, 2>) const' lvalue CXXMethod 'operator[]' 'const vector<float, 4> &(vector<uint, 2>) const'
-        |-ImplicitCastExpr <col:9, col:28> 'const Texture2D<vector<float, 4> >::mips_slice_type' xvalue <NoOp>
-        | `-CXXOperatorCallExpr <col:9, col:28> 'Texture2D<vector<float, 4> >::mips_slice_type' xvalue
-        |   |-ImplicitCastExpr <col:19, col:28> 'Texture2D<vector<float, 4> >::mips_slice_type &&(*)(unsigned int) const' <FunctionToPointerDecay>
-        |   | `-DeclRefExpr <col:19, col:28> 'Texture2D<vector<float, 4> >::mips_slice_type &&(unsigned int) const' lvalue CXXMethod 'operator[]' 'Texture2D<vector<float, 4> >::mips_slice_type &&(unsigned int) const'
+        |-ImplicitCastExpr <col:9, col:28> 'const Texture2D<vector<float, 4> >::mips_slice_type' lvalue <NoOp>
+        | `-CXXOperatorCallExpr <col:9, col:28> 'Texture2D<vector<float, 4> >::mips_slice_type' lvalue
+        |   |-ImplicitCastExpr <col:19, col:28> 'Texture2D<vector<float, 4> >::mips_slice_type &(*)(unsigned int) const' <FunctionToPointerDecay>
+        |   | `-DeclRefExpr <col:19, col:28> 'Texture2D<vector<float, 4> >::mips_slice_type &(unsigned int) const' lvalue CXXMethod 'operator[]' 'Texture2D<vector<float, 4> >::mips_slice_type &(unsigned int) const'
         |   |-ImplicitCastExpr <col:9, col:15> 'const Texture2D<vector<float, 4> >::mips_type' lvalue <NoOp>
         |   |-ImplicitCastExpr <col:9, col:15> 'const Texture2D<vector<float, 4> >::mips_type' lvalue <NoOp>
         |   | `-MemberExpr <col:9, col:15> 'Texture2D<vector<float, 4> >::mips_type' lvalue .mips
         |   | `-MemberExpr <col:9, col:15> 'Texture2D<vector<float, 4> >::mips_type' lvalue .mips
         |   |   `-DeclRefExpr <col:9> 'Texture2D':'Texture2D<vector<float, 4> >' lvalue Var 'g_t2d' 'Texture2D':'Texture2D<vector<float, 4> >'
         |   |   `-DeclRefExpr <col:9> 'Texture2D':'Texture2D<vector<float, 4> >' lvalue Var 'g_t2d' 'Texture2D':'Texture2D<vector<float, 4> >'
@@ -351,6 +518,7 @@ float4 test_mips_double_indexing()
   */
   */
   // fxc error X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions
   // fxc error X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions
   f4 += g_t2da.mips[mipSlice][pos]; // expected-error {{no viable overloaded operator[] for type 'Texture2DArray<vector<float, 4> >::mips_slice_type'}} expected-note {{candidate function [with element = const vector<float, 4> &] not viable: no known conversion from 'uint' to 'vector<uint, 3>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}}
   f4 += g_t2da.mips[mipSlice][pos]; // expected-error {{no viable overloaded operator[] for type 'Texture2DArray<vector<float, 4> >::mips_slice_type'}} expected-note {{candidate function [with element = const vector<float, 4> &] not viable: no known conversion from 'uint' to 'vector<uint, 3>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}}
+  f4 += g_t2da.mips[mipSlice][pos2];  /* expected-error {{no viable overloaded operator[] for type 'Texture2DArray<vector<float, 4> >::mips_slice_type'}} expected-note {{candidate function [with element = const vector<float, 4> &] not viable: no known conversion from 'vector<[...], 2>' to 'vector<[...], 3>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
   f4 += g_t2da.mips[mipSlice][pos3];
   f4 += g_t2da.mips[mipSlice][pos3];
   /*verify-ast
   /*verify-ast
     CompoundAssignOperator <col:3, col:35> 'float4':'vector<float, 4>' lvalue '+=' ComputeLHSTy='float4':'vector<float, 4>' ComputeResultTy='float4':'vector<float, 4>'
     CompoundAssignOperator <col:3, col:35> 'float4':'vector<float, 4>' lvalue '+=' ComputeLHSTy='float4':'vector<float, 4>' ComputeResultTy='float4':'vector<float, 4>'
@@ -359,10 +527,10 @@ float4 test_mips_double_indexing()
       `-CXXOperatorCallExpr <col:9, col:35> 'const vector<float, 4>' lvalue
       `-CXXOperatorCallExpr <col:9, col:35> 'const vector<float, 4>' lvalue
         |-ImplicitCastExpr <col:30, col:35> 'const vector<float, 4> &(*)(vector<uint, 3>) const' <FunctionToPointerDecay>
         |-ImplicitCastExpr <col:30, col:35> 'const vector<float, 4> &(*)(vector<uint, 3>) const' <FunctionToPointerDecay>
         | `-DeclRefExpr <col:30, col:35> 'const vector<float, 4> &(vector<uint, 3>) const' lvalue CXXMethod 'operator[]' 'const vector<float, 4> &(vector<uint, 3>) const'
         | `-DeclRefExpr <col:30, col:35> 'const vector<float, 4> &(vector<uint, 3>) const' lvalue CXXMethod 'operator[]' 'const vector<float, 4> &(vector<uint, 3>) const'
-        |-ImplicitCastExpr <col:9, col:29> 'const Texture2DArray<vector<float, 4> >::mips_slice_type' xvalue <NoOp>
-        | `-CXXOperatorCallExpr <col:9, col:29> 'Texture2DArray<vector<float, 4> >::mips_slice_type' xvalue
-        |   |-ImplicitCastExpr <col:20, col:29> 'Texture2DArray<vector<float, 4> >::mips_slice_type &&(*)(unsigned int) const' <FunctionToPointerDecay>
-        |   | `-DeclRefExpr <col:20, col:29> 'Texture2DArray<vector<float, 4> >::mips_slice_type &&(unsigned int) const' lvalue CXXMethod 'operator[]' 'Texture2DArray<vector<float, 4> >::mips_slice_type &&(unsigned int) const'
+        |-ImplicitCastExpr <col:9, col:29> 'const Texture2DArray<vector<float, 4> >::mips_slice_type' lvalue <NoOp>
+        | `-CXXOperatorCallExpr <col:9, col:29> 'Texture2DArray<vector<float, 4> >::mips_slice_type' lvalue
+        |   |-ImplicitCastExpr <col:20, col:29> 'Texture2DArray<vector<float, 4> >::mips_slice_type &(*)(unsigned int) const' <FunctionToPointerDecay>
+        |   | `-DeclRefExpr <col:20, col:29> 'Texture2DArray<vector<float, 4> >::mips_slice_type &(unsigned int) const' lvalue CXXMethod 'operator[]' 'Texture2DArray<vector<float, 4> >::mips_slice_type &(unsigned int) const'
         |   |-ImplicitCastExpr <col:9, col:16> 'const Texture2DArray<vector<float, 4> >::mips_type' lvalue <NoOp>
         |   |-ImplicitCastExpr <col:9, col:16> 'const Texture2DArray<vector<float, 4> >::mips_type' lvalue <NoOp>
         |   | `-MemberExpr <col:9, col:16> 'Texture2DArray<vector<float, 4> >::mips_type' lvalue .mips
         |   | `-MemberExpr <col:9, col:16> 'Texture2DArray<vector<float, 4> >::mips_type' lvalue .mips
         |   |   `-DeclRefExpr <col:9> 'Texture2DArray':'Texture2DArray<vector<float, 4> >' lvalue Var 'g_t2da' 'Texture2DArray':'Texture2DArray<vector<float, 4> >'
         |   |   `-DeclRefExpr <col:9> 'Texture2DArray':'Texture2DArray<vector<float, 4> >' lvalue Var 'g_t2da' 'Texture2DArray':'Texture2DArray<vector<float, 4> >'
@@ -371,12 +539,14 @@ float4 test_mips_double_indexing()
         `-ImplicitCastExpr <col:31> 'uint3':'vector<unsigned int, 3>' <LValueToRValue>
         `-ImplicitCastExpr <col:31> 'uint3':'vector<unsigned int, 3>' <LValueToRValue>
           `-DeclRefExpr <col:31> 'uint3':'vector<unsigned int, 3>' lvalue Var 'pos3' 'uint3':'vector<unsigned int, 3>'
           `-DeclRefExpr <col:31> 'uint3':'vector<unsigned int, 3>' lvalue Var 'pos3' 'uint3':'vector<unsigned int, 3>'
   */
   */
+  f4 += g_t2da.mips[mipSlice][pos4];  /* expected-error {{no viable overloaded operator[] for type 'Texture2DArray<vector<float, 4> >::mips_slice_type'}} expected-note {{candidate function [with element = const vector<float, 4> &] not viable: no known conversion from 'vector<[...], 4>' to 'vector<[...], 3>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */
   // fxc error X3018: invalid subscript 'mips'
   // fxc error X3018: invalid subscript 'mips'
   f4 += g_t2dms.mips[mipSlice][pos]; // expected-error {{no member named 'mips' in 'Texture2DMS<vector<float, 4>, 8>'}} fxc-error {{X3018: invalid subscript 'mips'}}
   f4 += g_t2dms.mips[mipSlice][pos]; // expected-error {{no member named 'mips' in 'Texture2DMS<vector<float, 4>, 8>'}} fxc-error {{X3018: invalid subscript 'mips'}}
   // fxc error X3018: invalid subscript 'mips'
   // fxc error X3018: invalid subscript 'mips'
   f4 += g_t2dmsa.mips[mipSlice][pos]; // expected-error {{no member named 'mips' in 'Texture2DMSArray<vector<float, 4>, 8>'}} fxc-error {{X3018: invalid subscript 'mips'}}
   f4 += g_t2dmsa.mips[mipSlice][pos]; // expected-error {{no member named 'mips' in 'Texture2DMSArray<vector<float, 4>, 8>'}} fxc-error {{X3018: invalid subscript 'mips'}}
   // fxc error X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions
   // fxc error X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions
   f4 += g_t3d.mips[mipSlice][pos]; // expected-error {{no viable overloaded operator[] for type 'Texture3D<vector<float, 4> >::mips_slice_type'}} expected-note {{candidate function [with element = const vector<float, 4> &] not viable: no known conversion from 'uint' to 'vector<uint, 3>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}}
   f4 += g_t3d.mips[mipSlice][pos]; // expected-error {{no viable overloaded operator[] for type 'Texture3D<vector<float, 4> >::mips_slice_type'}} expected-note {{candidate function [with element = const vector<float, 4> &] not viable: no known conversion from 'uint' to 'vector<uint, 3>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}}
+  f4 += g_t3d.mips[mipSlice][pos2]; // expected-error {{no viable overloaded operator[] for type 'Texture3D<vector<float, 4> >::mips_slice_type'}} expected-note {{candidate function [with element = const vector<float, 4> &] not viable: no known conversion from 'vector<[...], 2>' to 'vector<[...], 3>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}}
   f4 += g_t3d.mips[mipSlice][pos3];
   f4 += g_t3d.mips[mipSlice][pos3];
   /*verify-ast
   /*verify-ast
     CompoundAssignOperator <col:3, col:34> 'float4':'vector<float, 4>' lvalue '+=' ComputeLHSTy='float4':'vector<float, 4>' ComputeResultTy='float4':'vector<float, 4>'
     CompoundAssignOperator <col:3, col:34> 'float4':'vector<float, 4>' lvalue '+=' ComputeLHSTy='float4':'vector<float, 4>' ComputeResultTy='float4':'vector<float, 4>'
@@ -385,10 +555,10 @@ float4 test_mips_double_indexing()
       `-CXXOperatorCallExpr <col:9, col:34> 'const vector<float, 4>' lvalue
       `-CXXOperatorCallExpr <col:9, col:34> 'const vector<float, 4>' lvalue
         |-ImplicitCastExpr <col:29, col:34> 'const vector<float, 4> &(*)(vector<uint, 3>) const' <FunctionToPointerDecay>
         |-ImplicitCastExpr <col:29, col:34> 'const vector<float, 4> &(*)(vector<uint, 3>) const' <FunctionToPointerDecay>
         | `-DeclRefExpr <col:29, col:34> 'const vector<float, 4> &(vector<uint, 3>) const' lvalue CXXMethod 'operator[]' 'const vector<float, 4> &(vector<uint, 3>) const'
         | `-DeclRefExpr <col:29, col:34> 'const vector<float, 4> &(vector<uint, 3>) const' lvalue CXXMethod 'operator[]' 'const vector<float, 4> &(vector<uint, 3>) const'
-        |-ImplicitCastExpr <col:9, col:28> 'const Texture3D<vector<float, 4> >::mips_slice_type' xvalue <NoOp>
-        | `-CXXOperatorCallExpr <col:9, col:28> 'Texture3D<vector<float, 4> >::mips_slice_type' xvalue
-        |   |-ImplicitCastExpr <col:19, col:28> 'Texture3D<vector<float, 4> >::mips_slice_type &&(*)(unsigned int) const' <FunctionToPointerDecay>
-        |   | `-DeclRefExpr <col:19, col:28> 'Texture3D<vector<float, 4> >::mips_slice_type &&(unsigned int) const' lvalue CXXMethod 'operator[]' 'Texture3D<vector<float, 4> >::mips_slice_type &&(unsigned int) const'
+        |-ImplicitCastExpr <col:9, col:28> 'const Texture3D<vector<float, 4> >::mips_slice_type' lvalue <NoOp>
+        | `-CXXOperatorCallExpr <col:9, col:28> 'Texture3D<vector<float, 4> >::mips_slice_type' lvalue
+        |   |-ImplicitCastExpr <col:19, col:28> 'Texture3D<vector<float, 4> >::mips_slice_type &(*)(unsigned int) const' <FunctionToPointerDecay>
+        |   | `-DeclRefExpr <col:19, col:28> 'Texture3D<vector<float, 4> >::mips_slice_type &(unsigned int) const' lvalue CXXMethod 'operator[]' 'Texture3D<vector<float, 4> >::mips_slice_type &(unsigned int) const'
         |   |-ImplicitCastExpr <col:9, col:15> 'const Texture3D<vector<float, 4> >::mips_type' lvalue <NoOp>
         |   |-ImplicitCastExpr <col:9, col:15> 'const Texture3D<vector<float, 4> >::mips_type' lvalue <NoOp>
         |   | `-MemberExpr <col:9, col:15> 'Texture3D<vector<float, 4> >::mips_type' lvalue .mips
         |   | `-MemberExpr <col:9, col:15> 'Texture3D<vector<float, 4> >::mips_type' lvalue .mips
         |   |   `-DeclRefExpr <col:9> 'Texture3D':'Texture3D<vector<float, 4> >' lvalue Var 'g_t3d' 'Texture3D':'Texture3D<vector<float, 4> >'
         |   |   `-DeclRefExpr <col:9> 'Texture3D':'Texture3D<vector<float, 4> >' lvalue Var 'g_t3d' 'Texture3D':'Texture3D<vector<float, 4> >'
@@ -397,10 +567,18 @@ float4 test_mips_double_indexing()
         `-ImplicitCastExpr <col:30> 'uint3':'vector<unsigned int, 3>' <LValueToRValue>
         `-ImplicitCastExpr <col:30> 'uint3':'vector<unsigned int, 3>' <LValueToRValue>
           `-DeclRefExpr <col:30> 'uint3':'vector<unsigned int, 3>' lvalue Var 'pos3' 'uint3':'vector<unsigned int, 3>'
           `-DeclRefExpr <col:30> 'uint3':'vector<unsigned int, 3>' lvalue Var 'pos3' 'uint3':'vector<unsigned int, 3>'
   */
   */
+  f4 += g_t3d.mips[mipSlice][pos4]; // expected-error {{no viable overloaded operator[] for type 'Texture3D<vector<float, 4> >::mips_slice_type'}} expected-note {{candidate function [with element = const vector<float, 4> &] not viable: no known conversion from 'vector<[...], 4>' to 'vector<[...], 3>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}}
   // fxc error X3018: invalid subscript 'mips'
   // fxc error X3018: invalid subscript 'mips'
   f4 += g_tc.mips[mipSlice][pos]; // expected-error {{no member named 'mips' in 'TextureCube<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'mips'}}
   f4 += g_tc.mips[mipSlice][pos]; // expected-error {{no member named 'mips' in 'TextureCube<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'mips'}}
   // fxc error X3018: invalid subscript 'mips'
   // fxc error X3018: invalid subscript 'mips'
   f4 += g_tca.mips[mipSlice][pos]; // expected-error {{no member named 'mips' in 'TextureCubeArray<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'mips'}}
   f4 += g_tca.mips[mipSlice][pos]; // expected-error {{no member named 'mips' in 'TextureCubeArray<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'mips'}}
+
+  g_t1d.mips[mipSlice][pos] = f4;       /* expected-error {{cannot assign to return value because function 'operator[]<const vector<float, 4> &>' returns a const value}} fxc-error {{X3025: l-value specifies const object}} */
+  g_t1da.mips[mipSlice][pos2] = f4;     /* expected-error {{cannot assign to return value because function 'operator[]<const vector<float, 4> &>' returns a const value}} fxc-error {{X3025: l-value specifies const object}} */
+  g_t2d.mips[mipSlice][pos2] = f4;      /* expected-error {{cannot assign to return value because function 'operator[]<const vector<float, 4> &>' returns a const value}} fxc-error {{X3025: l-value specifies const object}} */
+  g_t2da.mips[mipSlice][pos3] = f4;     /* expected-error {{cannot assign to return value because function 'operator[]<const vector<float, 4> &>' returns a const value}} fxc-error {{X3025: l-value specifies const object}} */
+  g_t3d.mips[mipSlice][pos3] = f4;      /* expected-error {{cannot assign to return value because function 'operator[]<const vector<float, 4> &>' returns a const value}} fxc-error {{X3025: l-value specifies const object}} */
+
   return f4;
   return f4;
 }
 }
 
 
@@ -431,6 +609,10 @@ float4 test_sample_indexing()
   f4 += g_tc.sample[offset]; // expected-error {{no member named 'sample' in 'TextureCube<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'sample'}}
   f4 += g_tc.sample[offset]; // expected-error {{no member named 'sample' in 'TextureCube<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'sample'}}
   // fxc error X3018: invalid subscript 'sample'
   // fxc error X3018: invalid subscript 'sample'
   f4 += g_tca.sample[offset]; // expected-error {{no member named 'sample' in 'TextureCubeArray<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'sample'}}
   f4 += g_tca.sample[offset]; // expected-error {{no member named 'sample' in 'TextureCubeArray<vector<float, 4> >'}} fxc-error {{X3018: invalid subscript 'sample'}}
+
+  g_t2dms.sample[offset] = f4;      /* expected-error {{cannot convert from 'float4' to 'Texture2DMS<vector<float, 4>, 8>::sample_slice_type'}} fxc-error {{X3025: global variables are implicitly constant, enable compatibility mode to allow modification}} */
+  g_t2dmsa.sample[offset] = f4;     /* expected-error {{cannot convert from 'float4' to 'Texture2DMSArray<vector<float, 4>, 8>::sample_slice_type'}} fxc-error {{X3025: global variables are implicitly constant, enable compatibility mode to allow modification}} */
+
   return f4;
   return f4;
 }
 }
 
 
@@ -452,10 +634,10 @@ float4 test_sample_double_indexing()
       `-CXXOperatorCallExpr <col:9, col:41> 'const vector<float, 4>' lvalue
       `-CXXOperatorCallExpr <col:9, col:41> 'const vector<float, 4>' lvalue
         |-ImplicitCastExpr <col:36, col:41> 'const vector<float, 4> &(*)(vector<uint, 2>) const' <FunctionToPointerDecay>
         |-ImplicitCastExpr <col:36, col:41> 'const vector<float, 4> &(*)(vector<uint, 2>) const' <FunctionToPointerDecay>
         | `-DeclRefExpr <col:36, col:41> 'const vector<float, 4> &(vector<uint, 2>) const' lvalue CXXMethod 'operator[]' 'const vector<float, 4> &(vector<uint, 2>) const'
         | `-DeclRefExpr <col:36, col:41> 'const vector<float, 4> &(vector<uint, 2>) const' lvalue CXXMethod 'operator[]' 'const vector<float, 4> &(vector<uint, 2>) const'
-        |-ImplicitCastExpr <col:9, col:35> 'const Texture2DMS<vector<float, 4>, 8>::sample_slice_type' xvalue <NoOp>
-        | `-CXXOperatorCallExpr <col:9, col:35> 'Texture2DMS<vector<float, 4>, 8>::sample_slice_type' xvalue
-        |   |-ImplicitCastExpr <col:23, col:35> 'Texture2DMS<vector<float, 4>, 8>::sample_slice_type &&(*)(unsigned int) const' <FunctionToPointerDecay>
-        |   | `-DeclRefExpr <col:23, col:35> 'Texture2DMS<vector<float, 4>, 8>::sample_slice_type &&(unsigned int) const' lvalue CXXMethod 'operator[]' 'Texture2DMS<vector<float, 4>, 8>::sample_slice_type &&(unsigned int) const'
+        |-ImplicitCastExpr <col:9, col:35> 'const Texture2DMS<vector<float, 4>, 8>::sample_slice_type' lvalue <NoOp>
+        | `-CXXOperatorCallExpr <col:9, col:35> 'Texture2DMS<vector<float, 4>, 8>::sample_slice_type' lvalue
+        |   |-ImplicitCastExpr <col:23, col:35> 'Texture2DMS<vector<float, 4>, 8>::sample_slice_type &(*)(unsigned int) const' <FunctionToPointerDecay>
+        |   | `-DeclRefExpr <col:23, col:35> 'Texture2DMS<vector<float, 4>, 8>::sample_slice_type &(unsigned int) const' lvalue CXXMethod 'operator[]' 'Texture2DMS<vector<float, 4>, 8>::sample_slice_type &(unsigned int) const'
         |   |-ImplicitCastExpr <col:9, col:17> 'const Texture2DMS<vector<float, 4>, 8>::sample_type' lvalue <NoOp>
         |   |-ImplicitCastExpr <col:9, col:17> 'const Texture2DMS<vector<float, 4>, 8>::sample_type' lvalue <NoOp>
         |   | `-MemberExpr <col:9, col:17> 'Texture2DMS<vector<float, 4>, 8>::sample_type' lvalue .sample
         |   | `-MemberExpr <col:9, col:17> 'Texture2DMS<vector<float, 4>, 8>::sample_type' lvalue .sample
         |   |   `-DeclRefExpr <col:9> 'Texture2DMS<float4, 8>':'Texture2DMS<vector<float, 4>, 8>' lvalue Var 'g_t2dms' 'Texture2DMS<float4, 8>':'Texture2DMS<vector<float, 4>, 8>'
         |   |   `-DeclRefExpr <col:9> 'Texture2DMS<float4, 8>':'Texture2DMS<vector<float, 4>, 8>' lvalue Var 'g_t2dms' 'Texture2DMS<float4, 8>':'Texture2DMS<vector<float, 4>, 8>'
@@ -474,10 +656,10 @@ float4 test_sample_double_indexing()
       `-CXXOperatorCallExpr <col:9, col:42> 'const vector<float, 4>' lvalue
       `-CXXOperatorCallExpr <col:9, col:42> 'const vector<float, 4>' lvalue
         |-ImplicitCastExpr <col:37, col:42> 'const vector<float, 4> &(*)(vector<uint, 3>) const' <FunctionToPointerDecay>
         |-ImplicitCastExpr <col:37, col:42> 'const vector<float, 4> &(*)(vector<uint, 3>) const' <FunctionToPointerDecay>
         | `-DeclRefExpr <col:37, col:42> 'const vector<float, 4> &(vector<uint, 3>) const' lvalue CXXMethod 'operator[]' 'const vector<float, 4> &(vector<uint, 3>) const'
         | `-DeclRefExpr <col:37, col:42> 'const vector<float, 4> &(vector<uint, 3>) const' lvalue CXXMethod 'operator[]' 'const vector<float, 4> &(vector<uint, 3>) const'
-        |-ImplicitCastExpr <col:9, col:36> 'const Texture2DMSArray<vector<float, 4>, 8>::sample_slice_type' xvalue <NoOp>
-        | `-CXXOperatorCallExpr <col:9, col:36> 'Texture2DMSArray<vector<float, 4>, 8>::sample_slice_type' xvalue
-        |   |-ImplicitCastExpr <col:24, col:36> 'Texture2DMSArray<vector<float, 4>, 8>::sample_slice_type &&(*)(unsigned int) const' <FunctionToPointerDecay>
-        |   | `-DeclRefExpr <col:24, col:36> 'Texture2DMSArray<vector<float, 4>, 8>::sample_slice_type &&(unsigned int) const' lvalue CXXMethod 'operator[]' 'Texture2DMSArray<vector<float, 4>, 8>::sample_slice_type &&(unsigned int) const'
+        |-ImplicitCastExpr <col:9, col:36> 'const Texture2DMSArray<vector<float, 4>, 8>::sample_slice_type' lvalue <NoOp>
+        | `-CXXOperatorCallExpr <col:9, col:36> 'Texture2DMSArray<vector<float, 4>, 8>::sample_slice_type' lvalue
+        |   |-ImplicitCastExpr <col:24, col:36> 'Texture2DMSArray<vector<float, 4>, 8>::sample_slice_type &(*)(unsigned int) const' <FunctionToPointerDecay>
+        |   | `-DeclRefExpr <col:24, col:36> 'Texture2DMSArray<vector<float, 4>, 8>::sample_slice_type &(unsigned int) const' lvalue CXXMethod 'operator[]' 'Texture2DMSArray<vector<float, 4>, 8>::sample_slice_type &(unsigned int) const'
         |   |-ImplicitCastExpr <col:9, col:18> 'const Texture2DMSArray<vector<float, 4>, 8>::sample_type' lvalue <NoOp>
         |   |-ImplicitCastExpr <col:9, col:18> 'const Texture2DMSArray<vector<float, 4>, 8>::sample_type' lvalue <NoOp>
         |   | `-MemberExpr <col:9, col:18> 'Texture2DMSArray<vector<float, 4>, 8>::sample_type' lvalue .sample
         |   | `-MemberExpr <col:9, col:18> 'Texture2DMSArray<vector<float, 4>, 8>::sample_type' lvalue .sample
         |   |   `-DeclRefExpr <col:9> 'Texture2DMSArray<float4, 8>':'Texture2DMSArray<vector<float, 4>, 8>' lvalue Var 'g_t2dmsa' 'Texture2DMSArray<float4, 8>':'Texture2DMSArray<vector<float, 4>, 8>'
         |   |   `-DeclRefExpr <col:9> 'Texture2DMSArray<float4, 8>':'Texture2DMSArray<vector<float, 4>, 8>' lvalue Var 'g_t2dmsa' 'Texture2DMSArray<float4, 8>':'Texture2DMSArray<vector<float, 4>, 8>'
@@ -486,6 +668,10 @@ float4 test_sample_double_indexing()
         `-ImplicitCastExpr <col:38> 'uint3':'vector<unsigned int, 3>' <LValueToRValue>
         `-ImplicitCastExpr <col:38> 'uint3':'vector<unsigned int, 3>' <LValueToRValue>
           `-DeclRefExpr <col:38> 'uint3':'vector<unsigned int, 3>' lvalue Var 'pos3' 'uint3':'vector<unsigned int, 3>'
           `-DeclRefExpr <col:38> 'uint3':'vector<unsigned int, 3>' lvalue Var 'pos3' 'uint3':'vector<unsigned int, 3>'
   */
   */
+
+  g_t2dms.sample[sampleSlice][pos2] = f4;  /* expected-error {{cannot assign to return value because function 'operator[]<const vector<float, 4> &>' returns a const value}} fxc-error {{X3025: l-value specifies const object}} */
+  g_t2dmsa.sample[sampleSlice][pos3] = f4; /* expected-error {{cannot assign to return value because function 'operator[]<const vector<float, 4> &>' returns a const value}} fxc-error {{X3025: l-value specifies const object}} */
+
   return f4;
   return f4;
 }
 }
 
 

+ 14 - 0
tools/clang/test/HLSLFileCheck/hlsl/intrinsics/basic/clamp_const_prop.hlsl

@@ -0,0 +1,14 @@
+// RUN: %dxc -T ps_6_0 %s -E main | %FileCheck %s
+// CHECK: call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float 1.000000e+00)
+// CHECK: call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float -1.250000e+00)
+// CHECK: call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float 3.000000e+00)
+// CHECK: call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float 2.000000e+00)
+
+[RootSignature("")]
+float4 main() : SV_Target {
+  return float4(
+    clamp(10, 0, 1),
+    clamp(-1.0f, -2.5f, -1.25f),
+    clamp((double)3, (double)-2, (double)5),
+    clamp(-5LL, 2LL, 5LL));
+}

+ 2 - 2
tools/clang/test/HLSLFileCheck/hlsl/intrinsics/helper/IsHelperLane.hlsl

@@ -32,7 +32,7 @@
 // RUN: %dxc -E cs -T cs_6_0 -Od %s | FileCheck %s -check-prefixes=CHECKCONST
 // RUN: %dxc -E cs -T cs_6_0 -Od %s | FileCheck %s -check-prefixes=CHECKCONST
 // RUN: %dxc -E as -T as_6_5 -Od %s | FileCheck %s -check-prefixes=CHECKCONST
 // RUN: %dxc -E as -T as_6_5 -Od %s | FileCheck %s -check-prefixes=CHECKCONST
 // RUN: %dxc -E ms -T ms_6_5 -Od %s | FileCheck %s -check-prefixes=CHECKCONST
 // RUN: %dxc -E ms -T ms_6_5 -Od %s | FileCheck %s -check-prefixes=CHECKCONST
-// RUN: %dxc -T lib_6_5 %s | FileCheck %s -check-prefixes=CHECKLIBGV
+// RUN: %dxilver 1.6 | %dxc -T lib_6_5 %s | FileCheck %s -check-prefixes=CHECKLIBGV
 
 
 
 
 // Exactly one call
 // Exactly one call
@@ -277,7 +277,7 @@ RWStructuredBuffer<float4> SB;
 void cs(uint gidx : SV_GroupIndex)
 void cs(uint gidx : SV_GroupIndex)
 {
 {
   float4 result = a + IsHelperLane();
   float4 result = a + IsHelperLane();
-  SB[gidx] = QuadReadAcrossX(result);
+  SB[gidx] = result;
 }
 }
 
 
 /// Amplification Shader
 /// Amplification Shader

+ 4 - 3
tools/clang/test/HLSLFileCheck/hlsl/intrinsics/pixel/attr/attributeAtVertex.hlsl

@@ -1,8 +1,9 @@
-// RUN: %dxilver 1.1 | %dxc -E main -T ps_6_1 %s | FileCheck %s
+// RUN: %dxc -E main -T ps_6_1 %s | FileCheck %s
+// RUN: %dxilver 1.6 | %dxc -E main -T ps_6_1 %s | FileCheck %s -check-prefixes=CHECK,CHK16
 
 
 
 
-// CHECK: Note: shader requires additional functionality:
-// CHECK-NEXT: Barycentrics
+// CHK16: Note: shader requires additional functionality:
+// CHK16-NEXT: Barycentrics
 
 
 // CHECK: call float @dx.op.attributeAtVertex.f32(i32 137, i32 0, i32 0, i8 0, i8 0)
 // CHECK: call float @dx.op.attributeAtVertex.f32(i32 137, i32 0, i32 0, i8 0, i8 0)
 // CHECK: call float @dx.op.attributeAtVertex.f32(i32 137, i32 0, i32 0, i8 1, i8 0)
 // CHECK: call float @dx.op.attributeAtVertex.f32(i32 137, i32 0, i32 0, i8 1, i8 0)

+ 4 - 3
tools/clang/test/HLSLFileCheck/hlsl/intrinsics/pixel/attr/attributeAtVertexNoOpt.hlsl

@@ -1,7 +1,8 @@
-// RUN: %dxilver 1.1 | %dxc -E main -T ps_6_1 -O0 %s | FileCheck %s
+// RUN: %dxc -E main -T ps_6_1 -O0 %s | FileCheck %s
+// RUN: %dxilver 1.6 | %dxc -E main -T ps_6_1 -O0 %s | FileCheck %s -check-prefixes=CHECK,CHK16
 
 
-// CHECK: Note: shader requires additional functionality:
-// CHECK-NEXT: Barycentrics
+// CHK16: Note: shader requires additional functionality:
+// CHK16-NEXT: Barycentrics
 
 
 // CHECK: call float @dx.op.attributeAtVertex.f32(i32 137, i32 1, i32 0, i8 0, i8 0)
 // CHECK: call float @dx.op.attributeAtVertex.f32(i32 137, i32 1, i32 0, i8 0, i8 0)
 // CHECK: call float @dx.op.attributeAtVertex.f32(i32 137, i32 1, i32 0, i8 1, i8 0)
 // CHECK: call float @dx.op.attributeAtVertex.f32(i32 137, i32 1, i32 0, i8 1, i8 0)

+ 1 - 1
tools/clang/test/HLSLFileCheck/hlsl/lifetimes/lifetimes_lib_6_3.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -T lib_6_3 -enable-lifetime-markers %s  | FileCheck %s
+// RUN: %dxilver 1.6 | %dxc -T lib_6_3 -enable-lifetime-markers %s  | FileCheck %s
 
 
 // This file is identical to lifetimes.hlsl except that it tests for
 // This file is identical to lifetimes.hlsl except that it tests for
 // undef stores instead of lifetime intrinsics (fallback for earlier
 // undef stores instead of lifetime intrinsics (fallback for earlier

+ 1 - 1
tools/clang/test/HLSLFileCheck/hlsl/objects/CbufferLegacy/cbufferSize1.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
+// RUN: %dxilver 1.6 | %dxc -E main -T ps_6_0 %s | FileCheck %s
 
 
 // CHECK: error: CBuffer size is 65552 bytes, exceeding maximum of 65536 bytes.
 // CHECK: error: CBuffer size is 65552 bytes, exceeding maximum of 65536 bytes.
 
 

+ 1 - 1
tools/clang/test/HLSLFileCheck/hlsl/objects/CbufferLegacy/cbufferSize3.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
+// RUN: %dxilver 1.6 | %dxc -E main -T ps_6_0 %s | FileCheck %s
 
 
 // CHECK: error: CBuffer size is 65540 bytes, exceeding maximum of 65536 bytes.
 // CHECK: error: CBuffer size is 65540 bytes, exceeding maximum of 65536 bytes.
 
 

+ 1 - 1
tools/clang/test/HLSLFileCheck/hlsl/objects/CbufferLegacy/cbufferSize5.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
+// RUN: %dxilver 1.6 | %dxc -E main -T ps_6_0 %s | FileCheck %s
 
 
 // CHECK: error: CBuffer size is 65540 bytes, exceeding maximum of 65536 bytes.
 // CHECK: error: CBuffer size is 65540 bytes, exceeding maximum of 65536 bytes.
 
 

+ 1 - 1
tools/clang/test/HLSLFileCheck/hlsl/objects/CbufferLegacy/cbufferSize6.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
+// RUN: %dxilver 1.6 | %dxc -E main -T ps_6_0 %s | FileCheck %s
 
 
 // CHECK: error: CBuffer size is 65540 bytes, exceeding maximum of 65536 bytes.
 // CHECK: error: CBuffer size is 65540 bytes, exceeding maximum of 65536 bytes.
 
 

+ 4 - 3
tools/clang/test/HLSLFileCheck/hlsl/semantics/sv_barycentrics/barycentrics.hlsl

@@ -1,7 +1,8 @@
-// RUN: %dxilver 1.1 | %dxc -E main -T ps_6_1 %s | FileCheck %s
+// RUN: %dxc -E main -T ps_6_1 %s | FileCheck %s
+// RUN: %dxilver 1.6 | %dxc -E main -T ps_6_1 %s | FileCheck %s -check-prefixes=CHECK,CHK16
 
 
-// CHECK: Note: shader requires additional functionality:
-// CHECK-NEXT: Barycentrics
+// CHK16: Note: shader requires additional functionality:
+// CHK16-NEXT: Barycentrics
 // CHECK: !"SV_Barycentrics"
 // CHECK: !"SV_Barycentrics"
 
 
 float4 main(float3 bary : SV_Barycentrics) : SV_Target
 float4 main(float3 bary : SV_Barycentrics) : SV_Target

+ 4 - 3
tools/clang/test/HLSLFileCheck/hlsl/semantics/sv_barycentrics/barycentrics1.hlsl

@@ -1,7 +1,8 @@
-// RUN: %dxilver 1.1 | %dxc -E main -T ps_6_1 %s | FileCheck %s
+// RUN: %dxc -E main -T ps_6_1 %s | FileCheck %s
+// RUN: %dxilver 1.6 | %dxc -E main -T ps_6_1 %s | FileCheck %s -check-prefixes=CHECK,CHK16
 
 
-// CHECK: Note: shader requires additional functionality:
-// CHECK-NEXT: Barycentrics
+// CHK16: Note: shader requires additional functionality:
+// CHK16-NEXT: Barycentrics
 
 
 // CHECK: ; SV_Barycentrics
 // CHECK: ; SV_Barycentrics
 // CHECK: ; SV_Barycentrics
 // CHECK: ; SV_Barycentrics

+ 1 - 1
tools/clang/test/HLSLFileCheck/hlsl/types/conversions/semantics_Mod.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
+// RUN: %dxilver 1.6 | %dxc -E main -T ps_6_0 %s | FileCheck %s
 
 
 // CHECK: @main
 // CHECK: @main
 
 

+ 9 - 9
tools/clang/test/HLSLFileCheck/hlsl/types/modifiers/groupshared/groupshared_shadermodels.hlsl

@@ -1,12 +1,12 @@
-// RUN: %dxc -E PSMain -T ps_6_0 %s | FileCheck %s
-// RUN: %dxc -E VSMain -T vs_6_0 %s | FileCheck %s
-// RUN: %dxc -E GSMain -T gs_6_0 %s | FileCheck %s
-// RUN: %dxc -E HSMain -T hs_6_0 %s | FileCheck %s
-// RUN: %dxc -E DSMain -T ds_6_0 %s | FileCheck %s
-// RUN: %dxc -E CSMain -T lib_6_5 %s | FileCheck %s -check-prefix=LIBCHK
-// RUN: %dxc -E CSMain -T cs_6_0 %s | FileCheck %s -check-prefix=CSCHK
-// RUN: %dxc -E MSMain -T ms_6_5 %s | FileCheck %s -check-prefix=CSCHK
-// RUN: %dxc -E ASMain -T as_6_5 %s | FileCheck %s -check-prefix=CSCHK
+// RUN: %dxilver 1.6 | %dxc -E PSMain -T ps_6_0 %s | FileCheck %s
+// RUN: %dxilver 1.6 | %dxc -E VSMain -T vs_6_0 %s | FileCheck %s
+// RUN: %dxilver 1.6 | %dxc -E GSMain -T gs_6_0 %s | FileCheck %s
+// RUN: %dxilver 1.6 | %dxc -E HSMain -T hs_6_0 %s | FileCheck %s
+// RUN: %dxilver 1.6 | %dxc -E DSMain -T ds_6_0 %s | FileCheck %s
+// RUN: %dxilver 1.6 | %dxc -E CSMain -T lib_6_5 %s | FileCheck %s -check-prefix=LIBCHK
+// RUN: %dxilver 1.6 | %dxc -E CSMain -T cs_6_0 %s | FileCheck %s -check-prefix=CSCHK
+// RUN: %dxilver 1.6 | %dxc -E MSMain -T ms_6_5 %s | FileCheck %s -check-prefix=CSCHK
+// RUN: %dxilver 1.6 | %dxc -E ASMain -T as_6_5 %s | FileCheck %s -check-prefix=CSCHK
 
 
 // Test that the proper error for groupshared is produced when compiling in non-compute contexts
 // Test that the proper error for groupshared is produced when compiling in non-compute contexts
 // and that everything is fine when we are
 // and that everything is fine when we are

+ 1 - 1
tools/clang/test/HLSLFileCheck/validation/rawbufferstore_uav.hlsl

@@ -1,6 +1,6 @@
 // RUN: %dxilver 1.5 | %dxc -T vs_6_2 -E main %s | FileCheck %s
 // RUN: %dxilver 1.5 | %dxc -T vs_6_2 -E main %s | FileCheck %s
 
 
-// CHECK: store should be on uav resource
+// CHECK: error: cannot assign to return value because function 'operator[]<const int &>' returns a const value
 
 
 StructuredBuffer<int> buf;
 StructuredBuffer<int> buf;
 void main() { buf[0] = 0; }
 void main() { buf[0] = 0; }

+ 59 - 0
tools/clang/tools/dxclib/dxc.cpp

@@ -1160,6 +1160,59 @@ void DxcContext::GetCompilerVersionInfo(llvm::raw_string_ostream &OS) {
 #define VERSION_STRING_SUFFIX ""
 #define VERSION_STRING_SUFFIX ""
 #endif
 #endif
 
 
+#ifdef _WIN32
+// Unhandled exception filter called when an unhandled exception occurs
+// to at least print an generic error message instead of crashing silently.
+// passes exception along to allow crash dumps to be generated
+static LONG CALLBACK ExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)
+{
+  static char scratch[32];
+
+  fputs("Internal compiler error: " , stderr);
+
+  if (!pExceptionInfo || !pExceptionInfo->ExceptionRecord) {
+    // No information at all, it's not much, but it's the best we can do
+    fputs("Unknown", stderr);
+    return EXCEPTION_CONTINUE_SEARCH;
+  }
+
+  switch(pExceptionInfo->ExceptionRecord->ExceptionCode) {
+    // native exceptions
+  case EXCEPTION_ACCESS_VIOLATION: {
+    fputs("access violation. Attempted to ", stderr);
+    if (pExceptionInfo->ExceptionRecord->ExceptionInformation[0])
+      fputs("write", stderr);
+    else
+      fputs("read", stderr);
+    fputs(" from address ", stderr);
+    sprintf_s(scratch, _countof(scratch), "0x%p\n", (void*)pExceptionInfo->ExceptionRecord->ExceptionInformation[1]);
+    fputs(scratch, stderr);
+  } break;
+  case EXCEPTION_STACK_OVERFLOW:
+    fputs("stack overflow\n", stderr);
+    break;
+    // LLVM exceptions
+  case STATUS_LLVM_ASSERT:
+    fputs("LLVM Assert\n", stderr);
+    break;
+  case STATUS_LLVM_UNREACHABLE:
+    fputs("LLVM Unreachable\n", stderr);
+    break;
+  case STATUS_LLVM_FATAL:
+    fputs("LLVM Fatal Error\n", stderr);
+    break;
+  default:
+    fputs("Error ", stderr);
+    sprintf_s(scratch, _countof(scratch), "0x%08x\n", pExceptionInfo->ExceptionRecord->ExceptionCode);
+    fputs(scratch, stderr);
+  }
+
+  // Continue search to pass along the exception
+  return EXCEPTION_CONTINUE_SEARCH;
+}
+#endif
+
+
 #ifdef _WIN32
 #ifdef _WIN32
 int dxc::main(int argc, const wchar_t **argv_) {
 int dxc::main(int argc, const wchar_t **argv_) {
 #else
 #else
@@ -1199,6 +1252,12 @@ int dxc::main(int argc, const char **argv_) {
       dxcOpts.EntryPoint = "main";
       dxcOpts.EntryPoint = "main";
     }
     }
 
 
+#ifdef _WIN32
+    // Set exception handler if enabled
+    if (dxcOpts.HandleExceptions)
+      SetUnhandledExceptionFilter(ExceptionFilter);
+#endif
+
     // Setup a helper DLL.
     // Setup a helper DLL.
     {
     {
       std::string dllErrorString;
       std::string dllErrorString;

+ 168 - 112
tools/clang/tools/dxcompiler/dxcpdbutils.cpp

@@ -96,52 +96,31 @@ static bool IsBitcode(const void *ptr, size_t size) {
   return !memcmp(ptr, pattern, _countof(pattern));
   return !memcmp(ptr, pattern, _countof(pattern));
 }
 }
 
 
-static void ComputeFlagsBasedOnArgs(ArrayRef<std::wstring> args, std::vector<std::wstring> *outFlags, std::vector<std::wstring> *outDefines, std::wstring *outTargetProfile, std::wstring *outEntryPoint) {
+static std::vector<std::pair<std::wstring, std::wstring> > ComputeArgPairs(ArrayRef<std::string> args) {
+  std::vector<std::pair<std::wstring, std::wstring> > ret;
+
   const llvm::opt::OptTable *optionTable = hlsl::options::getHlslOptTable();
   const llvm::opt::OptTable *optionTable = hlsl::options::getHlslOptTable();
   assert(optionTable);
   assert(optionTable);
   if (optionTable) {
   if (optionTable) {
-    std::vector<std::string> argUtf8List;
-    for (unsigned i = 0; i < args.size(); i++) {
-      argUtf8List.push_back(ToUtf8String(args[i]));
-    }
-
     std::vector<const char *> argPointerList;
     std::vector<const char *> argPointerList;
-    for (unsigned i = 0; i < argUtf8List.size(); i++) {
-      argPointerList.push_back(argUtf8List[i].c_str());
+    for (unsigned i = 0; i < args.size(); i++) {
+      argPointerList.push_back(args[i].c_str());
     }
     }
 
 
     unsigned missingIndex = 0;
     unsigned missingIndex = 0;
     unsigned missingCount = 0;
     unsigned missingCount = 0;
     llvm::opt::InputArgList argList = optionTable->ParseArgs(argPointerList, missingIndex, missingCount);
     llvm::opt::InputArgList argList = optionTable->ParseArgs(argPointerList, missingIndex, missingCount);
     for (llvm::opt::Arg *arg : argList) {
     for (llvm::opt::Arg *arg : argList) {
-      if (arg->getOption().matches(hlsl::options::OPT_D)) {
-        std::wstring def = ToWstring(arg->getValue());
-        if (outDefines)
-          outDefines->push_back(def);
-        continue;
-      }
-      else if (arg->getOption().matches(hlsl::options::OPT_target_profile)) {
-        if (outTargetProfile)
-          *outTargetProfile = ToWstring(arg->getValue());
-        continue;
-      }
-      else if (arg->getOption().matches(hlsl::options::OPT_entrypoint)) {
-        if (outEntryPoint)
-          *outEntryPoint = ToWstring(arg->getValue());
-        continue;
+      std::pair<std::wstring, std::wstring> newPair;
+      newPair.first = ToWstring( arg->getOption().getName() );
+      if (arg->getNumValues() > 0) {
+        newPair.second = ToWstring( arg->getValue() );
       }
       }
 
 
-      if (outFlags) {
-        llvm::StringRef Name = arg->getOption().getName();
-        if (Name.size()) {
-          outFlags->push_back(std::wstring(L"-") + ToWstring(Name));
-        }
-        if (arg->getNumValues() > 0) {
-          outFlags->push_back(ToWstring(arg->getValue()));
-        }
-      }
+      ret.push_back(std::move(newPair));
     }
     }
   }
   }
+  return ret;
 }
 }
 
 
 struct DxcPdbVersionInfo :
 struct DxcPdbVersionInfo :
@@ -246,10 +225,13 @@ struct PdbRecompilerIncludeHandler : public IDxcIncludeHandler {
     if (it == m_FileMap.end())
     if (it == m_FileMap.end())
       return E_FAIL;
       return E_FAIL;
 
 
-    CComPtr<IDxcBlobEncoding> pEncoding;
-    IFR(m_pPdbUtils->GetSource(it->second, &pEncoding));
+    CComPtr<IDxcBlobEncoding> pSource;
+    IFR(m_pPdbUtils->GetSource(it->second, &pSource));
 
 
-    return pEncoding.QueryInterface(ppIncludeSource);
+    CComPtr<IDxcBlobEncoding> pOutBlob;
+    IFR(hlsl::DxcCreateBlobEncodingFromBlob(pSource, 0, pSource->GetBufferSize(), /*encoding Known*/true, CP_UTF8, m_pMalloc, &pOutBlob));
+
+    return pOutBlob.QueryInterface(ppIncludeSource);
   }
   }
 };
 };
 
 
@@ -260,16 +242,14 @@ private:
 
 
   struct Source_File {
   struct Source_File {
     std::wstring Name;
     std::wstring Name;
-    CComPtr<IDxcBlobEncoding> Content;
+    CComPtr<IDxcBlob> Content;
   };
   };
 
 
   CComPtr<IDxcBlob> m_InputBlob;
   CComPtr<IDxcBlob> m_InputBlob;
   CComPtr<IDxcBlob> m_pDebugProgramBlob;
   CComPtr<IDxcBlob> m_pDebugProgramBlob;
   CComPtr<IDxcBlob> m_ContainerBlob;
   CComPtr<IDxcBlob> m_ContainerBlob;
   std::vector<Source_File> m_SourceFiles;
   std::vector<Source_File> m_SourceFiles;
-  std::vector<std::wstring> m_Defines;
-  std::vector<std::wstring> m_Args;
-  std::vector<std::wstring> m_Flags;
+
   std::wstring m_EntryPoint;
   std::wstring m_EntryPoint;
   std::wstring m_TargetProfile;
   std::wstring m_TargetProfile;
   std::wstring m_Name;
   std::wstring m_Name;
@@ -290,17 +270,24 @@ private:
     std::wstring Value;
     std::wstring Value;
   };
   };
   std::vector<ArgPair> m_ArgPairs;
   std::vector<ArgPair> m_ArgPairs;
+  std::vector<std::wstring> m_Defines;
+  std::vector<std::wstring> m_Args;
+  std::vector<std::wstring> m_Flags;
 
 
-  void Reset() {
-    m_pDebugProgramBlob = nullptr;
-    m_InputBlob = nullptr;
-    m_ContainerBlob = nullptr;
-    m_SourceFiles.clear();
+  void ResetAllArgs() {
+    m_ArgPairs.clear();
     m_Defines.clear();
     m_Defines.clear();
     m_Args.clear();
     m_Args.clear();
     m_Flags.clear();
     m_Flags.clear();
     m_EntryPoint.clear();
     m_EntryPoint.clear();
     m_TargetProfile.clear();
     m_TargetProfile.clear();
+  }
+
+  void Reset() {
+    m_pDebugProgramBlob = nullptr;
+    m_InputBlob = nullptr;
+    m_ContainerBlob = nullptr;
+    m_SourceFiles.clear();
     m_Name.clear();
     m_Name.clear();
     m_MainFileName.clear();
     m_MainFileName.clear();
     m_HashBlob = nullptr;
     m_HashBlob = nullptr;
@@ -308,8 +295,8 @@ private:
     m_VersionInfo = {};
     m_VersionInfo = {};
     m_VersionCommitSha.clear();
     m_VersionCommitSha.clear();
     m_VersionString.clear();
     m_VersionString.clear();
-    m_ArgPairs.clear();
     m_pCachedRecompileResult = nullptr;
     m_pCachedRecompileResult = nullptr;
+    ResetAllArgs();
   }
   }
 
 
   bool HasSources() const {
   bool HasSources() const {
@@ -379,26 +366,14 @@ private:
           file.Name = ToWstring(md_name->getString());
           file.Name = ToWstring(md_name->getString());
 
 
           // File content
           // File content
-          IFR(hlsl::DxcCreateBlobWithEncodingOnHeapCopy(
+          IFR(hlsl::DxcCreateBlobOnHeapCopy(
             md_content->getString().data(),
             md_content->getString().data(),
             md_content->getString().size(),
             md_content->getString().size(),
-            CP_ACP, // NOTE: ACP instead of UTF8 because it's possible for compiler implementations to
-                    // inject non-UTF8 data here.
             &file.Content));
             &file.Content));
 
 
           m_SourceFiles.push_back(std::move(file));
           m_SourceFiles.push_back(std::move(file));
         }
         }
       }
       }
-      // dx.source.defines
-      else if (node_name == hlsl::DxilMDHelper::kDxilSourceDefinesMDName ||
-               node_name == hlsl::DxilMDHelper::kDxilSourceDefinesOldMDName)
-      {
-        MDTuple *tup = cast<MDTuple>(node.getOperand(0));
-        for (unsigned i = 0; i < tup->getNumOperands(); i++) {
-          StringRef define = cast<MDString>(tup->getOperand(i))->getString();
-          m_Defines.push_back(ToWstring(define));
-        }
-      }
       // dx.source.mainFileName
       // dx.source.mainFileName
       else if (node_name == hlsl::DxilMDHelper::kDxilSourceMainFileNameMDName ||
       else if (node_name == hlsl::DxilMDHelper::kDxilSourceMainFileNameMDName ||
                node_name == hlsl::DxilMDHelper::kDxilSourceMainFileNameOldMDName)
                node_name == hlsl::DxilMDHelper::kDxilSourceMainFileNameOldMDName)
@@ -412,13 +387,20 @@ private:
                node_name == hlsl::DxilMDHelper::kDxilSourceArgsOldMDName)
                node_name == hlsl::DxilMDHelper::kDxilSourceArgsOldMDName)
       {
       {
         MDTuple *tup = cast<MDTuple>(node.getOperand(0));
         MDTuple *tup = cast<MDTuple>(node.getOperand(0));
+        std::vector<std::string> args;
         // Args
         // Args
         for (unsigned i = 0; i < tup->getNumOperands(); i++) {
         for (unsigned i = 0; i < tup->getNumOperands(); i++) {
           StringRef arg = cast<MDString>(tup->getOperand(i))->getString();
           StringRef arg = cast<MDString>(tup->getOperand(i))->getString();
-          m_Args.push_back(ToWstring(arg));
+          args.push_back(arg.str());
         }
         }
 
 
-        ComputeFlagsBasedOnArgs(m_Args, &m_Flags, nullptr, nullptr, nullptr);
+        std::vector<std::pair<std::wstring, std::wstring> > Pairs = ComputeArgPairs(args);
+        for (std::pair<std::wstring, std::wstring> &p : Pairs) {
+          ArgPair newPair;
+          newPair.Name  = std::move(p.first);
+          newPair.Value = std::move(p.second);
+          AddArgPair(std::move(newPair));
+        }
       }
       }
     }
     }
 
 
@@ -503,38 +485,7 @@ private:
             newPair.Name = ToWstring(pair.Name);
             newPair.Name = ToWstring(pair.Name);
             newPair.Value = ToWstring(pair.Value);
             newPair.Value = ToWstring(pair.Value);
           }
           }
-
-          bool excludeFromFlags = false;
-          if (newPair.Name == L"E") {
-            m_EntryPoint = newPair.Value;
-            excludeFromFlags = true;
-          }
-          else if (newPair.Name == L"T") {
-            m_TargetProfile = newPair.Value;
-            excludeFromFlags = true;
-          }
-          else if (newPair.Name == L"D") {
-            m_Defines.push_back(newPair.Value);
-            excludeFromFlags = true;
-          }
-
-          std::wstring nameWithDash;
-          if (newPair.Name.size())
-            nameWithDash = std::wstring(L"-") + newPair.Name;
-
-          if (!excludeFromFlags) {
-            if (nameWithDash.size())
-              m_Flags.push_back(nameWithDash);
-            if (newPair.Value.size())
-              m_Flags.push_back(newPair.Value);
-          }
-
-          if (nameWithDash.size())
-            m_Args.push_back(nameWithDash);
-          if (newPair.Value.size())
-            m_Args.push_back(newPair.Value);
-
-          m_ArgPairs.push_back( std::move(newPair) );
+          AddArgPair(std::move(newPair));
         }
         }
 
 
         // Entry point might have been omitted. Set it to main by default.
         // Entry point might have been omitted. Set it to main by default.
@@ -548,11 +499,9 @@ private:
 
 
           Source_File source;
           Source_File source;
           source.Name = ToWstring(source_data.Name);
           source.Name = ToWstring(source_data.Name);
-          IFR(hlsl::DxcCreateBlobWithEncodingOnHeapCopy(
+          IFR(hlsl::DxcCreateBlobOnHeapCopy(
             source_data.Content.data(),
             source_data.Content.data(),
             source_data.Content.size(),
             source_data.Content.size(),
-            CP_ACP, // NOTE: ACP instead of UTF8 because it's possible for compiler implementations to
-                    // inject non-UTF8 data here.
             &source.Content));
             &source.Content));
 
 
           // First file is the main file
           // First file is the main file
@@ -582,8 +531,8 @@ private:
       {
       {
         const hlsl::DxilProgramHeader *program_header = (const hlsl::DxilProgramHeader *)(part+1);
         const hlsl::DxilProgramHeader *program_header = (const hlsl::DxilProgramHeader *)(part+1);
 
 
-        CComPtr<IDxcBlobEncoding> pProgramHeaderBlob;
-        IFR(hlsl::DxcCreateBlobWithEncodingFromPinned(program_header, program_header->SizeInUint32*sizeof(UINT32), CP_ACP, &pProgramHeaderBlob));
+        CComPtr<IDxcBlob> pProgramHeaderBlob;
+        IFR(hlsl::DxcCreateBlobFromPinned(program_header, program_header->SizeInUint32*sizeof(UINT32), &pProgramHeaderBlob));
         IFR(pProgramHeaderBlob.QueryInterface(ppDebugProgramBlob));
         IFR(pProgramHeaderBlob.QueryInterface(ppDebugProgramBlob));
 
 
       } break; // hlsl::DFCC_ShaderDebugInfoDXIL
       } break; // hlsl::DFCC_ShaderDebugInfoDXIL
@@ -593,6 +542,40 @@ private:
     return S_OK;
     return S_OK;
   }
   }
 
 
+  void AddArgPair(ArgPair &&newPair) {
+    bool excludeFromFlags = false;
+    if (newPair.Name == L"E") {
+      m_EntryPoint = newPair.Value;
+      excludeFromFlags = true;
+    }
+    else if (newPair.Name == L"T") {
+      m_TargetProfile = newPair.Value;
+      excludeFromFlags = true;
+    }
+    else if (newPair.Name == L"D") {
+      m_Defines.push_back(newPair.Value);
+      excludeFromFlags = true;
+    }
+
+    std::wstring nameWithDash;
+    if (newPair.Name.size())
+      nameWithDash = std::wstring(L"-") + newPair.Name;
+
+    if (!excludeFromFlags) {
+      if (nameWithDash.size())
+        m_Flags.push_back(nameWithDash);
+      if (newPair.Value.size())
+        m_Flags.push_back(newPair.Value);
+    }
+
+    if (nameWithDash.size())
+      m_Args.push_back(nameWithDash);
+    if (newPair.Value.size())
+      m_Args.push_back(newPair.Value);
+
+    m_ArgPairs.push_back( std::move(newPair) );
+  }
+
 public:
 public:
   DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL()
   DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL()
   DXC_MICROCOM_TM_ALLOC(DxcPdbUtils)
   DXC_MICROCOM_TM_ALLOC(DxcPdbUtils)
@@ -649,10 +632,11 @@ public:
       }
       }
       // DXIL program header or bitcode
       // DXIL program header or bitcode
       else {
       else {
-        CComPtr<IDxcBlobEncoding> pProgramHeaderBlob;
-        IFR(hlsl::DxcCreateBlobWithEncodingFromPinned(
+        CComPtr<IDxcBlob> pProgramHeaderBlob;
+        IFR(hlsl::DxcCreateBlobFromPinned(
           (hlsl::DxilProgramHeader *)pPdbOrDxil->GetBufferPointer(),
           (hlsl::DxilProgramHeader *)pPdbOrDxil->GetBufferPointer(),
-          pPdbOrDxil->GetBufferSize(), CP_ACP, &pProgramHeaderBlob));
+          pPdbOrDxil->GetBufferSize(), &pProgramHeaderBlob));
+
         IFR(pProgramHeaderBlob.QueryInterface(&m_pDebugProgramBlob));
         IFR(pProgramHeaderBlob.QueryInterface(&m_pDebugProgramBlob));
         IFR(PopulateSourcesFromProgramHeaderOrBitcode(m_pDebugProgramBlob));
         IFR(PopulateSourcesFromProgramHeaderOrBitcode(m_pDebugProgramBlob));
       }
       }
@@ -737,6 +721,63 @@ public:
     return m_pDebugProgramBlob != nullptr;
     return m_pDebugProgramBlob != nullptr;
   }
   }
 
 
+  virtual HRESULT STDMETHODCALLTYPE OverrideArgs(_In_ DxcArgPair *pArgPairs, UINT32 uNumArgPairs) override {
+    try {
+      DxcThreadMalloc TM(m_pMalloc);
+
+      ResetAllArgs();
+
+      for (UINT32 i = 0; i < uNumArgPairs; i++) {
+        ArgPair newPair;
+        newPair.Name  = pArgPairs[i].pName ? pArgPairs[i].pName : L"";
+        newPair.Value = pArgPairs[i].pValue ? pArgPairs[i].pValue : L"";
+        AddArgPair(std::move(newPair));
+      }
+
+      // Clear the cached compile result
+      m_pCachedRecompileResult = nullptr;
+    }
+    CATCH_CPP_RETURN_HRESULT()
+
+    return S_OK;
+  }
+
+  virtual HRESULT STDMETHODCALLTYPE OverrideRootSignature(_In_ const WCHAR *pRootSignature) override {
+    try {
+      DxcThreadMalloc TM(m_pMalloc);
+
+      std::vector<ArgPair> newArgPairs;
+      for (ArgPair &pair : m_ArgPairs) {
+        if (pair.Name == L"rootsig-define") {
+          continue;
+        }
+        newArgPairs.push_back(pair);
+      }
+
+      ResetAllArgs();
+
+      for (ArgPair &newArg : newArgPairs) {
+        AddArgPair(std::move(newArg));
+      }
+
+      ArgPair rsPair;
+      rsPair.Name = L"rootsig-define";
+      rsPair.Value = L"__DXC_RS_DEFINE";
+      AddArgPair(std::move(rsPair));
+
+      ArgPair defPair;
+      defPair.Name = L"D";
+      defPair.Value = std::wstring(L"__DXC_RS_DEFINE=") + pRootSignature;
+      AddArgPair(std::move(defPair));
+
+      // Clear the cached compile result
+      m_pCachedRecompileResult = nullptr;
+    }
+    CATCH_CPP_RETURN_HRESULT()
+
+    return S_OK;
+  }
+
   virtual HRESULT STDMETHODCALLTYPE CompileForFullPDB(_COM_Outptr_ IDxcResult **ppResult) {
   virtual HRESULT STDMETHODCALLTYPE CompileForFullPDB(_COM_Outptr_ IDxcResult **ppResult) {
     if (!ppResult) return E_POINTER;
     if (!ppResult) return E_POINTER;
     *ppResult = nullptr;
     *ppResult = nullptr;
@@ -747,26 +788,42 @@ public:
     if (m_pCachedRecompileResult)
     if (m_pCachedRecompileResult)
       return m_pCachedRecompileResult.QueryInterface(ppResult);
       return m_pCachedRecompileResult.QueryInterface(ppResult);
 
 
+    DxcThreadMalloc TM(m_pMalloc);
+
+    // Fail early if there are no source files.
+    if (m_SourceFiles.empty())
+      return E_FAIL;
+
     if (!m_pCompiler)
     if (!m_pCompiler)
       IFR(DxcCreateInstance2(m_pMalloc, CLSID_DxcCompiler, IID_PPV_ARGS(&m_pCompiler)));
       IFR(DxcCreateInstance2(m_pMalloc, CLSID_DxcCompiler, IID_PPV_ARGS(&m_pCompiler)));
 
 
-    DxcThreadMalloc TM(m_pMalloc);
+    std::vector<std::wstring> new_args_storage;
+    for (unsigned i = 0; i < m_ArgPairs.size(); i++) {
+      std::wstring name  = m_ArgPairs[i].Name;
+      std::wstring value = m_ArgPairs[i].Value;
+
+      if (name == L"Zs") continue;
+      if (name == L"Zi") continue;
+
+      if (name.size()) {
+        name.insert(name.begin(), L'-');
+        new_args_storage.push_back(std::move(name));
+      }
+      if (value.size()) {
+        new_args_storage.push_back(std::move(value));
+      }
+    }
+    new_args_storage.push_back(L"-Zi");
 
 
     std::vector<const WCHAR *> new_args;
     std::vector<const WCHAR *> new_args;
-    for (unsigned i = 0; i < m_Args.size(); i++) {
-      if (m_Args[i] == L"/Zs" || m_Args[i] == L"-Zs")
-        continue;
-      new_args.push_back(m_Args[i].c_str());
+    for (std::wstring &arg : new_args_storage) {
+      new_args.push_back(arg.c_str());
     }
     }
-    new_args.push_back(L"-Zi");
 
 
     assert(m_MainFileName.size());
     assert(m_MainFileName.size());
     if (m_MainFileName.size())
     if (m_MainFileName.size())
       new_args.push_back(m_MainFileName.c_str());
       new_args.push_back(m_MainFileName.c_str());
 
 
-    if (m_SourceFiles.empty())
-      return E_FAIL;
-
     CComPtr<PdbRecompilerIncludeHandler> pIncludeHandler = CreateOnMalloc<PdbRecompilerIncludeHandler>(m_pMalloc);
     CComPtr<PdbRecompilerIncludeHandler> pIncludeHandler = CreateOnMalloc<PdbRecompilerIncludeHandler>(m_pMalloc);
     if (!pIncludeHandler)
     if (!pIncludeHandler)
       return E_OUTOFMEMORY;
       return E_OUTOFMEMORY;
@@ -777,13 +834,12 @@ public:
       pIncludeHandler->m_FileMap.insert(std::pair<std::wstring, unsigned>(NormalizedName, i));
       pIncludeHandler->m_FileMap.insert(std::pair<std::wstring, unsigned>(NormalizedName, i));
     }
     }
 
 
-    IDxcBlobEncoding *main_file = m_SourceFiles[0].Content;
+    IDxcBlob *main_file = m_SourceFiles[0].Content;
 
 
     DxcBuffer source_buf = {};
     DxcBuffer source_buf = {};
     source_buf.Ptr = main_file->GetBufferPointer();
     source_buf.Ptr = main_file->GetBufferPointer();
     source_buf.Size = main_file->GetBufferSize();
     source_buf.Size = main_file->GetBufferSize();
-    BOOL bEndodingKnown = FALSE;
-    IFR(main_file->GetEncoding(&bEndodingKnown, &source_buf.Encoding));
+    source_buf.Encoding = CP_UTF8;
 
 
     CComPtr<IDxcResult> pResult;
     CComPtr<IDxcResult> pResult;
     IFR(m_pCompiler->Compile(&source_buf, new_args.data(), new_args.size(), pIncludeHandler, IID_PPV_ARGS(&m_pCachedRecompileResult)));
     IFR(m_pCompiler->Compile(&source_buf, new_args.data(), new_args.size(), pIncludeHandler, IID_PPV_ARGS(&m_pCachedRecompileResult)));

+ 64 - 0
tools/clang/unittests/HLSL/CompilerTest.cpp

@@ -1282,12 +1282,74 @@ static void VerifyPdbUtil(dxc::DxcDllSupport &dllSupport,
     CComPtr<IDxcPixDxilDebugInfo> pDebugInfo;
     CComPtr<IDxcPixDxilDebugInfo> pDebugInfo;
     VERIFY_SUCCEEDED(pFactory->NewDxcPixDxilDebugInfo(&pDebugInfo));
     VERIFY_SUCCEEDED(pFactory->NewDxcPixDxilDebugInfo(&pDebugInfo));
     VERIFY_ARE_NOT_EQUAL(pDebugInfo, nullptr);
     VERIFY_ARE_NOT_EQUAL(pDebugInfo, nullptr);
+
+    // Recompile when it's a full PDB anyway.
+    {
+      CComPtr<IDxcResult> pResult;
+      VERIFY_SUCCEEDED(pPdbUtils->CompileForFullPDB(&pResult));
+
+      HRESULT compileStatus = S_OK;
+      VERIFY_SUCCEEDED(pResult->GetStatus(&compileStatus));
+      VERIFY_SUCCEEDED(compileStatus);
+
+      CComPtr<IDxcBlob> pRecompiledPdbBlob;
+      VERIFY_SUCCEEDED(pResult->GetOutput(DXC_OUT_PDB, IID_PPV_ARGS(&pRecompiledPdbBlob), nullptr));
+    }
+
   }
   }
   else {
   else {
     VERIFY_IS_FALSE(pPdbUtils->IsFullPDB());
     VERIFY_IS_FALSE(pPdbUtils->IsFullPDB());
     CComPtr<IDxcBlob> pFullPdb;
     CComPtr<IDxcBlob> pFullPdb;
     VERIFY_SUCCEEDED(pPdbUtils->GetFullPDB(&pFullPdb));
     VERIFY_SUCCEEDED(pPdbUtils->GetFullPDB(&pFullPdb));
 
 
+    // Save a copy of the arg pairs
+    std::vector<std::pair< std::wstring, std::wstring> > pairsStorage;
+    UINT32 uNumArgsPairs = 0;
+    VERIFY_SUCCEEDED(pPdbUtils->GetArgPairCount(&uNumArgsPairs));
+    for (UINT32 i = 0; i < uNumArgsPairs; i++) {
+      CComBSTR pName, pValue;
+      VERIFY_SUCCEEDED(pPdbUtils->GetArgPair(i, &pName, &pValue));
+      std::pair< std::wstring, std::wstring> pairStorage;
+      pairStorage.first  = pName  ? pName  : L"";
+      pairStorage.second = pValue ? pValue : L"";
+      pairsStorage.push_back(pairStorage);
+    }
+
+    // Set an obviously wrong RS and verify compilation fails
+    {
+      VERIFY_SUCCEEDED(pPdbUtils->OverrideRootSignature(L""));
+      CComPtr<IDxcResult> pResult;
+      VERIFY_SUCCEEDED(pPdbUtils->CompileForFullPDB(&pResult));
+
+      HRESULT result = S_OK;
+      VERIFY_SUCCEEDED(pResult->GetStatus(&result));
+      VERIFY_FAILED(result);
+
+      CComPtr<IDxcBlobEncoding> pErr;
+      VERIFY_SUCCEEDED(pResult->GetErrorBuffer(&pErr));
+    }
+
+    // Set an obviously wrong set of args and verify compilation fails
+    {
+
+      std::vector<DxcArgPair> pairs;
+      for (auto &p : pairsStorage) {
+        DxcArgPair pair = {};
+        pair.pName = p.first.c_str();
+        pair.pValue = p.second.c_str();
+        pairs.push_back(pair);
+      }
+
+      VERIFY_SUCCEEDED(pPdbUtils->OverrideArgs(pairs.data(), pairs.size()));
+
+      CComPtr<IDxcResult> pResult;
+      VERIFY_SUCCEEDED(pPdbUtils->CompileForFullPDB(&pResult));
+
+      HRESULT result = S_OK;
+      VERIFY_SUCCEEDED(pResult->GetStatus(&result));
+      VERIFY_SUCCEEDED(result);
+    }
+
     auto ReplaceDebugFlagPair = [](const std::vector<std::pair<const WCHAR *, const WCHAR *> > &List) -> std::vector<std::pair<const WCHAR *, const WCHAR *> > {
     auto ReplaceDebugFlagPair = [](const std::vector<std::pair<const WCHAR *, const WCHAR *> > &List) -> std::vector<std::pair<const WCHAR *, const WCHAR *> > {
       std::vector<std::pair<const WCHAR *, const WCHAR *> > ret;
       std::vector<std::pair<const WCHAR *, const WCHAR *> > ret;
       for (unsigned i = 0; i < List.size(); i++) {
       for (unsigned i = 0; i < List.size(); i++) {
@@ -1357,6 +1419,7 @@ static void VerifyPdbUtil(dxc::DxcDllSupport &dllSupport,
 #ifdef _WIN32
 #ifdef _WIN32
 
 
 TEST_F(CompilerTest, CompileThenTestPdbUtilsStripped) {
 TEST_F(CompilerTest, CompileThenTestPdbUtilsStripped) {
+  if (m_ver.SkipDxilVersion(1, 5)) return;
   CComPtr<TestIncludeHandler> pInclude;
   CComPtr<TestIncludeHandler> pInclude;
   CComPtr<IDxcCompiler> pCompiler;
   CComPtr<IDxcCompiler> pCompiler;
   CComPtr<IDxcBlobEncoding> pSource;
   CComPtr<IDxcBlobEncoding> pSource;
@@ -1548,6 +1611,7 @@ void CompilerTest::TestPdbUtils(bool bSlim, bool bSourceInDebugModule, bool bStr
 }
 }
 
 
 TEST_F(CompilerTest, CompileThenTestPdbUtils) {
 TEST_F(CompilerTest, CompileThenTestPdbUtils) {
+  if (m_ver.SkipDxilVersion(1, 5)) return;
   TestPdbUtils(/*bSlim*/true,  /*bSourceInDebugModule*/false, /*strip*/true);  // Slim PDB, where source info is stored in its own part, and debug module is NOT present
   TestPdbUtils(/*bSlim*/true,  /*bSourceInDebugModule*/false, /*strip*/true);  // Slim PDB, where source info is stored in its own part, and debug module is NOT present
 
 
   TestPdbUtils(/*bSlim*/false, /*bSourceInDebugModule*/true,  /*strip*/false);  // Old PDB format, where source info is embedded in the module
   TestPdbUtils(/*bSlim*/false, /*bSourceInDebugModule*/true,  /*strip*/false);  // Old PDB format, where source info is embedded in the module

+ 3 - 0
tools/clang/unittests/HLSL/DxilModuleTest.cpp

@@ -47,6 +47,7 @@ public:
   TEST_CLASS_SETUP(InitSupport);
   TEST_CLASS_SETUP(InitSupport);
 
 
   dxc::DxcDllSupport m_dllSupport;
   dxc::DxcDllSupport m_dllSupport;
+  VersionSupportInfo m_ver;
 
 
   // Basic loading tests.
   // Basic loading tests.
   TEST_METHOD(LoadDxilModule_1_0)
   TEST_METHOD(LoadDxilModule_1_0)
@@ -81,6 +82,7 @@ public:
 bool DxilModuleTest::InitSupport() {
 bool DxilModuleTest::InitSupport() {
   if (!m_dllSupport.IsEnabled()) {
   if (!m_dllSupport.IsEnabled()) {
     VERIFY_SUCCEEDED(m_dllSupport.Initialize());
     VERIFY_SUCCEEDED(m_dllSupport.Initialize());
+    m_ver.Initialize(m_dllSupport);
   }
   }
   return true;
   return true;
 }
 }
@@ -582,6 +584,7 @@ TEST_F(DxilModuleTest, SetValidatorVersion) {
 }
 }
 
 
 TEST_F(DxilModuleTest, PayloadQualifier) {
 TEST_F(DxilModuleTest, PayloadQualifier) {
+  if (m_ver.SkipDxilVersion(1, 6)) return;
   std::vector<LPCWSTR> arguments = { L"-enable-payload-qualifiers" };
   std::vector<LPCWSTR> arguments = { L"-enable-payload-qualifiers" };
   Compiler c(m_dllSupport);
   Compiler c(m_dllSupport);
 
 

+ 86 - 38
tools/clang/unittests/HLSL/ExecutionTest.cpp

@@ -308,9 +308,7 @@ public:
   TEST_METHOD(AtomicsShared64Test);
   TEST_METHOD(AtomicsShared64Test);
   TEST_METHOD(AtomicsFloatTest);
   TEST_METHOD(AtomicsFloatTest);
   TEST_METHOD(HelperLaneTest);
   TEST_METHOD(HelperLaneTest);
-  BEGIN_TEST_METHOD(HelperLaneTestWave)
-    TEST_METHOD_PROPERTY(L"Priority", L"2") // Remove this line once warp handles this
-  END_TEST_METHOD()
+  TEST_METHOD(HelperLaneTestWave);
   TEST_METHOD(SignatureResourcesTest)
   TEST_METHOD(SignatureResourcesTest)
   TEST_METHOD(DynamicResourcesTest)
   TEST_METHOD(DynamicResourcesTest)
   TEST_METHOD(QuadReadTest)
   TEST_METHOD(QuadReadTest)
@@ -1387,7 +1385,7 @@ public:
   void RunLifetimeIntrinsicTest(ID3D12Device *pDevice, LPCSTR shader, D3D_SHADER_MODEL shaderModel, bool useLibTarget, LPCWSTR *pOptions, int numOptions, std::vector<uint32_t> &values);
   void RunLifetimeIntrinsicTest(ID3D12Device *pDevice, LPCSTR shader, D3D_SHADER_MODEL shaderModel, bool useLibTarget, LPCWSTR *pOptions, int numOptions, std::vector<uint32_t> &values);
   void RunLifetimeIntrinsicComputeTest(ID3D12Device *pDevice, LPCSTR pShader, CComPtr<ID3D12DescriptorHeap>& pUavHeap, CComPtr<ID3D12RootSignature>& pRootSignature,
   void RunLifetimeIntrinsicComputeTest(ID3D12Device *pDevice, LPCSTR pShader, CComPtr<ID3D12DescriptorHeap>& pUavHeap, CComPtr<ID3D12RootSignature>& pRootSignature,
                                        LPCWSTR pTargetProfile, LPCWSTR *pOptions, int numOptions, std::vector<uint32_t> &values);
                                        LPCWSTR pTargetProfile, LPCWSTR *pOptions, int numOptions, std::vector<uint32_t> &values);
-  void RunLifetimeIntrinsicLibTest(ID3D12Device5 *pDevice, LPCSTR pShader, CComPtr<ID3D12RootSignature>& pRootSignature,
+  void RunLifetimeIntrinsicLibTest(ID3D12Device *pDevice0, LPCSTR pShader, CComPtr<ID3D12RootSignature>& pRootSignature,
                                    LPCWSTR pTargetProfile, LPCWSTR *pOptions, int numOptions);
                                    LPCWSTR pTargetProfile, LPCWSTR *pOptions, int numOptions);
 
 
   void SetDescriptorHeap(ID3D12GraphicsCommandList *pCommandList, ID3D12DescriptorHeap *pHeap) {
   void SetDescriptorHeap(ID3D12GraphicsCommandList *pCommandList, ID3D12DescriptorHeap *pHeap) {
@@ -1634,8 +1632,11 @@ void ExecutionTest::RunLifetimeIntrinsicComputeTest(ID3D12Device *pDevice, LPCST
   WaitForSignal(pCommandQueue, FO);
   WaitForSignal(pCommandQueue, FO);
 }
 }
 
 
-void ExecutionTest::RunLifetimeIntrinsicLibTest(ID3D12Device5 *pDevice, LPCSTR pShader, CComPtr<ID3D12RootSignature>& pRootSignature,
+void ExecutionTest::RunLifetimeIntrinsicLibTest(ID3D12Device *pDevice0, LPCSTR pShader, CComPtr<ID3D12RootSignature>& pRootSignature,
                                                 LPCWSTR pTargetProfile, LPCWSTR *pOptions, int numOptions) {
                                                 LPCWSTR pTargetProfile, LPCWSTR *pOptions, int numOptions) {
+  CComPtr<ID3D12Device5> pDevice;
+  VERIFY_SUCCEEDED(pDevice0->QueryInterface(IID_PPV_ARGS(&pDevice)));
+
   // Create command queue.
   // Create command queue.
   CComPtr<ID3D12CommandQueue> pCommandQueue;
   CComPtr<ID3D12CommandQueue> pCommandQueue;
   CreateCommandQueue(pDevice, L"RunLifetimeIntrinsicTest Command Queue", &pCommandQueue, D3D12_COMMAND_LIST_TYPE_DIRECT);
   CreateCommandQueue(pDevice, L"RunLifetimeIntrinsicTest Command Queue", &pCommandQueue, D3D12_COMMAND_LIST_TYPE_DIRECT);
@@ -1722,10 +1723,13 @@ void ExecutionTest::RunLifetimeIntrinsicTest(ID3D12Device *pDevice, LPCSTR pShad
     CreateRootSignatureFromDesc(pDevice, &rootSignatureDesc, &pRootSignature);
     CreateRootSignatureFromDesc(pDevice, &rootSignatureDesc, &pRootSignature);
   }
   }
 
 
-  if (useLibTarget)
-    RunLifetimeIntrinsicLibTest(reinterpret_cast<ID3D12Device5*>(pDevice), pShader, pRootSignature, pTargetProfile, pOptions, numOptions);
-  else
-    RunLifetimeIntrinsicComputeTest(pDevice, pShader, pUavHeap, pRootSignature, pTargetProfile, pOptions, numOptions, values);
+  if (useLibTarget) {
+    RunLifetimeIntrinsicLibTest(pDevice, pShader, pRootSignature, pTargetProfile,
+      pOptions, numOptions);
+  } else {
+    RunLifetimeIntrinsicComputeTest(pDevice, pShader, pUavHeap, pRootSignature, pTargetProfile,
+      pOptions, numOptions, values);
+  }
 }
 }
 
 
 TEST_F(ExecutionTest, LifetimeIntrinsicTest) {
 TEST_F(ExecutionTest, LifetimeIntrinsicTest) {
@@ -1772,59 +1776,97 @@ TEST_F(ExecutionTest, LifetimeIntrinsicTest) {
   static const int ThreadsPerGroup = NumThreadsX * NumThreadsY * NumThreadsZ;
   static const int ThreadsPerGroup = NumThreadsX * NumThreadsY * NumThreadsZ;
   static const int DispatchGroupCount = 1;
   static const int DispatchGroupCount = 1;
 
 
-  // TODO: There's probably a lot of things in the rest of this test that could be stripped away.
+  CComPtr<ID3D12Device> pDevice;
+  bool bSM_6_6_Supported = CreateDevice(&pDevice, D3D_SHADER_MODEL_6_6, false, true);
+  bool bSM_6_3_Supported = bSM_6_6_Supported;
+  if (!bSM_6_6_Supported) {
+    // Try 6.3 for downlevel DXR case
+    bSM_6_3_Supported = CreateDevice(&pDevice, D3D_SHADER_MODEL_6_3, false, true);
+  }
+  if (!bSM_6_3_Supported) {
+    // Otherwise, 6.0 better be supported for compute case
+    VERIFY_IS_TRUE(CreateDevice(&pDevice, D3D_SHADER_MODEL_6_0, false, false));
+  }
+  bool bDXRSupported = bSM_6_3_Supported && DoesDeviceSupportRayTracing(pDevice);
 
 
-  CComPtr<ID3D12Device5> pDevice;
-  if (!CreateDevice(reinterpret_cast<ID3D12Device**>(&pDevice), D3D_SHADER_MODEL_6_6, true, true)) {
-    WEX::Logging::Log::Comment(L"Lifetime test not run pre 6.6");
+  if (GetTestParamUseWARP(UseWarpByDefault()) || IsDeviceBasicAdapter(pDevice)) {
+    WEX::Logging::Log::Comment(L"WARP has a known issue with LifetimeIntrinsicTest.");
     WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
     WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
     return;
     return;
   }
   }
 
 
+  if (!bSM_6_6_Supported) {
+    WEX::Logging::Log::Comment(L"Native lifetime markers skipped, device does not support SM 6.6");
+  }
+  if (!bDXRSupported) {
+    WEX::Logging::Log::Comment(L"DXR lifetime tests skipped, device does not support DXR");
+  }
+
   std::vector<uint32_t> values;
   std::vector<uint32_t> values;
   SetupComputeValuePattern(values, ThreadsPerGroup * DispatchGroupCount);
   SetupComputeValuePattern(values, ThreadsPerGroup * DispatchGroupCount);
 
 
   // Run a number of tests for different configurations that will cause
   // Run a number of tests for different configurations that will cause
-  // lifetime intrinsics to be placed directly, be replaced by a zeroinitializer
-  // store, or be replaced by an undef store.
-  LPCWSTR pOptions15[] = {L"/validator-version 1.5"};
-  LPCWSTR pOptions16[] = {L"/validator-version 1.6", L"/Vd"};
+  // lifetime intrinsics to be:
+  // - placed directly
+  // - translated to an undef store
+  // - translated to a zeroinitializer store
+  // against compute and DXR targets, downlevel and SM 6.6:
+  // - downlevel: cs_6_0, lib_6_3 (DXR)
+  // - cs_6_6, lib_6_6 (DXR)
 
 
   VERIFY_ARE_EQUAL(values[1], (uint32_t)1);
   VERIFY_ARE_EQUAL(values[1], (uint32_t)1);
 
 
-  // Test regular shader with zeroinitializer store.
-  RunLifetimeIntrinsicTest(pDevice, pShader, D3D_SHADER_MODEL_6_0, false, pOptions15, _countof(pOptions15), values);
+  LPCWSTR optsBase[] = {L"-enable-lifetime-markers"};
+  LPCWSTR optsZeroStore[] = {L"-enable-lifetime-markers", L"-force-zero-store-lifetimes"};
+
+  WEX::Logging::Log::Comment(L"==== cs_6_0 with default translation");
+  RunLifetimeIntrinsicTest(pDevice, pShader, D3D_SHADER_MODEL_6_0, false,
+    optsBase, _countof(optsBase), values);
   VERIFY_ARE_EQUAL(values[1], (uint32_t)1);
   VERIFY_ARE_EQUAL(values[1], (uint32_t)1);
 
 
-  if (DoesDeviceSupportRayTracing(pDevice)) {
-    // Test library with zeroinitializer store.
-    RunLifetimeIntrinsicTest(pDevice, pShader, D3D_SHADER_MODEL_6_3, true, pOptions15, _countof(pOptions15), values);
+  if (bDXRSupported) {
+    WEX::Logging::Log::Comment(L"==== DXR lib_6_3 with default translation");
+    RunLifetimeIntrinsicTest(pDevice, pShader, D3D_SHADER_MODEL_6_3, true,
+      optsBase, _countof(optsBase), values);
     VERIFY_ARE_EQUAL(values[1], (uint32_t)1);
     VERIFY_ARE_EQUAL(values[1], (uint32_t)1);
   }
   }
 
 
-  // Testing SM 6.6 and validator version 1.6 requires experimental shaders
-  // being turned on.
-  if (!m_ExperimentalModeEnabled)
-      return;
-
-  // Test regular shader with undef store.
-  RunLifetimeIntrinsicTest(pDevice, pShader, D3D_SHADER_MODEL_6_0, false, pOptions16, _countof(pOptions16), values);
+  WEX::Logging::Log::Comment(L"==== cs_6_0 with zeroinitializer translation");
+  RunLifetimeIntrinsicTest(pDevice, pShader, D3D_SHADER_MODEL_6_0, false,
+    optsZeroStore, _countof(optsZeroStore), values);
   VERIFY_ARE_EQUAL(values[1], (uint32_t)1);
   VERIFY_ARE_EQUAL(values[1], (uint32_t)1);
 
 
-  if (DoesDeviceSupportRayTracing(pDevice)) {
-    // Test library with undef store.
-    RunLifetimeIntrinsicTest(pDevice, pShader, D3D_SHADER_MODEL_6_3, true, pOptions16, _countof(pOptions16), values);
+  if (bDXRSupported) {
+    WEX::Logging::Log::Comment(L"==== DXR lib_6_3 with zeroinitializer translation");
+    RunLifetimeIntrinsicTest(pDevice, pShader, D3D_SHADER_MODEL_6_3, true,
+      optsZeroStore, _countof(optsZeroStore), values);
     VERIFY_ARE_EQUAL(values[1], (uint32_t)1);
     VERIFY_ARE_EQUAL(values[1], (uint32_t)1);
   }
   }
 
 
-  // Test regular shader with lifetime intrinsics.
-  RunLifetimeIntrinsicTest(pDevice, pShader, D3D_SHADER_MODEL_6_5, false, pOptions16, _countof(pOptions16), values); // TODO: Test 6.6 here!
-  VERIFY_ARE_EQUAL(values[1], (uint32_t)1);
+  if (bSM_6_6_Supported) {
+    WEX::Logging::Log::Comment(L"==== cs_6_6 with zeroinitializer translation");
+    RunLifetimeIntrinsicTest(pDevice, pShader, D3D_SHADER_MODEL_6_6, false,
+      optsZeroStore, _countof(optsZeroStore), values);
+    VERIFY_ARE_EQUAL(values[1], (uint32_t)1);
+
+    if (bDXRSupported) {
+      WEX::Logging::Log::Comment(L"==== DXR lib_6_6 with zeroinitializer translation");
+      RunLifetimeIntrinsicTest(pDevice, pShader, D3D_SHADER_MODEL_6_6, true,
+        optsZeroStore, _countof(optsZeroStore), values);
+      VERIFY_ARE_EQUAL(values[1], (uint32_t)1);
+    }
 
 
-  if (DoesDeviceSupportRayTracing(pDevice)) {
-    // Test library with lifetime intrinsics.
-    RunLifetimeIntrinsicTest(pDevice, pShader, D3D_SHADER_MODEL_6_5, true, pOptions16, _countof(pOptions16), values); // TODO: Test 6.6 here!
+    WEX::Logging::Log::Comment(L"==== cs_6_6 with native lifetime markers");
+    RunLifetimeIntrinsicTest(pDevice, pShader, D3D_SHADER_MODEL_6_6, false,
+      optsBase, _countof(optsBase), values);
     VERIFY_ARE_EQUAL(values[1], (uint32_t)1);
     VERIFY_ARE_EQUAL(values[1], (uint32_t)1);
+
+    if (bDXRSupported) {
+      WEX::Logging::Log::Comment(L"==== DXR lib_6_6 with native lifetime markers");
+      RunLifetimeIntrinsicTest(pDevice, pShader, D3D_SHADER_MODEL_6_6, true,
+        optsBase, _countof(optsBase), values);
+      VERIFY_ARE_EQUAL(values[1], (uint32_t)1);
+    }
   }
   }
 }
 }
 
 
@@ -9392,6 +9434,12 @@ TEST_F(ExecutionTest, HelperLaneTestWave) {
       continue;
       continue;
     }
     }
 
 
+    if (GetTestParamUseWARP(UseWarpByDefault()) || IsDeviceBasicAdapter(pDevice)) {
+      WEX::Logging::Log::Comment(L"WARP has a known issue with HelperLaneTestWave.");
+      WEX::Logging::Log::Result(WEX::Logging::TestResults::Skipped);
+      return;
+    }
+
     if (!DoesDeviceSupportWaveOps(pDevice)) {
     if (!DoesDeviceSupportWaveOps(pDevice)) {
       LogCommentFmt(L"Device does not support wave operations in shader model 6.%1u", ((UINT)sm & 0x0f));
       LogCommentFmt(L"Device does not support wave operations in shader model 6.%1u", ((UINT)sm & 0x0f));
       continue;
       continue;

+ 1 - 0
tools/clang/unittests/HLSL/LinkerTest.cpp

@@ -793,6 +793,7 @@ TEST_F(LinkerTest, RunLinkToLibWithGlobalCtor) {
 }
 }
 
 
 TEST_F(LinkerTest, LinkSm63ToSm66) {
 TEST_F(LinkerTest, LinkSm63ToSm66) {
+  if (m_ver.SkipDxilVersion(1, 6)) return;
   CComPtr<IDxcBlob> pLib0;
   CComPtr<IDxcBlob> pLib0;
   CompileLib(L"..\\CodeGenHLSL\\linker\\link_to_sm66.hlsl", &pLib0, {}, L"lib_6_3");
   CompileLib(L"..\\CodeGenHLSL\\linker\\link_to_sm66.hlsl", &pLib0, {}, L"lib_6_3");
 
 

+ 14 - 4
utils/hct/VerifierHelper.py

@@ -48,13 +48,18 @@ HlslVerifierTestCpp = os.path.expandvars(r'${HLSL_SRC_DIR}\tools\clang\unittests
 HlslDataDir = os.path.expandvars(r'${HLSL_SRC_DIR}\tools\clang\test\HLSL')
 HlslDataDir = os.path.expandvars(r'${HLSL_SRC_DIR}\tools\clang\test\HLSL')
 HlslBinDir = os.path.expandvars(r'${HLSL_BLD_DIR}\Debug\bin')
 HlslBinDir = os.path.expandvars(r'${HLSL_BLD_DIR}\Debug\bin')
 VerifierTests = {
 VerifierTests = {
+    'RunArrayIndexOutOfBounds': 'array-index-out-of-bounds-HV-2016.hlsl',
+    'RunArrayLength': 'array-length.hlsl',
     'RunAttributes': 'attributes.hlsl',
     'RunAttributes': 'attributes.hlsl',
     'RunBadInclude': 'bad-include.hlsl',
     'RunBadInclude': 'bad-include.hlsl',
     'RunBinopDims': 'binop-dims.hlsl',
     'RunBinopDims': 'binop-dims.hlsl',
+    'RunBuiltinTypesNoInheritance': 'builtin-types-no-inheritance.hlsl',
     'RunCXX11Attributes': 'cxx11-attributes.hlsl',
     'RunCXX11Attributes': 'cxx11-attributes.hlsl',
     'RunConstAssign': 'const-assign.hlsl',
     'RunConstAssign': 'const-assign.hlsl',
     'RunConstDefault': 'const-default.hlsl',
     'RunConstDefault': 'const-default.hlsl',
     'RunConstExpr': 'const-expr.hlsl',
     'RunConstExpr': 'const-expr.hlsl',
+    'RunConversionsBetweenTypeShapes': 'conversions-between-type-shapes.hlsl',
+    'RunConversionsNonNumericAggregates': 'conversions-non-numeric-aggregates.hlsl',
     'RunCppErrors': 'cpp-errors.hlsl',
     'RunCppErrors': 'cpp-errors.hlsl',
     'RunCppErrorsHV2015': 'cpp-errors-hv2015.hlsl',
     'RunCppErrorsHV2015': 'cpp-errors-hv2015.hlsl',
     'RunDerivedToBaseCasts': 'derived-to-base.hlsl',
     'RunDerivedToBaseCasts': 'derived-to-base.hlsl',
@@ -62,12 +67,15 @@ VerifierTests = {
     'RunEnums': 'enums.hlsl',
     'RunEnums': 'enums.hlsl',
     'RunFunctions': 'functions.hlsl',
     'RunFunctions': 'functions.hlsl',
     'RunImplicitCasts': 'implicit-casts.hlsl',
     'RunImplicitCasts': 'implicit-casts.hlsl',
+    'RunIncompleteArray': 'incomp_array_err.hlsl',
+    'RunIncompleteType': 'incomplete-type.hlsl',
     'RunIndexingOperator': 'indexing-operator.hlsl',
     'RunIndexingOperator': 'indexing-operator.hlsl',
     'RunIntrinsicExamples': 'intrinsic-examples.hlsl',
     'RunIntrinsicExamples': 'intrinsic-examples.hlsl',
     'RunLiterals': 'literals.hlsl',
     'RunLiterals': 'literals.hlsl',
     'RunMatrixAssignments': 'matrix-assignments.hlsl',
     'RunMatrixAssignments': 'matrix-assignments.hlsl',
     'RunMatrixSyntax': 'matrix-syntax.hlsl',
     'RunMatrixSyntax': 'matrix-syntax.hlsl',
     'RunMatrixSyntaxExactPrecision': 'matrix-syntax-exact-precision.hlsl',
     'RunMatrixSyntaxExactPrecision': 'matrix-syntax-exact-precision.hlsl',
+    'RunMintypesPromotionWarnings': 'mintypes-promotion-warnings.hlsl',
     'RunMoreOperators': 'more-operators.hlsl',
     'RunMoreOperators': 'more-operators.hlsl',
     'RunObjectOperators': 'object-operators.hlsl',
     'RunObjectOperators': 'object-operators.hlsl',
     'RunPackReg': 'packreg.hlsl',
     'RunPackReg': 'packreg.hlsl',
@@ -79,6 +87,7 @@ VerifierTests = {
     'RunScalarOperatorsAssignExactPrecision': 'scalar-operators-assign-exact-precision.hlsl',
     'RunScalarOperatorsAssignExactPrecision': 'scalar-operators-assign-exact-precision.hlsl',
     'RunScalarOperatorsExactPrecision': 'scalar-operators-exact-precision.hlsl',
     'RunScalarOperatorsExactPrecision': 'scalar-operators-exact-precision.hlsl',
     'RunSemantics': 'semantics.hlsl',
     'RunSemantics': 'semantics.hlsl',
+    'RunSizeof': 'sizeof.hlsl',
     'RunString': 'string.hlsl',
     'RunString': 'string.hlsl',
     'RunStructAssignments': 'struct-assignments.hlsl',
     'RunStructAssignments': 'struct-assignments.hlsl',
     'RunSubobjects': 'subobjects-syntax.hlsl',
     'RunSubobjects': 'subobjects-syntax.hlsl',
@@ -100,6 +109,7 @@ fxcExcludedTests = [
     'RunCppErrorsHV2015',
     'RunCppErrorsHV2015',
     'RunCXX11Attributes',
     'RunCXX11Attributes',
     'RunEnums',
     'RunEnums',
+    'RunIncompleteType',
     'RunIntrinsicExamples',
     'RunIntrinsicExamples',
     'RunMatrixSyntaxExactPrecision',
     'RunMatrixSyntaxExactPrecision',
     'RunRayTracings',
     'RunRayTracings',
@@ -578,7 +588,7 @@ class File(object):
             result[i] = line, diag_col, expected
             result[i] = line, diag_col, expected
 
 
         with open(result_filename, 'wt') as f:
         with open(result_filename, 'wt') as f:
-            f.write('\n'.join(map(lambda (line, diag_col, expected): line, result)))
+            f.write('\n'.join(map((lambda res: res[0]), result)))
 
 
     def TryAst(self, result_filename=None):
     def TryAst(self, result_filename=None):
         temp_filename = os.path.expandvars(r'${TEMP}\%s' % os.path.split(self.filename)[1])
         temp_filename = os.path.expandvars(r'${TEMP}\%s' % os.path.split(self.filename)[1])
@@ -658,19 +668,19 @@ def ProcessVerifierOutput(lines):
             files[cur_filename] = File(cur_filename)
             files[cur_filename] = File(cur_filename)
             state = 'WaitingForCategory'
             state = 'WaitingForCategory'
             continue
             continue
-        if state is 'WaitingForFile':
+        if state == 'WaitingForFile':
             m = rxEndGroup.match(line)
             m = rxEndGroup.match(line)
             if m and m.group(2) == 'Failed':
             if m and m.group(2) == 'Failed':
                 # This usually happens when compiler crashes
                 # This usually happens when compiler crashes
                 print('Fatal Error: test %s failed without verifier results.' % cur_test)
                 print('Fatal Error: test %s failed without verifier results.' % cur_test)
-        if state is 'WaitingForCategory' or state is 'ReadingErrors':
+        if state == 'WaitingForCategory' or state == 'ReadingErrors':
             m = rxExpected.match(line)
             m = rxExpected.match(line)
             if m:
             if m:
                 ew = m.group(1)
                 ew = m.group(1)
                 expected = m.group(2) == 'expected but not seen'
                 expected = m.group(2) == 'expected but not seen'
                 state = 'ReadingErrors'
                 state = 'ReadingErrors'
                 continue
                 continue
-        if state is 'ReadingErrors':
+        if state == 'ReadingErrors':
             m = rxDiagReport.match(line)
             m = rxDiagReport.match(line)
             if m:
             if m:
                 line_num = int(m.group(2))
                 line_num = int(m.group(2))