Browse Source

Clean more validation TODOs.

Xiang Li 8 years ago
parent
commit
8eb801f1fd

+ 9 - 12
docs/DXIL.rst

@@ -2140,7 +2140,7 @@ INSTR.CBUFFERCLASSFORCBUFFERHANDLE        Expect Cbuffer for CBufferLoad handle
 INSTR.CBUFFEROUTOFBOUND                   Cbuffer access out of bound
 INSTR.CBUFFEROUTOFBOUND                   Cbuffer access out of bound
 INSTR.COORDINATECOUNTFORRAWTYPEDBUF       raw/typed buffer don't need 2 coordinates
 INSTR.COORDINATECOUNTFORRAWTYPEDBUF       raw/typed buffer don't need 2 coordinates
 INSTR.COORDINATECOUNTFORSTRUCTBUF         structured buffer require 2 coordinates
 INSTR.COORDINATECOUNTFORSTRUCTBUF         structured buffer require 2 coordinates
-INSTR.DETERMINATEDERIVATIVE               gradient operation uses a value that may not be defined for all pixels (in UAV loads can not participate in gradient operations)
+INSTR.DETERMINATEDERIVATIVE               TODO - gradient operation uses a value that may not be defined for all pixels (in UAV loads can not participate in gradient operations)
 INSTR.DXILSTRUCTUSER                      Dxil struct types should only used by ExtractValue
 INSTR.DXILSTRUCTUSER                      Dxil struct types should only used by ExtractValue
 INSTR.DXILSTRUCTUSEROUTOFBOUND            Index out of bound when extract value from dxil struct types
 INSTR.DXILSTRUCTUSEROUTOFBOUND            Index out of bound when extract value from dxil struct types
 INSTR.ERR_ALIAS_ARRAY_INDEX_OUT_OF_BOUNDS TODO - ERR_ALIAS_ARRAY_INDEX_OUT_OF_BOUNDS
 INSTR.ERR_ALIAS_ARRAY_INDEX_OUT_OF_BOUNDS TODO - ERR_ALIAS_ARRAY_INDEX_OUT_OF_BOUNDS
@@ -2159,14 +2159,14 @@ INSTR.INBOUNDSACCESS                      TODO - Access to out-of-bounds memory
 INSTR.MINPRECISIONNOTPRECISE              Instructions marked precise may not refer to minprecision values
 INSTR.MINPRECISIONNOTPRECISE              Instructions marked precise may not refer to minprecision values
 INSTR.MIPLEVELFORGETDIMENSION             Use mip level on buffer when GetDimensions
 INSTR.MIPLEVELFORGETDIMENSION             Use mip level on buffer when GetDimensions
 INSTR.MIPONUAVLOAD                        uav load don't support mipLevel/sampleIndex
 INSTR.MIPONUAVLOAD                        uav load don't support mipLevel/sampleIndex
-INSTR.NOIDIVBYZERO                        TODO - No signed integer division by zero
-INSTR.NOINDEFINITEACOS                    TODO - No indefinite arccosine
-INSTR.NOINDEFINITEASIN                    TODO - No indefinite arcsine
-INSTR.NOINDEFINITEDSXY                    TODO - No indefinite derivative calculation
-INSTR.NOINDEFINITELOG                     TODO - No indefinite logarithm
+INSTR.NOIDIVBYZERO                        No signed integer division by zero
+INSTR.NOINDEFINITEACOS                    No indefinite arccosine
+INSTR.NOINDEFINITEASIN                    No indefinite arcsine
+INSTR.NOINDEFINITEDSXY                    No indefinite derivative calculation
+INSTR.NOINDEFINITELOG                     No indefinite logarithm
 INSTR.NOPTRCAST                           TODO - Cast between pointer types disallowed
 INSTR.NOPTRCAST                           TODO - Cast between pointer types disallowed
 INSTR.NOREADINGUNINITIALIZED              Instructions should not read uninitialized value
 INSTR.NOREADINGUNINITIALIZED              Instructions should not read uninitialized value
-INSTR.NOUDIVBYZERO                        TODO - No unsigned integer division by zero
+INSTR.NOUDIVBYZERO                        No unsigned integer division by zero
 INSTR.OFFSETONUAVLOAD                     uav load don't support offset
 INSTR.OFFSETONUAVLOAD                     uav load don't support offset
 INSTR.OLOAD                               DXIL intrinsic overload must be valid
 INSTR.OLOAD                               DXIL intrinsic overload must be valid
 INSTR.ONLYONEALLOCCONSUME                 RWStructuredBuffers may increment or decrement their counters, but not both.
 INSTR.ONLYONEALLOCCONSUME                 RWStructuredBuffers may increment or decrement their counters, but not both.
@@ -2206,6 +2206,7 @@ INSTR.WAR_GRADIENT_IN_VARYING_FLOW        TODO - gradient instruction used in a
 INSTR.WRITEMASKFORTYPEDUAVSTORE           store on typed uav must write to all four components of the UAV
 INSTR.WRITEMASKFORTYPEDUAVSTORE           store on typed uav must write to all four components of the UAV
 INSTR.WRITEMASKMATCHVALUEFORUAVSTORE      uav store write mask must match store value mask, write mask is %0 and store value mask is %1
 INSTR.WRITEMASKMATCHVALUEFORUAVSTORE      uav store write mask must match store value mask, write mask is %0 and store value mask is %1
 META.BRANCHFLATTEN                        Can't use branch and flatten attributes together
 META.BRANCHFLATTEN                        Can't use branch and flatten attributes together
+META.CONTROLFLOWHINTNOTONCONTROLFLOW      Control flow hint only works on control flow inst
 META.DENSERESIDS                          Resource identifiers must be zero-based and dense
 META.DENSERESIDS                          Resource identifiers must be zero-based and dense
 META.ENTRYFUNCTION                        entrypoint not found
 META.ENTRYFUNCTION                        entrypoint not found
 META.FLAGSUSAGE                           Flags must match usage
 META.FLAGSUSAGE                           Flags must match usage
@@ -2232,7 +2233,7 @@ META.TARGET                               Target triple must be 'dxil-ms-dx'
 META.TESSELLATOROUTPUTPRIMITIVE           Invalid Tessellator Output Primitive specified. Must be point, line, triangleCW or triangleCCW.
 META.TESSELLATOROUTPUTPRIMITIVE           Invalid Tessellator Output Primitive specified. Must be point, line, triangleCW or triangleCCW.
 META.TESSELLATORPARTITION                 Invalid Tessellator Partitioning specified. Must be integer, pow2, fractional_odd or fractional_even.
 META.TESSELLATORPARTITION                 Invalid Tessellator Partitioning specified. Must be integer, pow2, fractional_odd or fractional_even.
 META.TEXTURETYPE                          elements of typed buffers and textures must fit in four 32-bit quantities
 META.TEXTURETYPE                          elements of typed buffers and textures must fit in four 32-bit quantities
-META.USED                                 TODO - All metadata must be used
+META.USED                                 All metadata must be used by dxil
 META.VALIDSAMPLERMODE                     Invalid sampler mode on sampler
 META.VALIDSAMPLERMODE                     Invalid sampler mode on sampler
 META.VALUERANGE                           Metadata value must be within range
 META.VALUERANGE                           Metadata value must be within range
 META.WELLFORMED                           TODO - Metadata must be well-formed in operand count and types
 META.WELLFORMED                           TODO - Metadata must be well-formed in operand count and types
@@ -2246,10 +2247,6 @@ SM.CSNORETURN                             Compute shaders can't return values, o
 SM.DOMAINLOCATIONIDXOOB                   DomainLocation component index out of bounds for the domain.
 SM.DOMAINLOCATIONIDXOOB                   DomainLocation component index out of bounds for the domain.
 SM.DSINPUTCONTROLPOINTCOUNTRANGE          DS input control point count must be [0..%0].  %1 specified
 SM.DSINPUTCONTROLPOINTCOUNTRANGE          DS input control point count must be [0..%0].  %1 specified
 SM.ERR_BIND_RESOURCE_RANGE_OVERFLOW       TODO - ERR_BIND_RESOURCE_RANGE_OVERFLOW
 SM.ERR_BIND_RESOURCE_RANGE_OVERFLOW       TODO - ERR_BIND_RESOURCE_RANGE_OVERFLOW
-SM.ERR_MAX_CBUFFER_EXCEEDED               TODO - The maximum number of constant buffer slots is exceeded for a library (slot index=%u, max slots=%u)
-SM.ERR_MAX_CONST_EXCEEDED                 TODO - ERR_MAX_CONST_EXCEEDED
-SM.ERR_MAX_SAMPLER_EXCEEDED               TODO - The maximum number of sampler slots is exceeded for a library (slot index=%u, max slots=%u)
-SM.ERR_MAX_TEXTURE_EXCEEDED               TODO - The maximum number of texture slots is exceeded for a library (slot index=%u, max slots=%u)
 SM.ERR_UNABLE_TO_BIND_RESOURCE            TODO - ERR_UNABLE_TO_BIND_RESOURCE
 SM.ERR_UNABLE_TO_BIND_RESOURCE            TODO - ERR_UNABLE_TO_BIND_RESOURCE
 SM.ERR_UNABLE_TO_BIND_UNBOUNDED_RESOURCE  TODO - ERR_UNABLE_TO_BIND_UNBOUNDED_RESOURCE
 SM.ERR_UNABLE_TO_BIND_UNBOUNDED_RESOURCE  TODO - ERR_UNABLE_TO_BIND_UNBOUNDED_RESOURCE
 SM.GSINSTANCECOUNTRANGE                   GS instance count must be [1..%0].  %1 specified
 SM.GSINSTANCECOUNTRANGE                   GS instance count must be [1..%0].  %1 specified

+ 0 - 10
include/dxc/HLSL/DxilConstants.h

@@ -52,18 +52,8 @@ namespace DXIL {
 
 
   // TODO: move these to appropriate places (ShaderModel.cpp?)
   // TODO: move these to appropriate places (ShaderModel.cpp?)
   const unsigned kMaxTempRegCount = 4096;         // DXBC only
   const unsigned kMaxTempRegCount = 4096;         // DXBC only
-  const unsigned kMaxD3D11ResourceCount = 128;
-  const unsigned kMaxD3D11SamplerCount = 16;
-  const unsigned kMaxD3D11CBufferCount = 14;
   const unsigned kMaxCBufferSize = 4096;
   const unsigned kMaxCBufferSize = 4096;
   const unsigned kMaxStructBufferStride = 2048;
   const unsigned kMaxStructBufferStride = 2048;
-  const unsigned kMaxD3D10UAVCount = 8;
-  const unsigned kMaxD3D10CS4UAVCount = 1;
-  const unsigned kMaxD3D11UAVCount = 64;
-  const unsigned kMaxD3D12TextureCount = 2048;
-  const unsigned kMaxD3D12SamplerCount = 128;
-  const unsigned kMaxD3D12UAVCount = 512;
-  const unsigned kMaxD3D12CBufferCount = 256;
   const unsigned kMaxHSOutputControlPointsTotalScalars = 3968;
   const unsigned kMaxHSOutputControlPointsTotalScalars = 3968;
   const unsigned kMaxHSOutputPatchConstantTotalScalars = 32*4;
   const unsigned kMaxHSOutputPatchConstantTotalScalars = 32*4;
   const unsigned kMaxOutputTotalScalars = 32*4;
   const unsigned kMaxOutputTotalScalars = 32*4;

+ 0 - 3
include/dxc/HLSL/DxilShaderModel.h

@@ -49,9 +49,6 @@ public:
   unsigned GetNumTempRegs() const { return DXIL::kMaxTempRegCount; }
   unsigned GetNumTempRegs() const { return DXIL::kMaxTempRegCount; }
   unsigned GetNumInputRegs() const { return m_NumInputRegs; }
   unsigned GetNumInputRegs() const { return m_NumInputRegs; }
   unsigned GetNumOutputRegs() const { return m_NumOutputRegs; }
   unsigned GetNumOutputRegs() const { return m_NumOutputRegs; }
-  unsigned GetNumResources() const;
-  unsigned GetNumSamplers() const;
-  unsigned GetNumCBuffers() const;
   unsigned GetCBufferSize() const { return DXIL::kMaxCBufferSize; }
   unsigned GetCBufferSize() const { return DXIL::kMaxCBufferSize; }
   unsigned SupportsUAV() const { return m_bUAVs; }
   unsigned SupportsUAV() const { return m_bUAVs; }
   unsigned SupportsTypedUAVs() const { return m_bTypedUavs; }
   unsigned SupportsTypedUAVs() const { return m_bTypedUavs; }

+ 9 - 12
include/dxc/HLSL/DxilValidation.h

@@ -47,7 +47,7 @@ enum class ValidationRule : unsigned {
   InstrCannotPullPosition, // pull-model evaluation of position disallowed
   InstrCannotPullPosition, // pull-model evaluation of position disallowed
   InstrCoordinateCountForRawTypedBuf, // raw/typed buffer don't need 2 coordinates
   InstrCoordinateCountForRawTypedBuf, // raw/typed buffer don't need 2 coordinates
   InstrCoordinateCountForStructBuf, // structured buffer require 2 coordinates
   InstrCoordinateCountForStructBuf, // structured buffer require 2 coordinates
-  InstrDeterminateDerivative, // gradient operation uses a value that may not be defined for all pixels (in UAV loads can not participate in gradient operations)
+  InstrDeterminateDerivative, // TODO - gradient operation uses a value that may not be defined for all pixels (in UAV loads can not participate in gradient operations)
   InstrDxilStructUser, // Dxil struct types should only used by ExtractValue
   InstrDxilStructUser, // Dxil struct types should only used by ExtractValue
   InstrDxilStructUserOutOfBound, // Index out of bound when extract value from dxil struct types
   InstrDxilStructUserOutOfBound, // Index out of bound when extract value from dxil struct types
   InstrERR_ALIAS_ARRAY_INDEX_OUT_OF_BOUNDS, // TODO - ERR_ALIAS_ARRAY_INDEX_OUT_OF_BOUNDS
   InstrERR_ALIAS_ARRAY_INDEX_OUT_OF_BOUNDS, // TODO - ERR_ALIAS_ARRAY_INDEX_OUT_OF_BOUNDS
@@ -66,14 +66,14 @@ enum class ValidationRule : unsigned {
   InstrMinPrecisionNotPrecise, // Instructions marked precise may not refer to minprecision values
   InstrMinPrecisionNotPrecise, // Instructions marked precise may not refer to minprecision values
   InstrMipLevelForGetDimension, // Use mip level on buffer when GetDimensions
   InstrMipLevelForGetDimension, // Use mip level on buffer when GetDimensions
   InstrMipOnUAVLoad, // uav load don't support mipLevel/sampleIndex
   InstrMipOnUAVLoad, // uav load don't support mipLevel/sampleIndex
-  InstrNoIDivByZero, // TODO - No signed integer division by zero
-  InstrNoIndefiniteAcos, // TODO - No indefinite arccosine
-  InstrNoIndefiniteAsin, // TODO - No indefinite arcsine
-  InstrNoIndefiniteDsxy, // TODO - No indefinite derivative calculation
-  InstrNoIndefiniteLog, // TODO - No indefinite logarithm
+  InstrNoIDivByZero, // No signed integer division by zero
+  InstrNoIndefiniteAcos, // No indefinite arccosine
+  InstrNoIndefiniteAsin, // No indefinite arcsine
+  InstrNoIndefiniteDsxy, // No indefinite derivative calculation
+  InstrNoIndefiniteLog, // No indefinite logarithm
   InstrNoPtrCast, // TODO - Cast between pointer types disallowed
   InstrNoPtrCast, // TODO - Cast between pointer types disallowed
   InstrNoReadingUninitialized, // Instructions should not read uninitialized value
   InstrNoReadingUninitialized, // Instructions should not read uninitialized value
-  InstrNoUDivByZero, // TODO - No unsigned integer division by zero
+  InstrNoUDivByZero, // No unsigned integer division by zero
   InstrOffsetOnUAVLoad, // uav load don't support offset
   InstrOffsetOnUAVLoad, // uav load don't support offset
   InstrOload, // DXIL intrinsic overload must be valid
   InstrOload, // DXIL intrinsic overload must be valid
   InstrOnlyOneAllocConsume, // RWStructuredBuffers may increment or decrement their counters, but not both.
   InstrOnlyOneAllocConsume, // RWStructuredBuffers may increment or decrement their counters, but not both.
@@ -115,6 +115,7 @@ enum class ValidationRule : unsigned {
 
 
   // Metadata
   // Metadata
   MetaBranchFlatten, // Can't use branch and flatten attributes together
   MetaBranchFlatten, // Can't use branch and flatten attributes together
+  MetaControlFlowHintNotOnControlFlow, // Control flow hint only works on control flow inst
   MetaDenseResIDs, // Resource identifiers must be zero-based and dense
   MetaDenseResIDs, // Resource identifiers must be zero-based and dense
   MetaEntryFunction, // entrypoint not found
   MetaEntryFunction, // entrypoint not found
   MetaFlagsUsage, // Flags must match usage
   MetaFlagsUsage, // Flags must match usage
@@ -141,7 +142,7 @@ enum class ValidationRule : unsigned {
   MetaTessellatorOutputPrimitive, // Invalid Tessellator Output Primitive specified. Must be point, line, triangleCW or triangleCCW.
   MetaTessellatorOutputPrimitive, // Invalid Tessellator Output Primitive specified. Must be point, line, triangleCW or triangleCCW.
   MetaTessellatorPartition, // Invalid Tessellator Partitioning specified. Must be integer, pow2, fractional_odd or fractional_even.
   MetaTessellatorPartition, // Invalid Tessellator Partitioning specified. Must be integer, pow2, fractional_odd or fractional_even.
   MetaTextureType, // elements of typed buffers and textures must fit in four 32-bit quantities
   MetaTextureType, // elements of typed buffers and textures must fit in four 32-bit quantities
-  MetaUsed, // TODO - All metadata must be used
+  MetaUsed, // All metadata must be used by dxil
   MetaValidSamplerMode, // Invalid sampler mode on sampler 
   MetaValidSamplerMode, // Invalid sampler mode on sampler 
   MetaValueRange, // Metadata value must be within range
   MetaValueRange, // Metadata value must be within range
   MetaWellFormed, // TODO - Metadata must be well-formed in operand count and types
   MetaWellFormed, // TODO - Metadata must be well-formed in operand count and types
@@ -164,10 +165,6 @@ enum class ValidationRule : unsigned {
   SmDSInputControlPointCountRange, // DS input control point count must be [0..%0].  %1 specified
   SmDSInputControlPointCountRange, // DS input control point count must be [0..%0].  %1 specified
   SmDomainLocationIdxOOB, // DomainLocation component index out of bounds for the domain.
   SmDomainLocationIdxOOB, // DomainLocation component index out of bounds for the domain.
   SmERR_BIND_RESOURCE_RANGE_OVERFLOW, // TODO - ERR_BIND_RESOURCE_RANGE_OVERFLOW
   SmERR_BIND_RESOURCE_RANGE_OVERFLOW, // TODO - ERR_BIND_RESOURCE_RANGE_OVERFLOW
-  SmERR_MAX_CBUFFER_EXCEEDED, // TODO - The maximum number of constant buffer slots is exceeded for a library (slot index=%u, max slots=%u)
-  SmERR_MAX_CONST_EXCEEDED, // TODO - ERR_MAX_CONST_EXCEEDED
-  SmERR_MAX_SAMPLER_EXCEEDED, // TODO - The maximum number of sampler slots is exceeded for a library (slot index=%u, max slots=%u)
-  SmERR_MAX_TEXTURE_EXCEEDED, // TODO - The maximum number of texture slots is exceeded for a library (slot index=%u, max slots=%u)
   SmERR_UNABLE_TO_BIND_RESOURCE, // TODO - ERR_UNABLE_TO_BIND_RESOURCE
   SmERR_UNABLE_TO_BIND_RESOURCE, // TODO - ERR_UNABLE_TO_BIND_RESOURCE
   SmERR_UNABLE_TO_BIND_UNBOUNDED_RESOURCE, // TODO - ERR_UNABLE_TO_BIND_UNBOUNDED_RESOURCE
   SmERR_UNABLE_TO_BIND_UNBOUNDED_RESOURCE, // TODO - ERR_UNABLE_TO_BIND_UNBOUNDED_RESOURCE
   SmGSInstanceCountRange, // GS instance count must be [1..%0].  %1 specified
   SmGSInstanceCountRange, // GS instance count must be [1..%0].  %1 specified

+ 2 - 1
lib/HLSL/DxilModule.cpp

@@ -405,7 +405,8 @@ void DxilModule::CollectShaderFlags(ShaderFlags &Flags) {
   }
   }
 
 
   unsigned NumUAVs = m_UAVs.size();
   unsigned NumUAVs = m_UAVs.size();
-  if (NumUAVs > DXIL::kMaxD3D10UAVCount)
+  const unsigned kSmallUAVCount = 8;
+  if (NumUAVs > kSmallUAVCount)
     Flags.Set64UAVs(true);
     Flags.Set64UAVs(true);
   if (NumUAVs && !(SM->IsCS() || SM->IsPS()))
   if (NumUAVs && !(SM->IsCS() || SM->IsPS()))
     Flags.SetUAVsAtEveryStage(true);
     Flags.SetUAVsAtEveryStage(true);

+ 1 - 15
lib/HLSL/DxilShaderModel.cpp

@@ -98,22 +98,8 @@ const ShaderModel *ShaderModel::GetInvalid() {
   return &ms_ShaderModels[kNumShaderModels - 1];
   return &ms_ShaderModels[kNumShaderModels - 1];
 }
 }
 
 
-unsigned ShaderModel::GetNumResources() const {
-  return IsSM51Plus() ? UINT_MAX : DXIL::kMaxD3D11ResourceCount;
-}
-
-unsigned ShaderModel::GetNumSamplers() const {
-  return IsSM51Plus() ? UINT_MAX : DXIL::kMaxD3D11SamplerCount;
-}
-
-unsigned ShaderModel::GetNumCBuffers() const {
-  return IsSM51Plus() ? UINT_MAX : DXIL::kMaxD3D11CBufferCount;
-}
-
 unsigned ShaderModel::GetUAVRegsBase() const {
 unsigned ShaderModel::GetUAVRegsBase() const {
-  if (IsSM51Plus()) return UINT_MAX;
-  if (IsSM50Plus()) return DXIL::kMaxD3D11UAVCount;
-  return SupportsUAV() ? DXIL::kMaxD3D10UAVCount : 0;
+  return UINT_MAX;
 }
 }
 
 
 typedef ShaderModel SM;
 typedef ShaderModel SM;

+ 374 - 148
lib/HLSL/DxilValidation.cpp

@@ -52,7 +52,7 @@ const char *hlsl::GetValidationRuleText(ValidationRule value) {
     case hlsl::ValidationRule::BitcodeValid: return "Module bitcode is invalid";
     case hlsl::ValidationRule::BitcodeValid: return "Module bitcode is invalid";
     case hlsl::ValidationRule::MetaRequired: return "TODO - Required metadata missing";
     case hlsl::ValidationRule::MetaRequired: return "TODO - Required metadata missing";
     case hlsl::ValidationRule::MetaKnown: return "Named metadata '%0' is unknown";
     case hlsl::ValidationRule::MetaKnown: return "Named metadata '%0' is unknown";
-    case hlsl::ValidationRule::MetaUsed: return "TODO - All metadata must be used";
+    case hlsl::ValidationRule::MetaUsed: return "All metadata must be used by dxil";
     case hlsl::ValidationRule::MetaTarget: return "Unknown target triple '%0'";
     case hlsl::ValidationRule::MetaTarget: return "Unknown target triple '%0'";
     case hlsl::ValidationRule::MetaWellFormed: return "TODO - Metadata must be well-formed in operand count and types";
     case hlsl::ValidationRule::MetaWellFormed: return "TODO - Metadata must be well-formed in operand count and types";
     case hlsl::ValidationRule::MetaSemanticLen: return "Semantic length must be at least 1 and at most 64";
     case hlsl::ValidationRule::MetaSemanticLen: return "Semantic length must be at least 1 and at most 64";
@@ -80,6 +80,7 @@ const char *hlsl::GetValidationRuleText(ValidationRule value) {
     case hlsl::ValidationRule::MetaInvalidControlFlowHint: return "Invalid control flow hint";
     case hlsl::ValidationRule::MetaInvalidControlFlowHint: return "Invalid control flow hint";
     case hlsl::ValidationRule::MetaBranchFlatten: return "Can't use branch and flatten attributes together";
     case hlsl::ValidationRule::MetaBranchFlatten: return "Can't use branch and flatten attributes together";
     case hlsl::ValidationRule::MetaForceCaseOnSwitch: return "Attribute forcecase only works for switch";
     case hlsl::ValidationRule::MetaForceCaseOnSwitch: return "Attribute forcecase only works for switch";
+    case hlsl::ValidationRule::MetaControlFlowHintNotOnControlFlow: return "Control flow hint only works on control flow inst";
     case hlsl::ValidationRule::MetaTextureType: return "elements of typed buffers and textures must fit in four 32-bit quantities";
     case hlsl::ValidationRule::MetaTextureType: return "elements of typed buffers and textures must fit in four 32-bit quantities";
     case hlsl::ValidationRule::InstrOload: return "DXIL intrinsic overload must be valid";
     case hlsl::ValidationRule::InstrOload: return "DXIL intrinsic overload must be valid";
     case hlsl::ValidationRule::InstrCallOload: return "Call to DXIL intrinsic '%0' does not match an allowed overload signature";
     case hlsl::ValidationRule::InstrCallOload: return "Call to DXIL intrinsic '%0' does not match an allowed overload signature";
@@ -98,18 +99,18 @@ const char *hlsl::GetValidationRuleText(ValidationRule value) {
     case hlsl::ValidationRule::InstrInBoundsAccess: return "TODO - Access to out-of-bounds memory is disallowed";
     case hlsl::ValidationRule::InstrInBoundsAccess: return "TODO - Access to out-of-bounds memory is disallowed";
     case hlsl::ValidationRule::InstrOpConstRange: return "TODO - Constant values must be in-range for operation";
     case hlsl::ValidationRule::InstrOpConstRange: return "TODO - Constant values must be in-range for operation";
     case hlsl::ValidationRule::InstrImmBiasForSampleB: return "bias amount for sample_b must be in the range [%0,%1], but %2 was specified as an immediate";
     case hlsl::ValidationRule::InstrImmBiasForSampleB: return "bias amount for sample_b must be in the range [%0,%1], but %2 was specified as an immediate";
-    case hlsl::ValidationRule::InstrNoIndefiniteLog: return "TODO - No indefinite logarithm";
-    case hlsl::ValidationRule::InstrNoIndefiniteAsin: return "TODO - No indefinite arcsine";
-    case hlsl::ValidationRule::InstrNoIndefiniteAcos: return "TODO - No indefinite arccosine";
-    case hlsl::ValidationRule::InstrNoIDivByZero: return "TODO - No signed integer division by zero";
-    case hlsl::ValidationRule::InstrNoUDivByZero: return "TODO - No unsigned integer division by zero";
-    case hlsl::ValidationRule::InstrNoIndefiniteDsxy: return "TODO - No indefinite derivative calculation";
+    case hlsl::ValidationRule::InstrNoIndefiniteLog: return "No indefinite logarithm";
+    case hlsl::ValidationRule::InstrNoIndefiniteAsin: return "No indefinite arcsine";
+    case hlsl::ValidationRule::InstrNoIndefiniteAcos: return "No indefinite arccosine";
+    case hlsl::ValidationRule::InstrNoIDivByZero: return "No signed integer division by zero";
+    case hlsl::ValidationRule::InstrNoUDivByZero: return "No unsigned integer division by zero";
+    case hlsl::ValidationRule::InstrNoIndefiniteDsxy: return "No indefinite derivative calculation";
     case hlsl::ValidationRule::InstrERR_ALIAS_ARRAY_INDEX_OUT_OF_BOUNDS: return "TODO - ERR_ALIAS_ARRAY_INDEX_OUT_OF_BOUNDS";
     case hlsl::ValidationRule::InstrERR_ALIAS_ARRAY_INDEX_OUT_OF_BOUNDS: return "TODO - ERR_ALIAS_ARRAY_INDEX_OUT_OF_BOUNDS";
     case hlsl::ValidationRule::InstrMinPrecisionNotPrecise: return "Instructions marked precise may not refer to minprecision values";
     case hlsl::ValidationRule::InstrMinPrecisionNotPrecise: return "Instructions marked precise may not refer to minprecision values";
     case hlsl::ValidationRule::InstrOnlyOneAllocConsume: return "RWStructuredBuffers may increment or decrement their counters, but not both.";
     case hlsl::ValidationRule::InstrOnlyOneAllocConsume: return "RWStructuredBuffers may increment or decrement their counters, but not both.";
     case hlsl::ValidationRule::InstrTextureOffset: return "offset texture instructions must take offset which can resolve to integer literal in the range -8 to 7";
     case hlsl::ValidationRule::InstrTextureOffset: return "offset texture instructions must take offset which can resolve to integer literal in the range -8 to 7";
     case hlsl::ValidationRule::InstrWAR_GRADIENT_IN_VARYING_FLOW: return "TODO - gradient instruction used in a loop with varying iteration; partial derivatives may have undefined value";
     case hlsl::ValidationRule::InstrWAR_GRADIENT_IN_VARYING_FLOW: return "TODO - gradient instruction used in a loop with varying iteration; partial derivatives may have undefined value";
-    case hlsl::ValidationRule::InstrDeterminateDerivative: return "gradient operation uses a value that may not be defined for all pixels (in UAV loads can not participate in gradient operations)";
+    case hlsl::ValidationRule::InstrDeterminateDerivative: return "TODO - gradient operation uses a value that may not be defined for all pixels (in UAV loads can not participate in gradient operations)";
     case hlsl::ValidationRule::InstrERR_NON_LITERAL_RESOURCE: return "TODO - Resources being indexed cannot come from conditional expressions, they must come from literal expressions.";
     case hlsl::ValidationRule::InstrERR_NON_LITERAL_RESOURCE: return "TODO - Resources being indexed cannot come from conditional expressions, they must come from literal expressions.";
     case hlsl::ValidationRule::InstrERR_NON_LITERAL_STREAM: return "TODO - stream parameter must come from a literal expression";
     case hlsl::ValidationRule::InstrERR_NON_LITERAL_STREAM: return "TODO - stream parameter must come from a literal expression";
     case hlsl::ValidationRule::InstrCannotPullPosition: return "%0 does not support pull-model evaluation of position";
     case hlsl::ValidationRule::InstrCannotPullPosition: return "%0 does not support pull-model evaluation of position";
@@ -204,10 +205,6 @@ const char *hlsl::GetValidationRuleText(ValidationRule value) {
     case hlsl::ValidationRule::SmUndefinedOutput: return "Not all elements of output %0 were written";
     case hlsl::ValidationRule::SmUndefinedOutput: return "Not all elements of output %0 were written";
     case hlsl::ValidationRule::SmCSNoReturn: return "Compute shaders can't return values, outputs must be written in writable resources (UAVs).";
     case hlsl::ValidationRule::SmCSNoReturn: return "Compute shaders can't return values, outputs must be written in writable resources (UAVs).";
     case hlsl::ValidationRule::SmCBufferTemplateTypeMustBeStruct: return "D3D12 constant/texture buffer template element can only be a struct";
     case hlsl::ValidationRule::SmCBufferTemplateTypeMustBeStruct: return "D3D12 constant/texture buffer template element can only be a struct";
-    case hlsl::ValidationRule::SmERR_MAX_CONST_EXCEEDED: return "TODO - ERR_MAX_CONST_EXCEEDED";
-    case hlsl::ValidationRule::SmERR_MAX_SAMPLER_EXCEEDED: return "TODO - The maximum number of sampler slots is exceeded for a library (slot index=%u, max slots=%u)";
-    case hlsl::ValidationRule::SmERR_MAX_TEXTURE_EXCEEDED: return "TODO - The maximum number of texture slots is exceeded for a library (slot index=%u, max slots=%u)";
-    case hlsl::ValidationRule::SmERR_MAX_CBUFFER_EXCEEDED: return "TODO - The maximum number of constant buffer slots is exceeded for a library (slot index=%u, max slots=%u)";
     case hlsl::ValidationRule::SmERR_UNABLE_TO_BIND_RESOURCE: return "TODO - ERR_UNABLE_TO_BIND_RESOURCE";
     case hlsl::ValidationRule::SmERR_UNABLE_TO_BIND_RESOURCE: return "TODO - ERR_UNABLE_TO_BIND_RESOURCE";
     case hlsl::ValidationRule::SmERR_UNABLE_TO_BIND_UNBOUNDED_RESOURCE: return "TODO - ERR_UNABLE_TO_BIND_UNBOUNDED_RESOURCE";
     case hlsl::ValidationRule::SmERR_UNABLE_TO_BIND_UNBOUNDED_RESOURCE: return "TODO - ERR_UNABLE_TO_BIND_UNBOUNDED_RESOURCE";
     case hlsl::ValidationRule::SmERR_BIND_RESOURCE_RANGE_OVERFLOW: return "TODO - ERR_BIND_RESOURCE_RANGE_OVERFLOW";
     case hlsl::ValidationRule::SmERR_BIND_RESOURCE_RANGE_OVERFLOW: return "TODO - ERR_BIND_RESOURCE_RANGE_OVERFLOW";
@@ -287,11 +284,20 @@ struct ValidationContext {
   std::vector<unsigned> outputCols;
   std::vector<unsigned> outputCols;
   std::vector<unsigned> patchConstCols;
   std::vector<unsigned> patchConstCols;
   unsigned domainLocSize;
   unsigned domainLocSize;
+  const unsigned kDxilControlFlowHintMDKind;
+  const unsigned kDxilPreciseMDKind;
+  const unsigned kLLVMLoopMDKind;
 
 
   ValidationContext(Module &llvmModule, Module *DebugModule,
   ValidationContext(Module &llvmModule, Module *DebugModule,
                     DxilModule &dxilModule,
                     DxilModule &dxilModule,
                     DiagnosticPrinterRawOStream &DiagPrn)
                     DiagnosticPrinterRawOStream &DiagPrn)
       : M(llvmModule), pDebugModule(DebugModule), DxilMod(dxilModule),
       : M(llvmModule), pDebugModule(DebugModule), DxilMod(dxilModule),
+        kDxilControlFlowHintMDKind(llvmModule.getContext().getMDKindID(
+            DxilMDHelper::kDxilControlFlowHintMDName)),
+        kDxilPreciseMDKind(llvmModule.getContext().getMDKindID(
+            DxilMDHelper::kDxilPreciseAttributeMDName)),
+        kLLVMLoopMDKind(llvmModule.getContext().getMDKindID(
+            "llvm.loop")),
         DiagPrinter(DiagPrn), LastRuleEmit((ValidationRule)-1) {
         DiagPrinter(DiagPrn), LastRuleEmit((ValidationRule)-1) {
     for (unsigned i = 0; i < DXIL::kNumOutputStreams; i++) {
     for (unsigned i = 0; i < DXIL::kNumOutputStreams; i++) {
       hasOutputPosition[i] = false;
       hasOutputPosition[i] = false;
@@ -883,7 +889,7 @@ static void ValidateSampleInst(CallInst *CI, Value *srvHandle, Value *samplerHan
     break;
     break;
   default:
   default:
     ValCtx.EmitInstrError(CI, rule);
     ValCtx.EmitInstrError(CI, rule);
-    break;
+    return;
   }
   }
 
 
   // Coord match resource kind.
   // Coord match resource kind.
@@ -1718,6 +1724,41 @@ static void ValidateDxilOperationCallInProfile(CallInst *CI,
     }
     }
 
 
   } break;
   } break;
+  case DXIL::OpCode::Asin: {
+    DxilInst_Asin I(CI);
+    if (ConstantFP *imm = dyn_cast<ConstantFP>(I.get_value())) {
+      if (imm->getValueAPF().isInfinity()) {
+        ValCtx.EmitInstrError(CI, ValidationRule::InstrNoIndefiniteAsin);
+      }
+    }
+  } break;
+  case DXIL::OpCode::Acos: {
+    DxilInst_Acos I(CI);
+    if (ConstantFP *imm = dyn_cast<ConstantFP>(I.get_value())) {
+      if (imm->getValueAPF().isInfinity()) {
+        ValCtx.EmitInstrError(CI, ValidationRule::InstrNoIndefiniteAcos);
+      }
+    }
+  } break;
+  case DXIL::OpCode::Log: {
+    DxilInst_Log I(CI);
+    if (ConstantFP *imm = dyn_cast<ConstantFP>(I.get_value())) {
+      if (imm->getValueAPF().isInfinity()) {
+        ValCtx.EmitInstrError(CI, ValidationRule::InstrNoIndefiniteLog);
+      }
+    }
+  } break;
+  case DXIL::OpCode::DerivFineX:
+  case DXIL::OpCode::DerivFineY:
+  case DXIL::OpCode::DerivCoarseX:
+  case DXIL::OpCode::DerivCoarseY: {
+    Value *V = CI->getArgOperand(DXIL::OperandIndex::kUnarySrc0OpIdx);
+    if (ConstantFP *imm = dyn_cast<ConstantFP>(V)) {
+      if (imm->getValueAPF().isInfinity()) {
+        ValCtx.EmitInstrError(CI, ValidationRule::InstrNoIndefiniteDsxy);
+      }
+    }
+  } break;
   }
   }
 }
 }
 
 
@@ -2067,6 +2108,137 @@ static void ValidateControlFlowHint(BasicBlock &bb, ValidationContext &ValCtx) {
   }
   }
 }
 }
 
 
+static void ValidateTBAAMetadata(MDNode *Node, ValidationContext &ValCtx) {
+  switch (Node->getNumOperands()) {
+  case 1: {
+    if (Node->getOperand(0)->getMetadataID() != Metadata::MDStringKind) {
+      ValCtx.EmitMetaError(Node, ValidationRule::MetaWellFormed);
+    }
+  } break;
+  case 2: {
+    MDNode *rootNode = dyn_cast<MDNode>(Node->getOperand(1));
+    if (!rootNode) {
+      ValCtx.EmitMetaError(Node, ValidationRule::MetaWellFormed);
+    } else {
+      ValidateTBAAMetadata(rootNode, ValCtx);
+    }
+  } break;
+  case 3: {
+    MDNode *rootNode = dyn_cast<MDNode>(Node->getOperand(1));
+    if (!rootNode) {
+      ValCtx.EmitMetaError(Node, ValidationRule::MetaWellFormed);
+    } else {
+      ValidateTBAAMetadata(rootNode, ValCtx);
+    }
+    ConstantAsMetadata *pointsToConstMem = dyn_cast<ConstantAsMetadata>(Node->getOperand(2));
+    if (!pointsToConstMem) {
+      ValCtx.EmitMetaError(Node, ValidationRule::MetaWellFormed);
+    } else {
+      ConstantInt *isConst = dyn_cast<ConstantInt>(pointsToConstMem->getValue());
+      if (!isConst) {
+        ValCtx.EmitMetaError(Node, ValidationRule::MetaWellFormed);
+      } else if (isConst->getValue().getLimitedValue() > 1) {
+        ValCtx.EmitMetaError(Node, ValidationRule::MetaWellFormed);
+      }
+    }
+  } break;
+  default:
+    ValCtx.EmitMetaError(Node, ValidationRule::MetaWellFormed);
+  }
+}
+
+static void ValidateLoopMetadata(MDNode *Node, ValidationContext &ValCtx) {
+  if (Node->getNumOperands() == 0 || Node->getNumOperands() > 2) {
+    ValCtx.EmitMetaError(Node, ValidationRule::MetaWellFormed);
+    return;
+  }
+  if (Node != Node->getOperand(0).get()) {
+    ValCtx.EmitMetaError(Node, ValidationRule::MetaWellFormed);
+    return;
+  }
+  if (Node->getNumOperands() == 1) {
+    return;
+  }
+
+  MDNode *LoopNode = dyn_cast<MDNode>(Node->getOperand(1).get());
+  if (!LoopNode) {
+    ValCtx.EmitMetaError(Node, ValidationRule::MetaWellFormed);
+    return;
+  }
+
+  if (LoopNode->getNumOperands() < 1 || LoopNode->getNumOperands() > 2) {
+    ValCtx.EmitMetaError(LoopNode, ValidationRule::MetaWellFormed);
+    return;
+  }
+
+  if (LoopNode->getOperand(0) == LoopNode) {
+    ValidateLoopMetadata(LoopNode, ValCtx);
+    return;
+  }
+
+  MDString *LoopStr = dyn_cast<MDString>(LoopNode->getOperand(0));
+  if (!LoopStr) {
+    ValCtx.EmitMetaError(LoopNode, ValidationRule::MetaWellFormed);
+    return;
+  }
+
+  StringRef Name = LoopStr->getString();
+  if (Name != "llvm.loop.unroll.full" && Name != "llvm.loop.unroll.disable" &&
+      Name != "llvm.loop.unroll.count") {
+    ValCtx.EmitMetaError(LoopNode, ValidationRule::MetaWellFormed);
+    return;
+  }
+
+  if (Name == "llvm.loop.unroll.count") {
+    if (LoopNode->getNumOperands() != 2) {
+      ValCtx.EmitMetaError(LoopNode, ValidationRule::MetaWellFormed);
+      return;
+    }
+    ConstantAsMetadata *CountNode =
+        dyn_cast<ConstantAsMetadata>(LoopNode->getOperand(1));
+    if (!CountNode) {
+      ValCtx.EmitMetaError(LoopNode, ValidationRule::MetaWellFormed);
+    } else {
+      ConstantInt *Count = dyn_cast<ConstantInt>(CountNode->getValue());
+      if (!Count) {
+        ValCtx.EmitMetaError(CountNode, ValidationRule::MetaWellFormed);
+      }
+    }
+  }
+}
+
+static void ValidateInstructionMetadata(Instruction *I,
+                                        ValidationContext &ValCtx) {
+  SmallVector<std::pair<unsigned, MDNode *>, 2> MDNodes;
+  I->getAllMetadataOtherThanDebugLoc(MDNodes);
+  for (auto &MD : MDNodes) {
+    if (MD.first == ValCtx.kDxilControlFlowHintMDKind) {
+      if (!isa<TerminatorInst>(I)) {
+        ValCtx.EmitInstrError(
+            I, ValidationRule::MetaControlFlowHintNotOnControlFlow);
+      }
+    } else if (MD.first == ValCtx.kDxilPreciseMDKind) {
+      // Validated in IsPrecise.
+    } else if (MD.first == ValCtx.kLLVMLoopMDKind) {
+      ValidateLoopMetadata(MD.second, ValCtx);
+    } else if (MD.first == LLVMContext::MD_tbaa) {
+      ValidateTBAAMetadata(MD.second, ValCtx);
+    } else if (MD.first == LLVMContext::MD_range) {
+      // Validated in Verifier.cpp.
+    } else {
+      ValCtx.EmitMetaError(MD.second, ValidationRule::MetaUsed);
+    }
+  }
+}
+
+static void ValidateFunctionMetadata(Function *F, ValidationContext &ValCtx) {
+  SmallVector<std::pair<unsigned, MDNode *>, 2> MDNodes;
+  F->getAllMetadata(MDNodes);
+  for (auto &MD : MDNodes) {
+    ValCtx.EmitMetaError(MD.second, ValidationRule::MetaUsed);
+  }
+}
+
 static void ValidateFunctionBody(Function *F, ValidationContext &ValCtx) {
 static void ValidateFunctionBody(Function *F, ValidationContext &ValCtx) {
   bool SupportsMinPrecision =
   bool SupportsMinPrecision =
       ValCtx.DxilMod.GetGlobalFlags() & DXIL::kEnableMinPrecision;
       ValCtx.DxilMod.GetGlobalFlags() & DXIL::kEnableMinPrecision;
@@ -2076,6 +2248,10 @@ static void ValidateFunctionBody(Function *F, ValidationContext &ValCtx) {
     for (auto i = b->begin(), iend = b->end(); i != iend; ++i) {
     for (auto i = b->begin(), iend = b->end(); i != iend; ++i) {
       llvm::Instruction &I = *i;
       llvm::Instruction &I = *i;
 
 
+      if (I.hasMetadata()) {
+        ValidateInstructionMetadata(&I, ValCtx);
+      }
+
       // Instructions must be allowed.
       // Instructions must be allowed.
       if (!IsLLVMInstructionAllowed(I)) {
       if (!IsLLVMInstructionAllowed(I)) {
         ValCtx.EmitInstrError(&I, ValidationRule::InstrAllowed);
         ValCtx.EmitInstrError(&I, ValidationRule::InstrAllowed);
@@ -2087,7 +2263,8 @@ static void ValidateFunctionBody(Function *F, ValidationContext &ValCtx) {
         if (IsPrecise(I, ValCtx)) {
         if (IsPrecise(I, ValCtx)) {
           for (auto &O : I.operands()) {
           for (auto &O : I.operands()) {
             if (IsValueMinPrec(ValCtx.DxilMod, O)) {
             if (IsValueMinPrec(ValCtx.DxilMod, O)) {
-              ValCtx.EmitInstrError(&I, ValidationRule::InstrMinPrecisionNotPrecise);
+              ValCtx.EmitInstrError(
+                  &I, ValidationRule::InstrMinPrecisionNotPrecise);
               break;
               break;
             }
             }
           }
           }
@@ -2107,7 +2284,8 @@ static void ValidateFunctionBody(Function *F, ValidationContext &ValCtx) {
           Value *opcodeVal = CI->getOperand(0);
           Value *opcodeVal = CI->getOperand(0);
           ConstantInt *OpcodeConst = dyn_cast<ConstantInt>(opcodeVal);
           ConstantInt *OpcodeConst = dyn_cast<ConstantInt>(opcodeVal);
           if (OpcodeConst == nullptr) {
           if (OpcodeConst == nullptr) {
-            ValCtx.EmitInstrFormatError(&I, ValidationRule::InstrOpConst, {"Opcode", "DXIL operation"});
+            ValCtx.EmitInstrFormatError(&I, ValidationRule::InstrOpConst,
+                                        {"Opcode", "DXIL operation"});
             continue;
             continue;
           }
           }
 
 
@@ -2135,8 +2313,8 @@ static void ValidateFunctionBody(Function *F, ValidationContext &ValCtx) {
       if (!isa<PHINode>(&I)) {
       if (!isa<PHINode>(&I)) {
         for (Value *op : I.operands()) {
         for (Value *op : I.operands()) {
           if (isa<UndefValue>(op)) {
           if (isa<UndefValue>(op)) {
-            ValCtx.EmitInstrError(
-                &I, ValidationRule::InstrNoReadingUninitialized);
+            ValCtx.EmitInstrError(&I,
+                                  ValidationRule::InstrNoReadingUninitialized);
           } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(op)) {
           } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(op)) {
             for (Value *opCE : CE->operands()) {
             for (Value *opCE : CE->operands()) {
               if (isa<UndefValue>(opCE)) {
               if (isa<UndefValue>(opCE)) {
@@ -2183,6 +2361,24 @@ static void ValidateFunctionBody(Function *F, ValidationContext &ValCtx) {
           continue;
           continue;
         }
         }
       } break;
       } break;
+      case Instruction::SDiv: {
+        BinaryOperator *BO = cast<BinaryOperator>(&I);
+        Value *V = BO->getOperand(1);
+        if (ConstantInt *imm = dyn_cast<ConstantInt>(V)) {
+          if (imm->getValue().getLimitedValue() == 0) {
+            ValCtx.EmitInstrError(BO, ValidationRule::InstrNoIDivByZero);
+          }
+        }
+      } break;
+      case Instruction::UDiv: {
+        BinaryOperator *BO = cast<BinaryOperator>(&I);
+        Value *V = BO->getOperand(1);
+        if (ConstantInt *imm = dyn_cast<ConstantInt>(V)) {
+          if (imm->getValue().getLimitedValue() == 0) {
+            ValCtx.EmitInstrError(BO, ValidationRule::InstrNoUDivByZero);
+          }
+        }
+      } break;
       }
       }
 
 
       if (PointerType *PT = dyn_cast<PointerType>(I.getType())) {
       if (PointerType *PT = dyn_cast<PointerType>(I.getType())) {
@@ -2214,165 +2410,196 @@ static void ValidateFunctionBody(Function *F, ValidationContext &ValCtx) {
   }
   }
 }
 }
 
 
-static void ValidateFunction(Function &F, ValidationContext &ValCtx) {
-  if (F.isDeclaration()) {
-    ValidateExternalFunction(&F, ValCtx);
-  } else {
-    DxilFunctionAnnotation *funcAnnotation = ValCtx.DxilMod.GetTypeSystem().GetFunctionAnnotation(&F);
-    if (!funcAnnotation) {
-      ValCtx.EmitFormatError(ValidationRule::MetaFunctionAnnotation, {F.getName().str().c_str()});
-      return;
+static void ValidateFunction(Function & F, ValidationContext & ValCtx) {
+    if (F.isDeclaration()) {
+        ValidateExternalFunction(&F, ValCtx);
     }
     }
+    else {
+        DxilFunctionAnnotation *funcAnnotation =
+            ValCtx.DxilMod.GetTypeSystem().GetFunctionAnnotation(&F);
+        if (!funcAnnotation) {
+            ValCtx.EmitFormatError(ValidationRule::MetaFunctionAnnotation,
+            { F.getName().str().c_str() });
+            return;
+        }
 
 
-    // Validate parameter type.
-    for (auto &arg : F.args()) {
-      Type *argTy = arg.getType();
-      if (argTy->isPointerTy())
-        argTy = argTy->getPointerElementType();
-      while (argTy->isArrayTy()) {
-        argTy = argTy->getArrayElementType();
-      }
+        // Validate parameter type.
+        for (auto &arg : F.args()) {
+            Type *argTy = arg.getType();
+            if (argTy->isPointerTy())
+                argTy = argTy->getPointerElementType();
+            while (argTy->isArrayTy()) {
+                argTy = argTy->getArrayElementType();
+            }
 
 
-      DxilParameterAnnotation &paramAnnoation = funcAnnotation->GetParameterAnnotation(arg.getArgNo());
+            DxilParameterAnnotation &paramAnnoation =
+                funcAnnotation->GetParameterAnnotation(arg.getArgNo());
+
+            if (argTy->isStructTy() && !HLModule::IsStreamOutputType(argTy) &&
+                !paramAnnoation.HasMatrixAnnotation()) {
+                if (arg.hasName())
+                    ValCtx.EmitFormatError(
+                        ValidationRule::DeclFnFlattenParam,
+                        { arg.getName().str().c_str(), F.getName().str().c_str() });
+                else
+                    ValCtx.EmitFormatError(ValidationRule::DeclFnFlattenParam,
+                    { std::to_string(arg.getArgNo()).c_str(),
+                     F.getName().str().c_str() });
+                break;
+            }
+        }
 
 
-      if (argTy->isStructTy()  && !HLModule::IsStreamOutputType(argTy) &&
-          !paramAnnoation.HasMatrixAnnotation()) {
-        if (arg.hasName())
-          ValCtx.EmitFormatError(
-              ValidationRule::DeclFnFlattenParam,
-              {arg.getName().str().c_str(), F.getName().str().c_str()});
-        else
-          ValCtx.EmitFormatError(ValidationRule::DeclFnFlattenParam,
-                                 {std::to_string(arg.getArgNo()).c_str(),
-                                  F.getName().str().c_str()});
-        break;
-      }
+        ValidateFunctionBody(&F, ValCtx);
     }
     }
 
 
-    ValidateFunctionBody(&F, ValCtx);
-  }
+    if (F.hasMetadata()) {
+        ValidateFunctionMetadata(&F, ValCtx);
+    }
 }
 }
 
 
-static void ValidateGlobalVariable(GlobalVariable &GV,
-                                   ValidationContext &ValCtx) {
-  bool isInternalGV =
-      HLModule::IsStaticGlobal(&GV) || HLModule::IsSharedMemoryGlobal(&GV);
-
-  if (!isInternalGV) {
-    if (!GV.user_empty()) {
-      bool hasInstructionUser = false;
-      for (User *U : GV.users()) {
-        if (isa<Instruction>(U)) {
-          hasInstructionUser = true;
-          break;
+static void ValidateGlobalVariable(GlobalVariable & GV,
+    ValidationContext & ValCtx) {
+    bool isInternalGV =
+        HLModule::IsStaticGlobal(&GV) || HLModule::IsSharedMemoryGlobal(&GV);
+
+    if (!isInternalGV) {
+        if (!GV.user_empty()) {
+            bool hasInstructionUser = false;
+            for (User *U : GV.users()) {
+                if (isa<Instruction>(U)) {
+                    hasInstructionUser = true;
+                    break;
+                }
+            }
+            // External GV should not have instruction user.
+            if (hasInstructionUser) {
+                ValCtx.EmitGlobalValueError(&GV, ValidationRule::DeclNotUsedExternal);
+            }
         }
         }
-      }
-      // External GV should not have instruction user.
-      if (hasInstructionUser) {
-        ValCtx.EmitGlobalValueError(&GV, ValidationRule::DeclNotUsedExternal);
-      }
-    }
-    // Must have metadata description for each variable.
+        // Must have metadata description for each variable.
 
 
-  } else {
-    // Internal GV must have user.
-    if (GV.user_empty()) {
-      ValCtx.EmitGlobalValueError(&GV, ValidationRule::DeclUsedInternal);
     }
     }
+    else {
+        // Internal GV must have user.
+        if (GV.user_empty()) {
+            ValCtx.EmitGlobalValueError(&GV, ValidationRule::DeclUsedInternal);
+        }
 
 
-    // Validate type for internal globals.
-    if (HLModule::IsStaticGlobal(&GV) || HLModule::IsSharedMemoryGlobal(&GV)) {
-      Type *Ty = GV.getType()->getPointerElementType();
-      ValidateType(Ty, ValCtx);
+        // Validate type for internal globals.
+        if (HLModule::IsStaticGlobal(&GV) ||
+            HLModule::IsSharedMemoryGlobal(&GV)) {
+            Type *Ty = GV.getType()->getPointerElementType();
+            ValidateType(Ty, ValCtx);
+        }
     }
     }
-  }
 }
 }
 
 
-static void ValidateGlobalVariables(ValidationContext &ValCtx) {
-  DxilModule &M = ValCtx.DxilMod;
+static void ValidateGlobalVariables(ValidationContext & ValCtx) {
+    DxilModule &M = ValCtx.DxilMod;
 
 
-  unsigned TGSMSize = 0;
-  const DataLayout &DL = M.GetModule()->getDataLayout();
-  for (GlobalVariable &GV : M.GetModule()->globals()) {
-    ValidateGlobalVariable(GV, ValCtx);
-    if (GV.getType()->getAddressSpace() == DXIL::kTGSMAddrSpace) {
-      TGSMSize += DL.getTypeAllocSize(GV.getType()->getElementType());
+    unsigned TGSMSize = 0;
+    const DataLayout &DL = M.GetModule()->getDataLayout();
+    for (GlobalVariable &GV : M.GetModule()->globals()) {
+        ValidateGlobalVariable(GV, ValCtx);
+        if (GV.getType()->getAddressSpace() == DXIL::kTGSMAddrSpace) {
+            TGSMSize += DL.getTypeAllocSize(GV.getType()->getElementType());
+        }
     }
     }
-  }
 
 
-  if (TGSMSize > DXIL::kMaxTGSMSize) {
-    ValCtx.EmitFormatError(ValidationRule::SmMaxTGSMSize,
-                          {std::to_string(TGSMSize).c_str(),
-                           std::to_string(DXIL::kMaxTGSMSize).c_str()});
-  }
+    if (TGSMSize > DXIL::kMaxTGSMSize) {
+        ValCtx.EmitFormatError(ValidationRule::SmMaxTGSMSize,
+        { std::to_string(TGSMSize).c_str(),
+         std::to_string(DXIL::kMaxTGSMSize).c_str() });
+    }
 }
 }
 
 
-static void ValidateValidatorVersion(ValidationContext &ValCtx) {
-  Module *pModule = &ValCtx.M;
-  NamedMDNode *pNode = pModule->getNamedMetadata("dx.valver");
-  if (pNode == nullptr) {
-    return;
-  }
-  if (pNode->getNumOperands() == 1) {
-    MDTuple *pVerValues = dyn_cast<MDTuple>(pNode->getOperand(0));
-    if (pVerValues != nullptr && pVerValues->getNumOperands() == 2) {
-      uint64_t majorVer, minorVer;
-      if (GetNodeOperandAsInt(ValCtx, pVerValues, 0, &majorVer) &&
-          GetNodeOperandAsInt(ValCtx, pVerValues, 1, &minorVer)) {
-        unsigned curMajor, curMinor;
-        GetValidationVersion(&curMajor, &curMinor);
-        // This will need to be updated as major/minor versions evolve,
-        // depending on the degree of compat across versions.
-        if (majorVer == curMajor && minorVer <= curMinor) {
-          return;
+static void ValidateValidatorVersion(ValidationContext & ValCtx) {
+    Module *pModule = &ValCtx.M;
+    NamedMDNode *pNode = pModule->getNamedMetadata("dx.valver");
+    if (pNode == nullptr) {
+        return;
+    }
+    if (pNode->getNumOperands() == 1) {
+        MDTuple *pVerValues = dyn_cast<MDTuple>(pNode->getOperand(0));
+        if (pVerValues != nullptr && pVerValues->getNumOperands() == 2) {
+            uint64_t majorVer, minorVer;
+            if (GetNodeOperandAsInt(ValCtx, pVerValues, 0, &majorVer) &&
+                GetNodeOperandAsInt(ValCtx, pVerValues, 1, &minorVer)) {
+                unsigned curMajor, curMinor;
+                GetValidationVersion(&curMajor, &curMinor);
+                // This will need to be updated as major/minor versions evolve,
+                // depending on the degree of compat across versions.
+                if (majorVer == curMajor && minorVer <= curMinor) {
+                    return;
+                }
+            }
         }
         }
-      }
     }
     }
-  }
-  ValCtx.EmitError(ValidationRule::MetaWellFormed);
+    ValCtx.EmitError(ValidationRule::MetaWellFormed);
 }
 }
 
 
-static void ValidateMetadata(ValidationContext &ValCtx) {
-  Module *pModule = &ValCtx.M;
-  const std::string &target = pModule->getTargetTriple();
-  if (target != "dxil-ms-dx") {
-    ValCtx.EmitFormatError(ValidationRule::MetaTarget, { target.c_str() });
-  }
-
-  for (auto &NamedMetaNode : pModule->named_metadata()) {
-    if (!DxilModule::IsKnownNamedMetaData(NamedMetaNode)) {
-      StringRef name = NamedMetaNode.getName();
-      if (!name.startswith_lower("llvm."))
-        ValCtx.EmitFormatError(ValidationRule::MetaKnown, { name.str().c_str() });
+static void ValidateMetadata(ValidationContext & ValCtx) {
+    Module *pModule = &ValCtx.M;
+    const std::string &target = pModule->getTargetTriple();
+    if (target != "dxil-ms-dx") {
+        ValCtx.EmitFormatError(ValidationRule::MetaTarget, { target.c_str() });
+    }
+
+    StringMap<bool> llvmNamedMeta;
+    // These llvm named metadata is verified in lib/IR/Verifier.cpp.
+    llvmNamedMeta["llvm.dbg.cu"];
+    llvmNamedMeta["llvm.dbg.contents"];
+    llvmNamedMeta["llvm.dbg.defines"];
+    llvmNamedMeta["llvm.dbg.mainFileName"];
+    llvmNamedMeta["llvm.dbg.args"];
+    llvmNamedMeta["llvm.ident"];
+    // Not for HLSL which does not have vtable.
+    // llvmNamedMeta["llvm.bitsets"];
+    llvmNamedMeta["llvm.module.flags"];
+
+    for (auto &NamedMetaNode : pModule->named_metadata()) {
+        if (!DxilModule::IsKnownNamedMetaData(NamedMetaNode)) {
+            StringRef name = NamedMetaNode.getName();
+            if (!name.startswith_lower("llvm."))
+                ValCtx.EmitFormatError(ValidationRule::MetaKnown,
+                { name.str().c_str() });
+            else {
+                if (llvmNamedMeta.count(name) == 0) {
+                    ValCtx.EmitFormatError(ValidationRule::MetaKnown,
+                    { name.str().c_str() });
+                }
+            }
+        }
     }
     }
-  }
 
 
-  if (!ValCtx.DxilMod.GetShaderModel()->IsValid()) {
-    ValCtx.EmitFormatError(ValidationRule::SmName, { ValCtx.DxilMod.GetShaderModel()->GetName() });
-  }
+    if (!ValCtx.DxilMod.GetShaderModel()->IsValid()) {
+        ValCtx.EmitFormatError(ValidationRule::SmName,
+        { ValCtx.DxilMod.GetShaderModel()->GetName() });
+    }
 
 
-  ValidateValidatorVersion(ValCtx);
+    ValidateValidatorVersion(ValCtx);
 }
 }
 
 
-static void ValidateResourceOverlap(hlsl::DxilResourceBase &res,
-    SpacesAllocator<unsigned, DxilResourceBase> &spaceAllocator,
-    ValidationContext &ValCtx) {
-  unsigned base = res.GetLowerBound();
-  unsigned size = res.GetRangeSize();
-  unsigned space = res.GetSpaceID();
-
-  auto &allocator = spaceAllocator.Get(space);
-  unsigned end = base + size - 1;
-  // unbounded
-  if (end < base)
-    end = size;
-  const DxilResourceBase *conflictRes = allocator.Insert(&res, base, end);
-  if (conflictRes) {
-      ValCtx.EmitFormatError(ValidationRule::SmResourceRangeOverlap,
-          {res.GetGlobalName().c_str(), std::to_string(base).c_str(),
-           std::to_string(size).c_str(), std::to_string(conflictRes->GetLowerBound()).c_str(),
-           std::to_string(conflictRes->GetRangeSize()).c_str(), std::to_string(space).c_str()});
-  }
+static void ValidateResourceOverlap(
+    hlsl::DxilResourceBase & res,
+    SpacesAllocator<unsigned, DxilResourceBase> & spaceAllocator,
+    ValidationContext & ValCtx) {
+    unsigned base = res.GetLowerBound();
+    unsigned size = res.GetRangeSize();
+    unsigned space = res.GetSpaceID();
+
+    auto &allocator = spaceAllocator.Get(space);
+    unsigned end = base + size - 1;
+    // unbounded
+    if (end < base)
+        end = size;
+    const DxilResourceBase *conflictRes = allocator.Insert(&res, base, end);
+    if (conflictRes) {
+        ValCtx.EmitFormatError(ValidationRule::SmResourceRangeOverlap,
+        { res.GetGlobalName().c_str(), std::to_string(base).c_str(),
+         std::to_string(size).c_str(), std::to_string(conflictRes->GetLowerBound()).c_str(),
+         std::to_string(conflictRes->GetRangeSize()).c_str(), std::to_string(space).c_str() });
+    }
 }
 }
 
 
 static void ValidateResource(hlsl::DxilResource &res,
 static void ValidateResource(hlsl::DxilResource &res,
@@ -3514,7 +3741,6 @@ ValidateDxilModule(llvm::Module *pModule, llvm::Module *pDebugModule) {
     ValidateFunction(F, ValCtx);
     ValidateFunction(F, ValCtx);
   }
   }
 
 
-
   ValidateUninitializedOutput(ValCtx);
   ValidateUninitializedOutput(ValCtx);
 
 
   ValidateShaderFlags(ValCtx);
   ValidateShaderFlags(ValCtx);

+ 2 - 0
tools/clang/lib/CodeGen/CGHLSLMS.cpp

@@ -4284,6 +4284,8 @@ Value *CGMSHLSLRuntime::EmitHLSLLiteralCast(CodeGenFunction &CGF, Value *Src,
         return Builder.CreateFPTrunc(Src, DstTy);
         return Builder.CreateFPTrunc(Src, DstTy);
       }
       }
     }
     }
+  } else if (UndefValue *UV = dyn_cast<UndefValue>(Src)) {
+    return UndefValue::get(DstTy);
   } else {
   } else {
     Instruction *I = cast<Instruction>(Src);
     Instruction *I = cast<Instruction>(Src);
     if (SelectInst *SI = dyn_cast<SelectInst>(I)) {
     if (SelectInst *SI = dyn_cast<SelectInst>(I)) {

+ 18 - 0
tools/clang/test/CodeGenHLSL/intrinsic_val_imm.hlsl

@@ -0,0 +1,18 @@
+// RUN: %dxc -E main -T ps_5_0 %s | FileCheck %s
+
+// CHECK: Shader extensions for 11.1
+
+
+// CHECK: Asin
+// CHECK: Acos
+
+float v;
+uint2 s;
+int2  i;
+
+float4 main(float4 arg : A) : SV_TARGET {
+  float t = asin(v) + acos(v) + s.x/s.y + i.x/i.y + log(v);
+  t +=  ddx(v) + ddy(s.x);
+  t +=  ddx_fine(v) + ddy_fine(s.x);
+  return t;
+}

+ 62 - 0
tools/clang/unittests/HLSL/ValidationTest.cpp

@@ -81,6 +81,13 @@ public:
   TEST_METHOD(PsInputSemantic)
   TEST_METHOD(PsInputSemantic)
   TEST_METHOD(PsOutputSemantic)
   TEST_METHOD(PsOutputSemantic)
   TEST_METHOD(ArrayOfSVTarget)
   TEST_METHOD(ArrayOfSVTarget)
+  TEST_METHOD(InfiniteLog)
+  TEST_METHOD(InfiniteAsin)
+  TEST_METHOD(InfiniteAcos)
+  TEST_METHOD(InfiniteDdxDdy)
+  TEST_METHOD(IDivByZero)
+  TEST_METHOD(UDivByZero)
+  TEST_METHOD(UnusedMetadata)
 
 
   TEST_METHOD(WhenInstrDisallowedThenFail);
   TEST_METHOD(WhenInstrDisallowedThenFail);
   TEST_METHOD(WhenDepthNotFloatThenFail);
   TEST_METHOD(WhenDepthNotFloatThenFail);
@@ -782,6 +789,61 @@ TEST_F(ValidationTest, ArrayOfSVTarget) {
       "Pixel shader output registers are not indexable.");
       "Pixel shader output registers are not indexable.");
 }
 }
 
 
+TEST_F(ValidationTest, InfiniteLog) {
+    RewriteAssemblyCheckMsg(
+      L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_5_0",
+      "op.unary.f32(i32 22, float %3)",
+      "op.unary.f32(i32 22, float 0x7FF0000000000000)",
+      "No indefinite logarithm");
+}
+
+TEST_F(ValidationTest, InfiniteAsin) {
+    RewriteAssemblyCheckMsg(
+      L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_5_0",
+      "op.unary.f32(i32 16, float %3)",
+      "op.unary.f32(i32 16, float 0x7FF0000000000000)",
+      "No indefinite arcsine");
+}
+
+TEST_F(ValidationTest, InfiniteAcos) {
+    RewriteAssemblyCheckMsg(
+      L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_5_0",
+      "op.unary.f32(i32 15, float %3)",
+      "op.unary.f32(i32 15, float 0x7FF0000000000000)",
+      "No indefinite arccosine");
+}
+
+TEST_F(ValidationTest, InfiniteDdxDdy) {
+    RewriteAssemblyCheckMsg(
+      L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_5_0",
+      "op.unary.f32(i32 86, float %3)",
+      "op.unary.f32(i32 86, float 0x7FF0000000000000)",
+      "No indefinite derivative calculation");
+}
+
+TEST_F(ValidationTest, IDivByZero) {
+    RewriteAssemblyCheckMsg(
+      L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_5_0",
+      "sdiv i32 %8, %9",
+      "sdiv i32 %8, 0",
+      "No signed integer division by zero");
+}
+
+TEST_F(ValidationTest, UDivByZero) {
+    RewriteAssemblyCheckMsg(
+      L"..\\CodeGenHLSL\\intrinsic_val_imm.hlsl", "ps_5_0",
+      "udiv i32 %5, %6",
+      "udiv i32 %5, 0",
+      "No unsigned integer division by zero");
+}
+
+TEST_F(ValidationTest, UnusedMetadata) {
+  RewriteAssemblyCheckMsg(L"..\\CodeGenHLSL\\loop2.hlsl", "ps_5_0",
+                          ", !llvm.loop ",
+                          ", !llvm.loop2 ",
+                          "All metadata must be used by dxil");
+}
+
 TEST_F(ValidationTest, WhenWaveAffectsGradientThenFail) {
 TEST_F(ValidationTest, WhenWaveAffectsGradientThenFail) {
   TestCheck(L"val-wave-failures-ps.hlsl");
   TestCheck(L"val-wave-failures-ps.hlsl");
 }
 }

+ 9 - 12
utils/hct/hctdb.py

@@ -1374,7 +1374,7 @@ class db_dxil(object):
 
 
         self.add_valrule("Meta.Required", "TODO - Required metadata missing")
         self.add_valrule("Meta.Required", "TODO - Required metadata missing")
         self.add_valrule_msg("Meta.Known", "Named metadata should be known", "Named metadata '%0' is unknown")
         self.add_valrule_msg("Meta.Known", "Named metadata should be known", "Named metadata '%0' is unknown")
-        self.add_valrule("Meta.Used", "TODO - All metadata must be used")
+        self.add_valrule("Meta.Used", "All metadata must be used by dxil")
         self.add_valrule_msg("Meta.Target", "Target triple must be 'dxil-ms-dx'", "Unknown target triple '%0'")
         self.add_valrule_msg("Meta.Target", "Target triple must be 'dxil-ms-dx'", "Unknown target triple '%0'")
         self.add_valrule("Meta.WellFormed", "TODO - Metadata must be well-formed in operand count and types")
         self.add_valrule("Meta.WellFormed", "TODO - Metadata must be well-formed in operand count and types")
         self.add_valrule("Meta.SemanticLen", "Semantic length must be at least 1 and at most 64")
         self.add_valrule("Meta.SemanticLen", "Semantic length must be at least 1 and at most 64")
@@ -1402,6 +1402,7 @@ class db_dxil(object):
         self.add_valrule("Meta.InvalidControlFlowHint", "Invalid control flow hint")
         self.add_valrule("Meta.InvalidControlFlowHint", "Invalid control flow hint")
         self.add_valrule("Meta.BranchFlatten", "Can't use branch and flatten attributes together")
         self.add_valrule("Meta.BranchFlatten", "Can't use branch and flatten attributes together")
         self.add_valrule("Meta.ForceCaseOnSwitch", "Attribute forcecase only works for switch")
         self.add_valrule("Meta.ForceCaseOnSwitch", "Attribute forcecase only works for switch")
+        self.add_valrule("Meta.ControlFlowHintNotOnControlFlow", "Control flow hint only works on control flow inst")
         self.add_valrule("Meta.TextureType", "elements of typed buffers and textures must fit in four 32-bit quantities")
         self.add_valrule("Meta.TextureType", "elements of typed buffers and textures must fit in four 32-bit quantities")
 
 
         self.add_valrule("Instr.Oload", "DXIL intrinsic overload must be valid")
         self.add_valrule("Instr.Oload", "DXIL intrinsic overload must be valid")
@@ -1425,12 +1426,12 @@ class db_dxil(object):
 
 
         # Need to clean up all error messages and actually implement.
         # Need to clean up all error messages and actually implement.
         # Midlevel
         # Midlevel
-        self.add_valrule("Instr.NoIndefiniteLog", "TODO - No indefinite logarithm")
-        self.add_valrule("Instr.NoIndefiniteAsin", "TODO - No indefinite arcsine")
-        self.add_valrule("Instr.NoIndefiniteAcos", "TODO - No indefinite arccosine")
-        self.add_valrule("Instr.NoIDivByZero", "TODO - No signed integer division by zero")
-        self.add_valrule("Instr.NoUDivByZero", "TODO - No unsigned integer division by zero")
-        self.add_valrule("Instr.NoIndefiniteDsxy", "TODO - No indefinite derivative calculation")
+        self.add_valrule("Instr.NoIndefiniteLog", "No indefinite logarithm")
+        self.add_valrule("Instr.NoIndefiniteAsin", "No indefinite arcsine")
+        self.add_valrule("Instr.NoIndefiniteAcos", "No indefinite arccosine")
+        self.add_valrule("Instr.NoIDivByZero", "No signed integer division by zero")
+        self.add_valrule("Instr.NoUDivByZero", "No unsigned integer division by zero")
+        self.add_valrule("Instr.NoIndefiniteDsxy", "No indefinite derivative calculation")
         self.add_valrule("Instr.ERR_ALIAS_ARRAY_INDEX_OUT_OF_BOUNDS", "TODO - ERR_ALIAS_ARRAY_INDEX_OUT_OF_BOUNDS")
         self.add_valrule("Instr.ERR_ALIAS_ARRAY_INDEX_OUT_OF_BOUNDS", "TODO - ERR_ALIAS_ARRAY_INDEX_OUT_OF_BOUNDS")
         self.add_valrule("Instr.MinPrecisionNotPrecise", "Instructions marked precise may not refer to minprecision values")
         self.add_valrule("Instr.MinPrecisionNotPrecise", "Instructions marked precise may not refer to minprecision values")
 
 
@@ -1441,7 +1442,7 @@ class db_dxil(object):
         self.add_valrule("Instr.TextureOffset", "offset texture instructions must take offset which can resolve to integer literal in the range -8 to 7")
         self.add_valrule("Instr.TextureOffset", "offset texture instructions must take offset which can resolve to integer literal in the range -8 to 7")
         # D3D12
         # D3D12
         self.add_valrule("Instr.WAR_GRADIENT_IN_VARYING_FLOW", "TODO - gradient instruction used in a loop with varying iteration; partial derivatives may have undefined value")
         self.add_valrule("Instr.WAR_GRADIENT_IN_VARYING_FLOW", "TODO - gradient instruction used in a loop with varying iteration; partial derivatives may have undefined value")
-        self.add_valrule("Instr.DeterminateDerivative", "gradient operation uses a value that may not be defined for all pixels (in UAV loads can not participate in gradient operations)")
+        self.add_valrule("Instr.DeterminateDerivative", "TODO - gradient operation uses a value that may not be defined for all pixels (in UAV loads can not participate in gradient operations)")
         self.add_valrule("Instr.ERR_NON_LITERAL_RESOURCE", "TODO - Resources being indexed cannot come from conditional expressions, they must come from literal expressions.")
         self.add_valrule("Instr.ERR_NON_LITERAL_RESOURCE", "TODO - Resources being indexed cannot come from conditional expressions, they must come from literal expressions.")
         self.add_valrule("Instr.ERR_NON_LITERAL_STREAM", "TODO - stream parameter must come from a literal expression")
         self.add_valrule("Instr.ERR_NON_LITERAL_STREAM", "TODO - stream parameter must come from a literal expression")
         self.add_valrule_msg("Instr.CannotPullPosition", "pull-model evaluation of position disallowed", "%0 does not support pull-model evaluation of position")
         self.add_valrule_msg("Instr.CannotPullPosition", "pull-model evaluation of position disallowed", "%0 does not support pull-model evaluation of position")
@@ -1546,10 +1547,6 @@ class db_dxil(object):
         self.add_valrule("Sm.UndefinedOutput", "Not all elements of output %0 were written")
         self.add_valrule("Sm.UndefinedOutput", "Not all elements of output %0 were written")
         self.add_valrule("Sm.CSNoReturn", "Compute shaders can't return values, outputs must be written in writable resources (UAVs).")
         self.add_valrule("Sm.CSNoReturn", "Compute shaders can't return values, outputs must be written in writable resources (UAVs).")
         self.add_valrule("Sm.CBufferTemplateTypeMustBeStruct", "D3D12 constant/texture buffer template element can only be a struct")
         self.add_valrule("Sm.CBufferTemplateTypeMustBeStruct", "D3D12 constant/texture buffer template element can only be a struct")
-        self.add_valrule("Sm.ERR_MAX_CONST_EXCEEDED", "TODO - ERR_MAX_CONST_EXCEEDED")
-        self.add_valrule("Sm.ERR_MAX_SAMPLER_EXCEEDED", "TODO - The maximum number of sampler slots is exceeded for a library (slot index=%u, max slots=%u)")
-        self.add_valrule("Sm.ERR_MAX_TEXTURE_EXCEEDED", "TODO - The maximum number of texture slots is exceeded for a library (slot index=%u, max slots=%u)")
-        self.add_valrule("Sm.ERR_MAX_CBUFFER_EXCEEDED", "TODO - The maximum number of constant buffer slots is exceeded for a library (slot index=%u, max slots=%u)")
         self.add_valrule("Sm.ERR_UNABLE_TO_BIND_RESOURCE", "TODO - ERR_UNABLE_TO_BIND_RESOURCE")
         self.add_valrule("Sm.ERR_UNABLE_TO_BIND_RESOURCE", "TODO - ERR_UNABLE_TO_BIND_RESOURCE")
         self.add_valrule("Sm.ERR_UNABLE_TO_BIND_UNBOUNDED_RESOURCE", "TODO - ERR_UNABLE_TO_BIND_UNBOUNDED_RESOURCE")
         self.add_valrule("Sm.ERR_UNABLE_TO_BIND_UNBOUNDED_RESOURCE", "TODO - ERR_UNABLE_TO_BIND_UNBOUNDED_RESOURCE")
         self.add_valrule("Sm.ERR_BIND_RESOURCE_RANGE_OVERFLOW", "TODO - ERR_BIND_RESOURCE_RANGE_OVERFLOW")
         self.add_valrule("Sm.ERR_BIND_RESOURCE_RANGE_OVERFLOW", "TODO - ERR_BIND_RESOURCE_RANGE_OVERFLOW")