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

Default to stripping reflection from DXIL and fix a bunch of fallout.

Two test options, -Qstrip_reflect_from_dxil and -Qkeep_reflect_in_dxil
for making tests work with reflection removed, since many tests are relying
on main module disassembly-reassembly between test phases and reflection
metadata will no longer be present there.  The strip option is for the
few cases where tests don't want the reflection kept in DXIL by default.

Validator no longer requires function annotations for no reason.

Fix places where remove global hook was not being called when functions
were removed manually from the list.

StripReflection now deletes function annotations, unless targeting lib or
old validator that required them.  Preserve global constructor list and
add annotation for 1.4 validator.  The global hook fixes were required
here, otherwise annotations would refer to dead functions during linking.
Struct annotations may not be removed in library case when they still need
translation to legacy types.

Allow missing struct annotation when not necessary to upgrade the layout.

Preserve usage in reflection by upgrading the module, emitting metadata,
cloning for reflection, then restoring validator version and re-emit
metadata.

Fix size for 16-bit type for usage and reflected size.

Make various batch reflection tests require validator 1.5, since these
tests rely on module disassembly->assembly, which will not preserve extra
usage metadata for reflection in 1.4.

Include reflection part in IDxcAssembler, but don't strip from module,
since there are no options to prevent this from breaking a lot of tests.

Don't strip reflection from offline lib target.
Tex Riddell 6 жил өмнө
parent
commit
892765cc4b
33 өөрчлөгдсөн 332 нэмэгдсэн , 68 устгасан
  1. 0 1
      docs/DXIL.rst
  2. 0 1
      include/dxc/HLSL/DxilValidation.h
  3. 1 0
      include/dxc/Support/HLSLOptions.h
  4. 8 2
      include/dxc/Support/HLSLOptions.td
  5. 1 1
      lib/Analysis/IPA/CallGraph.cpp
  6. 53 8
      lib/DXIL/DxilModule.cpp
  7. 6 0
      lib/DxcSupport/HLSLOptions.cpp
  8. 15 2
      lib/DxilContainer/DxilContainerAssembler.cpp
  9. 12 2
      lib/HLSL/DxilCondenseResources.cpp
  10. 20 4
      lib/HLSL/DxilContainerReflection.cpp
  11. 24 3
      lib/HLSL/DxilPreparePasses.cpp
  12. 0 8
      lib/HLSL/DxilValidation.cpp
  13. 2 8
      lib/Transforms/IPO/GlobalDCE.cpp
  14. 3 4
      tools/clang/test/CodeGenHLSL/batch/compiler_options/Qstrip_reflect.hlsl
  15. 3 4
      tools/clang/test/CodeGenHLSL/batch/compiler_options/Qstrip_reflect_struct_buf.hlsl
  16. 2 2
      tools/clang/test/CodeGenHLSL/batch/debug/misc/share_mem_dbg.hlsl
  17. 1 1
      tools/clang/test/CodeGenHLSL/batch/misc/d3dreflect/cb_sizes.hlsl
  18. 1 1
      tools/clang/test/CodeGenHLSL/batch/misc/d3dreflect/cbuf-usage-lib.hlsl
  19. 1 1
      tools/clang/test/CodeGenHLSL/batch/misc/d3dreflect/empty_struct2.hlsl
  20. 125 0
      tools/clang/test/CodeGenHLSL/batch/misc/d3dreflect/lib_global.hlsl
  21. 1 1
      tools/clang/test/CodeGenHLSL/batch/misc/d3dreflect/reflect-lib-1.hlsl
  22. 1 1
      tools/clang/test/CodeGenHLSL/batch/misc/d3dreflect/structured_buffer_layout.hlsl
  23. 1 1
      tools/clang/test/CodeGenHLSL/batch/misc/static_const_global.hlsl
  24. 4 1
      tools/clang/test/CodeGenHLSL/lib_global.hlsl
  25. 1 1
      tools/clang/tools/dxcompiler/dxcassembler.cpp
  26. 6 1
      tools/clang/tools/dxcompiler/dxcompilerobj.cpp
  27. 2 1
      tools/clang/tools/dxcompiler/dxcontainerbuilder.cpp
  28. 18 2
      tools/clang/unittests/HLSL/DxilContainerTest.cpp
  29. 8 0
      tools/clang/unittests/HLSL/FileCheckerTest.cpp
  30. 4 4
      tools/clang/unittests/HLSL/LinkerTest.cpp
  31. 2 0
      tools/clang/unittests/HLSL/OptimizerTest.cpp
  32. 6 1
      tools/clang/unittests/HLSL/ValidationTest.cpp
  33. 0 1
      utils/hct/hctdb.py

+ 0 - 1
docs/DXIL.rst

@@ -3075,7 +3075,6 @@ META.DUPLICATESYSVALUE                    System value may only appear once in s
 META.ENTRYFUNCTION                        entrypoint not found
 META.FLAGSUSAGE                           Flags must match usage
 META.FORCECASEONSWITCH                    Attribute forcecase only works for switch
-META.FUNCTIONANNOTATION                   Cannot find function annotation for %0
 META.GLCNOTONAPPENDCONSUME                globallycoherent cannot be used with append/consume buffers
 META.INTEGERINTERPMODE                    Interpolation mode on integer must be Constant
 META.INTERPMODEINONEROW                   Interpolation mode must be identical for all elements packed into the same row.

+ 0 - 1
include/dxc/HLSL/DxilValidation.h

@@ -152,7 +152,6 @@ enum class ValidationRule : unsigned {
   MetaEntryFunction, // entrypoint not found
   MetaFlagsUsage, // Flags must match usage
   MetaForceCaseOnSwitch, // Attribute forcecase only works for switch
-  MetaFunctionAnnotation, // Cannot find function annotation for %0
   MetaGlcNotOnAppendConsume, // globallycoherent cannot be used with append/consume buffers
   MetaIntegerInterpMode, // Interpolation mode on integer must be Constant
   MetaInterpModeInOneRow, // Interpolation mode must be identical for all elements packed into the same row.

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

@@ -154,6 +154,7 @@ public:
   bool StripRootSignature = false; // OPT_Qstrip_rootsignature
   bool StripPrivate = false; // OPT_Qstrip_priv
   bool StripReflection = false; // OPT_Qstrip_reflect
+  bool KeepReflectionInDxil = false; // OPT_Qkeep_reflect_in_dxil
   bool StripReflectionFromDxil = false; // OPT_Qstrip_reflect_from_dxil
   bool ExtractRootSignature = false; // OPT_extractrootsignature
   bool DisassembleColorCoded = false; // OPT_Cc

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

@@ -353,8 +353,6 @@ def dumpbin : Flag<["-", "/"], "dumpbin">, Flags<[DriverOption]>, Group<hlslutil
   HelpText<"Load a binary file rather than compiling">;
 def Qstrip_reflect : Flag<["-", "/"], "Qstrip_reflect">, Flags<[CoreOption, DriverOption]>, Group<hlslutil_Group>,
   HelpText<"Strip reflection data from shader bytecode  (must be used with /Fo <file>)">;
-def Qstrip_reflect_from_dxil : Flag<["-", "/"], "Qstrip_reflect_from_dxil">, Flags<[CoreOption, HelpHidden]>, Group<hlslutil_Group>,
-  HelpText<"Strip reflection data from shader bytecode  (must be used with /Fo <file>)">;
 def Qstrip_debug : Flag<["-", "/"], "Qstrip_debug">, Flags<[CoreOption, DriverOption]>, Group<hlslutil_Group>,
   HelpText<"Strip debug information from 4_0+ shader bytecode  (must be used with /Fo <file>)">;
 def Qembed_debug : Flag<["-", "/"], "Qembed_debug">, Flags<[CoreOption]>, Group<hlslutil_Group>,
@@ -368,6 +366,14 @@ def extractrootsignature : Flag<["-", "/"], "extractrootsignature">, Flags<[Driv
 def verifyrootsignature  : JoinedOrSeparate<["-", "/"], "verifyrootsignature">,  MetaVarName<"<file>">, Flags<[DriverOption]>, Group<hlslutil_Group>, HelpText<"Verify shader bytecode with root signature">;
 def force_rootsig_ver    : JoinedOrSeparate<["-", "/"], "force_rootsig_ver">,    Flags<[CoreOption]>, MetaVarName<"<profile>">, Group<hlslcomp_Group>, HelpText<"force root signature version (rootsig_1_1 if omitted)">;
 
+// Temporary TEST options, until reflection inside DXIL part can always be stripped
+def Qkeep_reflect_in_dxil : Flag<["-", "/"], "Qkeep_reflect_in_dxil">,
+  Flags<[CoreOption, HelpHidden]>, Group<hlslutil_Group>,
+  HelpText<"Keep reflection data in shader bytecode">;
+def Qstrip_reflect_from_dxil : Flag<["-", "/"], "Qstrip_reflect_from_dxil">,
+  Flags<[CoreOption, HelpHidden]>, Group<hlslutil_Group>,
+  HelpText<"Strip reflection data from shader bytecode  (must be used with /Fo <file>)">;
+
 /*
 def shtemplate : JoinedOrSeparate<["-", "/"], "shtemplate">, MetaVarName<"<file>">, Group<hlslcomp_Group>,
   HelpText<"Template shader file for merging/matching resources">;

+ 1 - 1
lib/Analysis/IPA/CallGraph.cpp

@@ -159,7 +159,7 @@ Function *CallGraph::removeFunctionFromModule(CallGraphNode *CGN) {
   delete CGN;                       // Delete the call graph node for this func
   FunctionMap.erase(F);             // Remove the call graph node from the map
 
-  if (M.HasHLModule()) M.GetHLModule().RemoveFunction(F); // HLSL Change
+  M.CallRemoveGlobalHook(F); // HLSL Change
 
   M.getFunctionList().remove(F);
   return F;

+ 53 - 8
lib/DXIL/DxilModule.cpp

@@ -1542,8 +1542,28 @@ StripResourcesReflection(std::vector<std::unique_ptr<TResource>> &vec) {
   return bChanged;
 }
 
+static bool ResourceTypeRequiresTranslation(const StructType* Ty) {
+  if (Ty->getName().startswith("class.matrix."))
+    return true;
+  for (auto eTy : Ty->elements()) {
+    if (StructType *structTy = dyn_cast<StructType>(eTy)) {
+      if (ResourceTypeRequiresTranslation(structTy))
+        return true;
+    }
+    SequentialType *seqTy;
+    while (seqTy = dyn_cast<SequentialType>(eTy)) {
+      eTy = seqTy->getElementType();
+    }
+    if (eTy->getScalarSizeInBits() < 32) {
+      return true;
+    }
+  }
+  return false;
+}
+
 bool DxilModule::StripReflection() {
   bool bChanged = false;
+  bool bIsLib = GetShaderModel()->IsLib();
 
   // Remove names.
   for (Function &F : m_pModule->functions()) {
@@ -1560,15 +1580,36 @@ bool DxilModule::StripReflection() {
       }
     }
   }
-  // Remove struct annotation.
-  // FunctionAnnotation is used later, so keep it.
-  if (!m_pTypeSystem->GetStructAnnotationMap().empty()) {
-    m_pTypeSystem->GetStructAnnotationMap().clear();
-    bChanged = true;
+
+  if (bIsLib && GetUseMinPrecision())
+  {
+    // We must preserve struct annotations for resources containing min-precision types,
+    // since they have not yet been converted for legacy layout.
+    SmallVector<const StructType*, 4> structsToRemove;
+    for (auto &item : m_pTypeSystem->GetStructAnnotationMap()) {
+      if (!ResourceTypeRequiresTranslation(item.first))
+        structsToRemove.emplace_back(item.first);
+    }
+    for (auto Ty : structsToRemove) {
+      m_pTypeSystem->GetStructAnnotationMap().erase(Ty);
+    }
+  } else {
+    // Remove struct annotations.
+    if (!m_pTypeSystem->GetStructAnnotationMap().empty()) {
+      m_pTypeSystem->GetStructAnnotationMap().clear();
+      bChanged = true;
+    }
+    if (DXIL::CompareVersions(m_ValMajor, m_ValMinor, 1, 5) >= 0) {
+      // Remove function annotations.
+      if (!m_pTypeSystem->GetFunctionAnnotationMap().empty()) {
+        m_pTypeSystem->GetFunctionAnnotationMap().clear();
+        bChanged = true;
+      }
+    }
   }
 
   // Resource
-  if (!GetShaderModel()->IsLib()) {
+  if (!bIsLib) {
     bChanged |= StripResourcesReflection(m_CBuffers);
     bChanged |= StripResourcesReflection(m_UAVs);
     bChanged |= StripResourcesReflection(m_SRVs);
@@ -1578,8 +1619,12 @@ bool DxilModule::StripReflection() {
   // Unused global.
   SmallVector<GlobalVariable *,2> UnusedGlobals;
   for (GlobalVariable &GV : m_pModule->globals()) {
-    if (GV.use_empty())
-      UnusedGlobals.emplace_back(&GV);
+    if (GV.use_empty()) {
+      // Need to preserve this global, otherwise we drop constructors
+      // for static globals.
+      if (!bIsLib || GV.getName().compare("llvm.global_ctors") != 0)
+        UnusedGlobals.emplace_back(&GV);
+    }
   }
   bChanged |= !UnusedGlobals.empty();
 

+ 6 - 0
lib/DxcSupport/HLSLOptions.cpp

@@ -553,6 +553,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
   opts.StripRootSignature = Args.hasFlag(OPT_Qstrip_rootsignature, OPT_INVALID, false);
   opts.StripPrivate = Args.hasFlag(OPT_Qstrip_priv, OPT_INVALID, false);
   opts.StripReflection = Args.hasFlag(OPT_Qstrip_reflect, OPT_INVALID, false);
+  opts.KeepReflectionInDxil = Args.hasFlag(OPT_Qkeep_reflect_in_dxil, OPT_INVALID, false);
   opts.StripReflectionFromDxil = Args.hasFlag(OPT_Qstrip_reflect_from_dxil, OPT_INVALID, false);
   opts.ExtractRootSignature = Args.hasFlag(OPT_extractrootsignature, OPT_INVALID, false);
   opts.DisassembleColorCoded = Args.hasFlag(OPT_Cc, OPT_INVALID, false);
@@ -700,6 +701,11 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
     opts.ValVerMinor = 0;
   }
 
+  if (opts.KeepReflectionInDxil && opts.StripReflectionFromDxil) {
+    errors << "-Qstrip_reflect_from_dxil mutually exclusive with -Qkeep_reflect_in_dxil.";
+    return 1;
+  }
+
     // SPIRV Change Starts
 #ifdef ENABLE_SPIRV_CODEGEN
   opts.GenSPIRV = Args.hasFlag(OPT_spirv, OPT_INVALID, false);

+ 15 - 2
lib/DxilContainer/DxilContainerAssembler.cpp

@@ -1559,8 +1559,6 @@ void hlsl::SerializeDxilContainerForModule(DxilModule *pModule,
     Flags &= ~SerializeDxilFlags::IncludeDebugNamePart;
   bool bSupportsShaderHash = DXIL::CompareVersions(ValMajor, ValMinor, 1, 5) >= 0;
   bool bCompat_1_4 = DXIL::CompareVersions(ValMajor, ValMinor, 1, 5) < 0;
-  if (DXIL::CompareVersions(ValMajor, ValMinor, 1, 5) < 0)
-    Flags &= ~SerializeDxilFlags::IncludeReflectionPart;
   bool bEmitReflection = Flags & SerializeDxilFlags::IncludeReflectionPart ||
                          pReflectionStreamOut;
 
@@ -1679,7 +1677,22 @@ void hlsl::SerializeDxilContainerForModule(DxilModule *pModule,
   // Clone module for reflection, strip function defs
   std::unique_ptr<Module> reflectionModule;
   if (bEmitReflection) {
+    if (DXIL::CompareVersions(ValMajor, ValMinor, 1, 5) < 0) {
+      // Retain usage information in metadata for reflection by:
+      // Upgrade validator version, re-emit metadata, then clone module for reflection.
+      // 0,0 = Not meant to be validated, support latest
+      pModule->SetValidatorVersion(0, 0);
+      pModule->ReEmitDxilResources();
+    }
+
     reflectionModule.reset(llvm::CloneModule(pModule->GetModule()));
+
+    if (DXIL::CompareVersions(ValMajor, ValMinor, 1, 5) < 0) {
+      // Now restore validator version on main module and re-emit metadata.
+      pModule->SetValidatorVersion(ValMajor, ValMinor);
+      pModule->ReEmitDxilResources();
+    }
+
     for (Function &F : reflectionModule->functions()) {
       if (!F.isDeclaration()) {
         F.deleteBody();

+ 12 - 2
lib/HLSL/DxilCondenseResources.cpp

@@ -497,8 +497,14 @@ public:
 
     GenerateDxilResourceHandles();
 
+    // TODO: Update types earlier for libraries and replace users, to
+    //       avoid having to preserve HL struct annotation.
+    // Note 1: Needs to happen after legalize
+    // Note 2: Cannot do this easily/trivially if any functions have
+    //         resource arguments (in offline linking target).
     if (DM.GetOP()->UseMinPrecision())
       UpdateStructTypeForLegacyLayout();
+
     // Change resource symbol into undef.
     UpdateResourceSymbols();
 
@@ -1601,7 +1607,11 @@ StructType *UpdateStructTypeForLegacyLayout(StructType *ST,
   unsigned fieldsCount = ST->getNumElements();
   std::vector<Type *> fieldTypes(fieldsCount);
   DxilStructAnnotation *SA = TypeSys.GetStructAnnotation(ST);
-  DXASSERT(SA, "must have annotation for struct type");
+
+  // After reflection is stripped from library, this will be null if no update is required.
+  if (!SA) {
+    return ST;
+  }
 
   if (SA->IsEmptyStruct()) {
     return ST;
@@ -2139,7 +2149,7 @@ static unsigned GetOffsetForCBExtractValue(ExtractValueInst *EV, bool bMinPrecis
   unsigned bits = EV->getType()->getScalarSizeInBits();
   if (bits == 64)
     typeSize = 8;
-  else if (bits == 16 && bMinPrecision)
+  else if (bits == 16 && !bMinPrecision)
     typeSize = 2;
   return (EV->getIndices().front() * typeSize);
 }

+ 20 - 4
lib/HLSL/DxilContainerReflection.cpp

@@ -871,6 +871,7 @@ HRESULT CShaderReflectionType::Initialize(
   //
   // Note that DXIL supports some types that don't currently have equivalents
   // in the reflection interface, so we try to muddle through here.
+  bool bMinPrec = M.GetUseMinPrecision();
   D3D_SHADER_VARIABLE_TYPE componentType = D3D_SVT_VOID;
   switch(typeAnnotation.GetCompType().GetKind())
   {
@@ -884,12 +885,22 @@ HRESULT CShaderReflectionType::Initialize(
 
   case hlsl::DXIL::ComponentType::I16:
     componentType = D3D_SVT_MIN16INT;
-    m_Name = "min16int";
+    if (bMinPrec) {
+      m_Name = "min16int";
+    } else {
+      m_Name = "int16_t";
+      cbCompSize = 2;
+    }
     break;
 
   case hlsl::DXIL::ComponentType::U16:
     componentType = D3D_SVT_MIN16UINT;
-    m_Name = "min16uint";
+    if (bMinPrec) {
+      m_Name = "min16uint";
+    } else {
+      m_Name = "uint16_t";
+      cbCompSize = 2;
+    }
     break;
 
   case hlsl::DXIL::ComponentType::I64:
@@ -916,7 +927,12 @@ HRESULT CShaderReflectionType::Initialize(
   case hlsl::DXIL::ComponentType::SNormF16:
   case hlsl::DXIL::ComponentType::UNormF16:
     componentType = D3D_SVT_MIN16FLOAT;
-    m_Name = "min16float";
+    if (bMinPrec) {
+      m_Name = "min16float";
+    } else {
+      m_Name = "float16_t";
+      cbCompSize = 2;
+    }
     break;
 
   case hlsl::DXIL::ComponentType::F32:
@@ -1529,7 +1545,7 @@ static unsigned GetOffsetForCBExtractValue(ExtractValueInst *EV, bool bMinPrecis
   unsigned bits = EV->getType()->getScalarSizeInBits();
   if (bits == 64)
     typeSize = 8;
-  else if (bits == 16 && bMinPrecision)
+  else if (bits == 16 && !bMinPrecision)
     typeSize = 2;
   return (EV->getIndices().front() * typeSize);
 }

+ 24 - 3
lib/HLSL/DxilPreparePasses.cpp

@@ -352,13 +352,13 @@ public:
   bool runOnModule(Module &M) override {
     if (M.HasDxilModule()) {
       DxilModule &DM = M.GetDxilModule();
+      unsigned ValMajor = 0;
+      unsigned ValMinor = 0;
+      M.GetDxilModule().GetValidatorVersion(ValMajor, ValMinor);
 
       bool IsLib = DM.GetShaderModel()->IsLib();
       // Skip validation patch for lib.
       if (!IsLib) {
-        unsigned ValMajor = 0;
-        unsigned ValMinor = 0;
-        M.GetDxilModule().GetValidatorVersion(ValMajor, ValMinor);
         if (ValMajor == 1 && ValMinor <= 1) {
           patchValidation_1_1(M);
         }
@@ -393,6 +393,11 @@ public:
       // Clear intermediate options that shouldn't be in the final DXIL
       DM.ClearIntermediateOptions();
 
+      if (IsLib && DXIL::CompareVersions(ValMajor, ValMinor, 1, 4) <= 0) {
+        // 1.4 validator requires function annotations for all functions
+        AddFunctionAnnotationForInitializers(M, DM);
+      }
+
       return true;
     }
 
@@ -542,6 +547,22 @@ private:
       }
     }
   }
+
+  void AddFunctionAnnotationForInitializers(Module &M, DxilModule &DM) {
+    if (GlobalVariable *GV = M.getGlobalVariable("llvm.global_ctors")) {
+      ConstantArray *init = cast<ConstantArray>(GV->getInitializer());
+      for (auto V : init->operand_values()) {
+        if (isa<ConstantAggregateZero>(V))
+          continue;
+        ConstantStruct *CS = cast<ConstantStruct>(V);
+        if (isa<ConstantPointerNull>(CS->getOperand(1)))
+          continue;
+        Function *F = cast<Function>(CS->getOperand(1));
+        if (DM.GetTypeSystem().GetFunctionAnnotation(F) == nullptr)
+          DM.GetTypeSystem().AddFunctionAnnotation(F);
+      }
+    }
+  }
 };
 }
 

+ 0 - 8
lib/HLSL/DxilValidation.cpp

@@ -103,7 +103,6 @@ const char *hlsl::GetValidationRuleText(ValidationRule value) {
     case hlsl::ValidationRule::MetaTessellatorOutputPrimitive: return "Invalid Tessellator Output Primitive specified. Must be point, line, triangleCW or triangleCCW.";
     case hlsl::ValidationRule::MetaMaxTessFactor: return "Hull Shader MaxTessFactor must be [%0..%1].  %2 specified";
     case hlsl::ValidationRule::MetaValidSamplerMode: return "Invalid sampler mode on sampler ";
-    case hlsl::ValidationRule::MetaFunctionAnnotation: return "Cannot find function annotation for %0";
     case hlsl::ValidationRule::MetaGlcNotOnAppendConsume: return "globallycoherent cannot be used with append/consume buffers";
     case hlsl::ValidationRule::MetaStructBufAlignment: return "structured buffer element size must be a multiple of %0 bytes (actual size %1 bytes)";
     case hlsl::ValidationRule::MetaStructBufAlignmentOutOfBound: return "structured buffer elements cannot be larger than %0 bytes (actual size %1 bytes)";
@@ -3592,13 +3591,6 @@ static void ValidateFunction(Function &F, ValidationContext &ValCtx) {
     if (isShader && !F.getReturnType()->isVoidTy())
       ValCtx.EmitFormatError(ValidationRule::DeclShaderReturnVoid, { F.getName() });
 
-    DxilFunctionAnnotation *funcAnnotation =
-        ValCtx.DxilMod.GetTypeSystem().GetFunctionAnnotation(&F);
-    if (!funcAnnotation) {
-      ValCtx.EmitFormatError(ValidationRule::MetaFunctionAnnotation, { F.getName() });
-      return;
-    }
-
     auto ArgFormatError = [&](Argument &arg, ValidationRule rule) {
       if (arg.hasName())
         ValCtx.EmitFormatError(rule, { arg.getName().str(), F.getName() });

+ 2 - 8
lib/Transforms/IPO/GlobalDCE.cpp

@@ -25,10 +25,6 @@
 #include "llvm/Transforms/Utils/GlobalStatus.h"
 #include "llvm/Pass.h"
 #include <unordered_map>
-#include "dxc/HLSL/HLModule.h" // HLSL Change
-#include "dxc/DXIL/DxilModule.h" // HLSL Change
-#include "dxc/DXIL/DxilOperations.h" // HLSL Change
-#include "dxc/DXIL/DxilInstructions.h" // HLSL Change
 using namespace llvm;
 
 #define DEBUG_TYPE "globaldce"
@@ -166,14 +162,12 @@ bool GlobalDCE::runOnModule(Module &M) {
       I->setAliasee(nullptr);
     } 
 
-  hlsl::HLModule *HLM = M.HasHLModule() ? &M.GetHLModule() : nullptr; // HLSL Change
-
   if (!DeadFunctions.empty()) {
     // Now that all interferences have been dropped, delete the actual objects
     // themselves.
     for (unsigned i = 0, e = DeadFunctions.size(); i != e; ++i) {
       RemoveUnusedGlobalValue(*DeadFunctions[i]);
-      if (HLM != nullptr) HLM->RemoveFunction(DeadFunctions[i]); // HLSL Change
+      M.CallRemoveGlobalHook(DeadFunctions[i]); // HLSL Change
       M.getFunctionList().erase(DeadFunctions[i]);
     }
     NumFunctions += DeadFunctions.size();
@@ -183,7 +177,7 @@ bool GlobalDCE::runOnModule(Module &M) {
   if (!DeadGlobalVars.empty()) {
     for (unsigned i = 0, e = DeadGlobalVars.size(); i != e; ++i) {
       RemoveUnusedGlobalValue(*DeadGlobalVars[i]);
-      if (HLM != nullptr) HLM->RemoveGlobal(DeadGlobalVars[i]); // HLSL Change
+      M.CallRemoveGlobalHook(DeadGlobalVars[i]); // HLSL Change
       M.getGlobalList().erase(DeadGlobalVars[i]);
     }
     NumVariables += DeadGlobalVars.size();

+ 3 - 4
tools/clang/test/CodeGenHLSL/batch/compiler_options/Qstrip_reflect.hlsl

@@ -1,8 +1,7 @@
-// RUN: %dxc -E main -T ps_6_0 %s -Qstrip_reflect | FileCheck %s
+// RUN: %dxilver 1.5 | %dxc -E main -T ps_6_0 %s -Qstrip_reflect | FileCheck %s
 
-// Make sure only function annotation, no struct annotation.
-// CHECK:!dx.typeAnnotations = !{[[FuncAnnot:[^,]+]]}
-// CHECK:[[FuncAnnot]] = !{i32 1, void ()* @main,
+// Make sure there are no type annotations
+// CHECK-NOT: !dx.typeAnnotations
 
 //--------------------------------------------------------------------------------------
 // File: BasicHLSL11_PS.hlsl

+ 3 - 4
tools/clang/test/CodeGenHLSL/batch/compiler_options/Qstrip_reflect_struct_buf.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T ps_6_2 -enable-16bit-types -HV 2018 -Qstrip_reflect %s  | FileCheck %s
+// RUN: %dxilver 1.5 | %dxc -E main -T ps_6_2 -enable-16bit-types -HV 2018 -Qstrip_reflect %s  | FileCheck %s
 
 
 struct MyStruct1
@@ -76,6 +76,5 @@ float4 main() : SV_Target {
     return 1;
 }
 
-// Make sure only function annotation, no struct annotation.
-// CHECK:!dx.typeAnnotations = !{[[FuncAnnot:[^,]+]]}
-// CHECK:[[FuncAnnot]] = !{i32 1, void ()* @main,
+// Make sure there are no type annotations
+// CHECK-NOT: !dx.typeAnnotations

+ 2 - 2
tools/clang/test/CodeGenHLSL/batch/debug/misc/share_mem_dbg.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T cs_6_0 -Zi -Od -DDefineA -DDefineB=0 %s | FileCheck %s
+// RUN: %dxc -E main -T cs_6_0 -Zi -Od -DDefineA -DDefineB=0 %s -Qstrip_reflect | FileCheck %s
 
 // CHECK: threadId
 // CHECK: groupId
@@ -22,7 +22,7 @@
 // Make sure source info contents exist.
 // CHECK: !{!"DefineA=1", !"DefineB=0"}
 // CHECK: share_mem_dbg.hlsl"}
-// CHECK: !{!"-E", !"main", !"-T", !"cs_6_0", !"-Zi", !"-Od", !"-D", !"DefineA", !"-D", !"DefineB=0"}
+// CHECK: !{!"-E", !"main", !"-T", !"cs_6_0", !"-Zi", !"-Od", !"-D", !"DefineA", !"-D", !"DefineB=0", !"-Qstrip_reflect"}
 
 
 struct S {

+ 1 - 1
tools/clang/test/CodeGenHLSL/batch/misc/d3dreflect/cb_sizes.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T vs_6_0 %s | %D3DReflect %s | FileCheck %s
+// RUN: %dxilver 1.5 | %dxc -E main -T vs_6_0 %s | %D3DReflect %s | FileCheck %s
 
 // Verify CB variable sizes align with expectations.
 // This also tests some matrix, struct, and array cases that may

+ 1 - 1
tools/clang/test/CodeGenHLSL/batch/misc/d3dreflect/cbuf-usage-lib.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -auto-binding-space 13 -T lib_6_3 %s | %D3DReflect %s | FileCheck %s
+// RUN: %dxilver 1.5 | %dxc -auto-binding-space 13 -T lib_6_3 %s | %D3DReflect %s | FileCheck %s
 
 // Make sure usage flag is set properly for cbuffers used in libraries
 

+ 1 - 1
tools/clang/test/CodeGenHLSL/batch/misc/d3dreflect/empty_struct2.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T vs_6_0 %s | %D3DReflect %s | FileCheck %s
+// RUN: %dxilver 1.5 | %dxc -E main -T vs_6_0 %s | %D3DReflect %s | FileCheck %s
 
 // Make sure nest empty struct works.
 

+ 125 - 0
tools/clang/test/CodeGenHLSL/batch/misc/d3dreflect/lib_global.hlsl

@@ -0,0 +1,125 @@
+// RUN: %dxilver 1.5 | %dxc -T lib_6_3 -enable-16bit-types %s | %D3DReflect %s | FileCheck %s
+
+// Note: validator version 1.5 is required because these tests use
+// module disassembly -> reassembly between steps, and type annotations
+// compatible with the 1.4 validator does not have usage metadata, so it's lost.
+
+// Make sure CB usage is correct.
+#if 0
+// CHECK: ID3D12LibraryReflection:
+// CHECK-NEXT:   D3D12_LIBRARY_DESC:
+// CHECK-NEXT:     Creator: <nullptr>
+// CHECK-NEXT:     Flags: 0
+// CHECK-NEXT:     FunctionCount: 2
+// CHECK-NEXT:   ID3D12FunctionReflection:
+// CHECK-NEXT:     D3D12_FUNCTION_DESC: Name: _GLOBAL__sub_I_lib_global.hlsl
+// CHECK-NEXT:       Shader Version: Library 6.3
+// CHECK-NEXT:       Creator: <nullptr>
+// CHECK-NEXT:       Flags: 0
+// CHECK-NEXT:       ConstantBuffers: 1
+// CHECK-NEXT:       BoundResources: 1
+// CHECK-NEXT:       FunctionParameterCount: 0
+// CHECK-NEXT:       HasReturn: FALSE
+// CHECK-NEXT:     Constant Buffers:
+// CHECK-NEXT:       ID3D12ShaderReflectionConstantBuffer:
+// CHECK-NEXT:         D3D12_SHADER_BUFFER_DESC: Name: X
+// CHECK-NEXT:           Type: D3D_CT_CBUFFER
+// CHECK-NEXT:           Size: 16
+// CHECK-NEXT:           uFlags: 0
+// CHECK-NEXT:           Num Variables: 2
+// CHECK-NEXT:         {
+// CHECK-NEXT:           ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:             D3D12_SHADER_VARIABLE_DESC: Name: e
+// CHECK-NEXT:               Size: 2
+// CHECK-NEXT:               StartOffset: 0
+// CHECK-NEXT:               uFlags: 0
+// CHECK-NEXT:               DefaultValue: <nullptr>
+// CHECK-NEXT:             ID3D12ShaderReflectionType:
+// CHECK-NEXT:               D3D12_SHADER_TYPE_DESC: Name: float16_t
+// CHECK-NEXT:                 Class: D3D_SVC_SCALAR
+// CHECK-NEXT:                 Type: D3D_SVT_MIN16FLOAT
+// CHECK-NEXT:                 Elements: 0
+// CHECK-NEXT:                 Rows: 1
+// CHECK-NEXT:                 Columns: 1
+// CHECK-NEXT:                 Members: 0
+// CHECK-NEXT:                 Offset: 0
+// CHECK-NEXT:             CBuffer: X
+// CHECK-NEXT:           ID3D12ShaderReflectionVariable:
+// CHECK-NEXT:             D3D12_SHADER_VARIABLE_DESC: Name: f
+// CHECK-NEXT:               Size: 2
+// CHECK-NEXT:               StartOffset: 2
+// CHECK-NEXT:               uFlags: 0x2
+// CHECK-NEXT:               DefaultValue: <nullptr>
+// CHECK-NEXT:             ID3D12ShaderReflectionType:
+// CHECK-NEXT:               D3D12_SHADER_TYPE_DESC: Name: float16_t
+// CHECK-NEXT:                 Class: D3D_SVC_SCALAR
+// CHECK-NEXT:                 Type: D3D_SVT_MIN16FLOAT
+// CHECK-NEXT:                 Elements: 0
+// CHECK-NEXT:                 Rows: 1
+// CHECK-NEXT:                 Columns: 1
+// CHECK-NEXT:                 Members: 0
+// CHECK-NEXT:                 Offset: 0
+// CHECK-NEXT:             CBuffer: X
+// CHECK-NEXT:         }
+// CHECK-NEXT:     Bound Resources:
+// CHECK-NEXT:       D3D12_SHADER_BUFFER_DESC: Name: X
+// CHECK-NEXT:         Type: D3D_SIT_CBUFFER
+// CHECK-NEXT:         uID: 0
+// CHECK-NEXT:         BindCount: 1
+// CHECK-NEXT:         BindPoint: 4294967295
+// CHECK-NEXT:         Space: 4294967295
+// CHECK-NEXT:         ReturnType: <unknown: 0>
+// CHECK-NEXT:         Dimension: D3D_SRV_DIMENSION_UNKNOWN
+// CHECK-NEXT:         NumSamples (or stride): 0
+// CHECK-NEXT:         uFlags: 0
+// CHECK-NEXT:   ID3D12FunctionReflection:
+// CHECK-NEXT:     D3D12_FUNCTION_DESC: Name: test
+// CHECK-NEXT:       Shader Version: Pixel 6.3
+// CHECK-NEXT:       Creator: <nullptr>
+// CHECK-NEXT:       Flags: 0
+// CHECK-NEXT:       ConstantBuffers: 0
+// CHECK-NEXT:       BoundResources: 2
+// CHECK-NEXT:       FunctionParameterCount: 0
+// CHECK-NEXT:       HasReturn: FALSE
+// CHECK-NEXT:     Bound Resources:
+// CHECK-NEXT:       D3D12_SHADER_BUFFER_DESC: Name: g_samLinear
+// CHECK-NEXT:         Type: D3D_SIT_SAMPLER
+// CHECK-NEXT:         uID: 0
+// CHECK-NEXT:         BindCount: 1
+// CHECK-NEXT:         BindPoint: 4294967295
+// CHECK-NEXT:         Space: 4294967295
+// CHECK-NEXT:         ReturnType: <unknown: 0>
+// CHECK-NEXT:         Dimension: D3D_SRV_DIMENSION_UNKNOWN
+// CHECK-NEXT:         NumSamples (or stride): 0
+// CHECK-NEXT:         uFlags: 0
+// CHECK-NEXT:       D3D12_SHADER_BUFFER_DESC: Name: g_txDiffuse
+// CHECK-NEXT:         Type: D3D_SIT_TEXTURE
+// CHECK-NEXT:         uID: 0
+// CHECK-NEXT:         BindCount: 1
+// CHECK-NEXT:         BindPoint: 4294967295
+// CHECK-NEXT:         Space: 4294967295
+// CHECK-NEXT:         ReturnType: D3D_RETURN_TYPE_FLOAT
+// CHECK-NEXT:         Dimension: D3D_SRV_DIMENSION_TEXTURE2D
+// CHECK-NEXT:         NumSamples (or stride): 4294967295
+// CHECK-NEXT:         uFlags: 0xc
+#endif
+
+Texture2D    g_txDiffuse;
+SamplerState    g_samLinear;
+
+cbuffer X {
+  half e, f;
+}
+
+static float g[2] = { 1, f };
+
+[shader("pixel")]
+float4 test(float2 c : C) : SV_TARGET
+{
+  float4 x = g_txDiffuse.Sample( g_samLinear, c );
+  return x + g[1];
+}
+
+void update() {
+  g[1]++;
+}

+ 1 - 1
tools/clang/test/CodeGenHLSL/batch/misc/d3dreflect/reflect-lib-1.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -T lib_6_3 -auto-binding-space 11 -default-linkage external %s | %D3DReflect %s | FileCheck %s
+// RUN: %dxilver 1.5 | %dxc -T lib_6_3 -auto-binding-space 11 -default-linkage external %s | %D3DReflect %s | FileCheck %s
 
 float cbval1;
 cbuffer MyCB : register(b11, space2) { int4 cbval2, cbval3; }

+ 1 - 1
tools/clang/test/CodeGenHLSL/batch/misc/d3dreflect/structured_buffer_layout.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -E main -T vs_6_0 %s | %D3DReflect %s | FileCheck %s
+// RUN: %dxilver 1.5 | %dxc -E main -T vs_6_0 %s | %D3DReflect %s | FileCheck %s
 
 // Verify SB type description does not follow the CB offseting alignment
 // even when structure is shared with a ConstantBuffer.

+ 1 - 1
tools/clang/test/CodeGenHLSL/batch/misc/static_const_global.hlsl

@@ -1,4 +1,4 @@
-// RUN: %dxc -T lib_6_3 -auto-binding-space 11 %s | FileCheck %s
+// RUN: %dxilver 1.5 | %dxc -T lib_6_3 -auto-binding-space 11 %s | FileCheck %s
 
 // Make sure ST is removed
 // CHECK-NOT: @ST

+ 4 - 1
tools/clang/test/CodeGenHLSL/lib_global.hlsl

@@ -4,7 +4,10 @@ Texture2D    g_txDiffuse;
 SamplerState    g_samLinear;
 
 cbuffer X {
-float f;
+  // Use min-precision type to force conversion of constant buffer type for legacy.
+  // This has to happen at link time at the moment, so this will break unless type
+  // annotations are retained for library.
+  min16float f;
 }
 
 static float g[2] = { 1, f };

+ 1 - 1
tools/clang/tools/dxcompiler/dxcassembler.cpp

@@ -141,7 +141,7 @@ HRESULT STDMETHODCALLTYPE DxcAssembler::AssembleToContainer(
     outStream.flush();
 
     CComPtr<IDxcBlob> pResultBlob;
-    hlsl::SerializeDxilFlags flags = hlsl::SerializeDxilFlags::None;
+    hlsl::SerializeDxilFlags flags = hlsl::SerializeDxilFlags::IncludeReflectionPart;
     if (HasDebugInfo(*M)) {
       flags |= SerializeDxilFlags::IncludeDebugInfoPart;
       flags |= SerializeDxilFlags::IncludeDebugNamePart;

+ 6 - 1
tools/clang/tools/dxcompiler/dxcompilerobj.cpp

@@ -624,6 +624,11 @@ public:
         needsValidation = false;
       }
 
+      if (compiler.getCodeGenOpts().HLSLProfile == "lib_6_x") {
+        // Currently do not support stripping reflection from offline linking target.
+        opts.KeepReflectionInDxil = true;
+      }
+
       if (opts.ValVerMajor != UINT_MAX) {
         // user-specified validator version override
         compiler.getCodeGenOpts().HLSLValidatorMajorVer = opts.ValVerMajor;
@@ -735,7 +740,7 @@ public:
           // Implies name part
           SerializeFlags |= SerializeDxilFlags::IncludeDebugNamePart;
         }
-        if (opts.StripReflection || opts.StripReflectionFromDxil) {
+        if (!opts.KeepReflectionInDxil) {
           SerializeFlags |= SerializeDxilFlags::StripReflectionFromDxilPart;
         }
         if (!opts.StripReflection) {

+ 2 - 1
tools/clang/tools/dxcompiler/dxcontainerbuilder.cpp

@@ -123,7 +123,8 @@ HRESULT STDMETHODCALLTYPE DxcContainerBuilder::RemovePart(_In_ UINT32 fourCC) {
     IFTBOOL(fourCC == DxilFourCC::DFCC_ShaderDebugInfoDXIL ||
                 fourCC == DxilFourCC::DFCC_ShaderDebugName ||
                 fourCC == DxilFourCC::DFCC_RootSignature ||
-                fourCC == DxilFourCC::DFCC_PrivateData,
+                fourCC == DxilFourCC::DFCC_PrivateData ||
+                fourCC == DxilFourCC::DFCC_ShaderStatistics,
             E_INVALIDARG); // You can only remove debug info, debug info name, rootsignature, or private data blob
     PartList::iterator it =
       std::find_if(m_parts.begin(), m_parts.end(),

+ 18 - 2
tools/clang/unittests/HLSL/DxilContainerTest.cpp

@@ -336,8 +336,12 @@ public:
     std::vector<FileRunCommandPart> parts;
     ParseCommandPartsFromFile(path, parts);
     VERIFY_IS_TRUE(parts.size() > 0);
-    VERIFY_ARE_EQUAL_STR(parts[0].Command.c_str(), "%dxc");
-    FileRunCommandPart &dxc = parts[0];
+    unsigned partIdx = 0;
+    if (parts[0].Command.compare("%dxilver") == 0) {
+      partIdx = 1;
+    }
+    FileRunCommandPart &dxc = parts[partIdx];
+    VERIFY_ARE_EQUAL_STR(dxc.Command.c_str(), "%dxc");
     m_dllSupport.Initialize();
 
     hlsl::options::MainArgs args;
@@ -504,6 +508,18 @@ public:
 
   void ReflectionTest(LPCWSTR name, bool ignoreIfDXBCFails) {
     WEX::Logging::Log::Comment(WEX::Common::String().Format(L"Reflection comparison for %s", name));
+
+    // Skip if unsupported.
+    std::vector<FileRunCommandPart> parts;
+    ParseCommandPartsFromFile(name, parts);
+    VERIFY_IS_TRUE(parts.size() > 0);
+    if (parts[0].Command.compare("%dxilver") == 0) {
+      VERIFY_IS_TRUE(parts.size() > 1);
+      auto result = parts[0].Run(m_dllSupport, nullptr);
+      if (result.ExitCode != 0)
+        return;
+    }
+
     CComPtr<IDxcBlob> pProgram;
     CComPtr<IDxcBlob> pProgramDXBC;
     HRESULT hrDXBC = CompileFromFile(name, true, &pProgramDXBC);

+ 8 - 0
tools/clang/unittests/HLSL/FileCheckerTest.cpp

@@ -431,6 +431,14 @@ FileRunCommandResult FileRunCommandPart::RunDxc(dxc::DxcDllSupport &DllSupport,
     }
   }
 
+  // For now, too many tests are sensitive to stripping the refleciton info
+  // from the main module, so use this flag to prevent this until tests
+  // can be updated.
+  // That is, unless the test explicitly requests -Qstrip_reflect_from_dxil or -Qstrip_reflect
+  if (!opts.StripReflectionFromDxil && !opts.StripReflection) {
+    flags.push_back(L"-Qkeep_reflect_in_dxil");
+  }
+
   std::vector<std::wstring> argWStrings;
   CopyArgsToWStrings(opts.Args, hlsl::options::CoreOption, argWStrings);
   for (const std::wstring &a : argWStrings)

+ 4 - 4
tools/clang/unittests/HLSL/LinkerTest.cpp

@@ -72,7 +72,8 @@ public:
   }
 
   void CompileLib(LPCWSTR filename, IDxcBlob **pResultBlob,
-                  llvm::ArrayRef<LPCWSTR> pArguments = {}) {
+                  llvm::ArrayRef<LPCWSTR> pArguments = {},
+                  LPCWSTR pShaderTarget = L"lib_6_x") {
     std::wstring fullPath = hlsl_test::GetPathToHlslDataFile(filename);
     CComPtr<IDxcBlobEncoding> pSource;
     CComPtr<IDxcLibrary> pLibrary;
@@ -85,10 +86,9 @@ public:
     CComPtr<IDxcOperationResult> pResult;
     CComPtr<IDxcBlob> pProgram;
 
-    CA2W shWide("lib_6_x", CP_UTF8);
     VERIFY_SUCCEEDED(
         m_dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler));
-    VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"hlsl.hlsl", L"", shWide,
+    VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"hlsl.hlsl", L"", pShaderTarget,
                                         const_cast<LPCWSTR*>(pArguments.data()), pArguments.size(),
                                         nullptr, 0,
                                         nullptr, &pResult));
@@ -218,7 +218,7 @@ TEST_F(LinkerTest, RunLinkFailReDefine) {
 
 TEST_F(LinkerTest, RunLinkGlobalInit) {
   CComPtr<IDxcBlob> pEntryLib;
-  CompileLib(L"..\\CodeGenHLSL\\lib_global.hlsl", &pEntryLib);
+  CompileLib(L"..\\CodeGenHLSL\\lib_global.hlsl", &pEntryLib, {}, L"lib_6_3");
   CComPtr<IDxcLinker> pLinker;
   CreateLinker(&pLinker);
 

+ 2 - 0
tools/clang/unittests/HLSL/OptimizerTest.cpp

@@ -179,12 +179,14 @@ void OptimizerTest::OptimizerWhenSliceNThenOK(int optLevel, LPCWSTR pText, LPCWS
   highLevelArgs.insert(highLevelArgs.end(), args.begin(), args.end());
 
   // Create the target program with a single invocation.
+  highLevelArgs.emplace_back(L"/Qkeep_reflect_in_dxil");
   VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"source.hlsl", L"main", pTarget,
     highLevelArgs.data(), static_cast<UINT32>(highLevelArgs.size()), nullptr, 0, nullptr, &pResult));
   VerifyOperationSucceeded(pResult);
   VERIFY_SUCCEEDED(pResult->GetResult(&pProgram));
   pResult.Release();
   std::string originalAssembly = DisassembleProgram(m_dllSupport, pProgram);
+  highLevelArgs.pop_back(); // Remove /keep_reflect_in_dxil
 
   // Get a list of passes for this configuration.
   highLevelArgs.emplace_back(L"/Odump");

+ 6 - 1
tools/clang/unittests/HLSL/ValidationTest.cpp

@@ -356,10 +356,15 @@ public:
       }
     }
 
+    std::vector<LPCWSTR> args;
+    args.reserve(argCount + 1);
+    args.insert(args.begin(), pArguments, pArguments + argCount);
+    args.emplace_back(L"-Qkeep_reflect_in_dxil");
+
     VERIFY_SUCCEEDED(
         m_dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler));
     VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"hlsl.hlsl", pEntryName, shWide,
-                                        pArguments, argCount, pDefines,
+                                        args.data(), (UINT32)args.size(), pDefines,
                                         defineCount, nullptr, &pResult));
     CheckOperationResultMsgs(pResult, nullptr, false, false);
     VERIFY_SUCCEEDED(pResult->GetResult(pResultBlob));

+ 0 - 1
utils/hct/hctdb.py

@@ -2271,7 +2271,6 @@ class db_dxil(object):
         self.add_valrule("Meta.TessellatorOutputPrimitive", "Invalid Tessellator Output Primitive specified. Must be point, line, triangleCW or triangleCCW.")
         self.add_valrule("Meta.MaxTessFactor", "Hull Shader MaxTessFactor must be [%0..%1].  %2 specified")
         self.add_valrule("Meta.ValidSamplerMode", "Invalid sampler mode on sampler ")
-        self.add_valrule("Meta.FunctionAnnotation", "Cannot find function annotation for %0")
         self.add_valrule("Meta.GlcNotOnAppendConsume", "globallycoherent cannot be used with append/consume buffers")
         self.add_valrule_msg("Meta.StructBufAlignment", "StructuredBuffer stride not aligned","structured buffer element size must be a multiple of %0 bytes (actual size %1 bytes)")
         self.add_valrule_msg("Meta.StructBufAlignmentOutOfBound", "StructuredBuffer stride out of bounds","structured buffer elements cannot be larger than %0 bytes (actual size %1 bytes)")