Browse Source

Remove ResourceAttribute metadata node from DxilFieldAnnotation (#4671)

Currently, ResourceAttribute is only used to capture resource type information during CodeGen for the annotate handle generated during AddOpcodeParamForIntrinsic.

Going through a metadata node is totally unnecessary, just adding code and complexity.

This change just stores the DxilResourceProperties instead, renaming `*ResourceAttribute` methods to `*ResourceProperties`.
This change also emits the resource properties to new field annotaion metadata in validator version 1.8+ to preserve through serialization.
Tex Riddell 3 years ago
parent
commit
87c30cf38f

+ 1 - 9
include/dxc/DXIL/DxilMetadataHelper.h

@@ -226,6 +226,7 @@ public:
   static const unsigned kDxilFieldAnnotationCompTypeTag           = 7;
   static const unsigned kDxilFieldAnnotationPreciseTag            = 8;
   static const unsigned kDxilFieldAnnotationCBUsedTag             = 9;
+  static const unsigned kDxilFieldAnnotationResPropTag            = 10;
 
   // DXR Payload Annotations
   static const unsigned kDxilPayloadAnnotationStructTag           = 0;
@@ -241,12 +242,6 @@ public:
   // Control flow hint.
   static const char kDxilControlFlowHintMDName[];
 
-  // Resource attribute.
-  static const char kHLDxilResourceAttributeMDName[];
-  static const unsigned kHLDxilResourceAttributeNumFields = 2;
-  static const unsigned kHLDxilResourceAttributeClass = 0;
-  static const unsigned kHLDxilResourceAttributeMeta = 1;
-
   // Precise attribute.
   static const char kDxilPreciseAttributeMDName[];
 
@@ -411,9 +406,6 @@ public:
   llvm::MDTuple *EmitDxilSampler(const DxilSampler &S);
   void LoadDxilSampler(const llvm::MDOperand &MDO, DxilSampler &S);
   const llvm::MDOperand &GetResourceClass(llvm::MDNode *MD, DXIL::ResourceClass &RC);
-  void LoadDxilResourceBaseFromMDNode(llvm::MDNode *MD, DxilResourceBase &R);
-  void LoadDxilResourceFromMDNode(llvm::MDNode *MD, DxilResource &R);
-  void LoadDxilSamplerFromMDNode(llvm::MDNode *MD, DxilSampler &S);
 
   // Type system.
   void EmitDxilTypeSystem(DxilTypeSystem &TypeSystem, std::vector<llvm::GlobalVariable *> &LLVMUsed);

+ 0 - 4
include/dxc/DXIL/DxilModule.h

@@ -109,10 +109,6 @@ public:
   const DxilResource &GetUAV(unsigned idx) const;
   const std::vector<std::unique_ptr<DxilResource> > &GetUAVs() const;
 
-  void LoadDxilResourceBaseFromMDNode(llvm::MDNode *MD, DxilResourceBase &R);
-  void LoadDxilResourceFromMDNode(llvm::MDNode *MD, DxilResource &R);
-  void LoadDxilSamplerFromMDNode(llvm::MDNode *MD, DxilSampler &S);
-
   void RemoveUnusedResources();
   void RemoveResourcesWithUnusedSymbols();
   void RemoveFunction(llvm::Function *F);

+ 8 - 4
include/dxc/DXIL/DxilTypeSystem.h

@@ -15,6 +15,7 @@
 #include "dxc/DXIL/DxilConstants.h"
 #include "dxc/DXIL/DxilCompType.h"
 #include "dxc/DXIL/DxilInterpolationMode.h"
+#include "dxc/DXIL/DxilResourceProperties.h"
 
 #include <memory>
 #include <string>
@@ -54,9 +55,12 @@ public:
   const DxilMatrixAnnotation &GetMatrixAnnotation() const;
   void SetMatrixAnnotation(const DxilMatrixAnnotation &MA);
 
-  bool HasResourceAttribute() const;
-  llvm::MDNode *GetResourceAttribute() const;
-  void SetResourceAttribute(llvm::MDNode *MD);
+  // Currently, ResourceProperties is only used to capture resource type
+  // information during CodeGen for the annotate handle generated during
+  // AddOpcodeParamForIntrinsic.
+  bool HasResourceProperties() const;
+  const DxilResourceProperties &GetResourceProperties() const;
+  void SetResourceProperties(const DxilResourceProperties &RP);
 
   bool HasCBufferOffset() const;
   unsigned GetCBufferOffset() const;
@@ -86,7 +90,7 @@ private:
   bool m_bPrecise;
   CompType m_CompType;
   DxilMatrixAnnotation m_Matrix;
-  llvm::MDNode *m_ResourceAttribute;
+  DxilResourceProperties m_ResourceProps;
   unsigned m_CBufferOffset;
   std::string m_Semantic;
   InterpolationMode m_InterpMode;

+ 1 - 8
include/dxc/HLSL/HLModule.h

@@ -176,14 +176,7 @@ public:
   void LoadHLMetadata();
   /// Delete any HLDXIR from the specified module.
   static void ClearHLMetadata(llvm::Module &M);
-  /// Create Metadata from a resource.
-  llvm::MDNode *DxilSamplerToMDNode(const DxilSampler &S);
-  llvm::MDNode *DxilSRVToMDNode(const DxilResource &SRV);
-  llvm::MDNode *DxilUAVToMDNode(const DxilResource &UAV);
-  llvm::MDNode *DxilCBufferToMDNode(const DxilCBuffer &CB);
-  void LoadDxilResourceBaseFromMDNode(llvm::MDNode *MD, DxilResourceBase &R);
-  void LoadDxilResourceFromMDNode(llvm::MDNode *MD, DxilResource &R);
-  void LoadDxilSamplerFromMDNode(llvm::MDNode *MD, DxilSampler &S);
+
   DxilResourceBase *
   AddResourceWithGlobalVariableAndProps(llvm::Constant *GV,
                                         DxilResourceProperties &RP);

+ 15 - 71
lib/DXIL/DxilMetadataHelper.cpp

@@ -20,6 +20,8 @@
 #include "dxc/DXIL/DxilFunctionProps.h"
 #include "dxc/DXIL/DxilShaderFlags.h"
 #include "dxc/DXIL/DxilSubobject.h"
+#include "dxc/DXIL/DxilModule.h"
+#include "dxc/DXIL/DxilOperations.h"
 
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/Function.h"
@@ -86,7 +88,6 @@ const char DxilMDHelper::kDxilPreciseAttributeMDName[]                = "dx.prec
 const char DxilMDHelper::kDxilVariableDebugLayoutMDName[]             = "dx.dbg.varlayout";
 const char DxilMDHelper::kDxilTempAllocaMDName[]                      = "dx.temp";
 const char DxilMDHelper::kDxilNonUniformAttributeMDName[]             = "dx.nonuniform";
-const char DxilMDHelper::kHLDxilResourceAttributeMDName[]             = "dx.hl.resource.attribute";
 const char DxilMDHelper::kDxilValidatorVersionMDName[]                = "dx.valver";
 const char DxilMDHelper::kDxilDxrPayloadAnnotationsMDName[]           = "dx.dxrPayloadAnnotations";
 
@@ -1205,6 +1206,14 @@ Metadata *DxilMDHelper::EmitDxilFieldAnnotation(const DxilFieldAnnotation &FA) {
     MDVals.emplace_back(Uint32ToConstMD(kDxilFieldAnnotationCBUsedTag));
     MDVals.emplace_back(BoolToConstMD(true));
   }
+  if (FA.HasResourceProperties() &&
+    DXIL::CompareVersions(m_MinValMajor, m_MinValMinor, 1, 8) >= 0) {
+    MDVals.emplace_back(Uint32ToConstMD(kDxilFieldAnnotationResPropTag));
+    MDVals.emplace_back(ValueAsMetadata::get(resource_helper::getAsConstant(
+        FA.GetResourceProperties(),
+        m_pModule->GetDxilModule().GetOP()->GetResourcePropertiesType(),
+        *m_pSM)));
+  }
 
   return MDNode::get(m_Ctx, MDVals);
 }
@@ -1253,6 +1262,11 @@ void DxilMDHelper::LoadDxilFieldAnnotation(const MDOperand &MDO, DxilFieldAnnota
     case kDxilFieldAnnotationCBUsedTag:
       FA.SetCBVarUsed(ConstMDToBool(MDO));
       break;
+    case kDxilFieldAnnotationResPropTag:
+      if (Constant *C = dyn_cast_or_null<Constant>(
+              dyn_cast<ValueAsMetadata>(MDO)->getValue()))
+        FA.SetResourceProperties(resource_helper::loadPropsFromConstant(*C));
+      break;
     default:
       DXASSERT(false, "Unknown extended shader properties tag");
       m_bExtraMetadata = true;
@@ -2032,76 +2046,6 @@ void DxilMDHelper::LoadDxilSampler(const MDOperand &MDO, DxilSampler &S) {
   m_bExtraMetadata |= m_ExtraPropertyHelper->m_bExtraMetadata;
 }
 
-const MDOperand &DxilMDHelper::GetResourceClass(llvm::MDNode *MD,
-                                                DXIL::ResourceClass &RC) {
-  IFTBOOL(MD->getNumOperands() >=
-              DxilMDHelper::kHLDxilResourceAttributeNumFields,
-          DXC_E_INCORRECT_DXIL_METADATA);
-  RC = static_cast<DxilResource::Class>(ConstMDToUint32(
-      MD->getOperand(DxilMDHelper::kHLDxilResourceAttributeClass)));
-  return MD->getOperand(DxilMDHelper::kHLDxilResourceAttributeMeta);
-}
-
-void DxilMDHelper::LoadDxilResourceBaseFromMDNode(llvm::MDNode *MD,
-                                                  DxilResourceBase &R) {
-  DxilResource::Class RC = DxilResource::Class::Invalid;
-  const MDOperand &Meta = GetResourceClass(MD, RC);
-
-  switch (RC) {
-  case DxilResource::Class::CBuffer: {
-    DxilCBuffer CB;
-    LoadDxilCBuffer(Meta, CB);
-    R = CB;
-  } break;
-  case DxilResource::Class::Sampler: {
-    DxilSampler S;
-    LoadDxilSampler(Meta, S);
-    R = S;
-  } break;
-  case DxilResource::Class::SRV: {
-    DxilResource Res;
-    LoadDxilSRV(Meta, Res);
-    R = Res;
-  } break;
-  case DxilResource::Class::UAV: {
-    DxilResource Res;
-    LoadDxilUAV(Meta, Res);
-    R = Res;
-  } break;
-  default:
-    DXASSERT(0, "Invalid metadata");
-  }
-}
-
-void DxilMDHelper::LoadDxilResourceFromMDNode(llvm::MDNode *MD,
-                                              DxilResource &R) {
-  DxilResource::Class RC = DxilResource::Class::Invalid;
-  const MDOperand &Meta = GetResourceClass(MD, RC);
-
-  switch (RC) {
-  case DxilResource::Class::SRV: {
-    LoadDxilSRV(Meta, R);
-  } break;
-  case DxilResource::Class::UAV: {
-    LoadDxilUAV(Meta, R);
-  } break;
-  default:
-    DXASSERT(0, "Invalid metadata");
-  }
-}
-
-void DxilMDHelper::LoadDxilSamplerFromMDNode(llvm::MDNode *MD, DxilSampler &S) {
-  DxilResource::Class RC = DxilResource::Class::Invalid;
-  const MDOperand &Meta = GetResourceClass(MD, RC);
-
-  switch (RC) {
-  case DxilResource::Class::Sampler: {
-    LoadDxilSampler(Meta, S);
-  } break;
-  default:
-    DXASSERT(0, "Invalid metadata");
-  }
-}
 
 //
 // DxilExtraPropertyHelper shader-specific methods.

+ 0 - 10
lib/DXIL/DxilModule.cpp

@@ -916,16 +916,6 @@ const vector<unique_ptr<DxilResource> > &DxilModule::GetUAVs() const {
   return m_UAVs;
 }
 
-void DxilModule::LoadDxilResourceBaseFromMDNode(MDNode *MD, DxilResourceBase &R) {
-  return m_pMDHelper->LoadDxilResourceBaseFromMDNode(MD, R);
-}
-void DxilModule::LoadDxilResourceFromMDNode(llvm::MDNode *MD, DxilResource &R) {
-  return m_pMDHelper->LoadDxilResourceFromMDNode(MD, R);
-}
-void DxilModule::LoadDxilSamplerFromMDNode(llvm::MDNode *MD, DxilSampler &S) {
-  return m_pMDHelper->LoadDxilSamplerFromMDNode(MD, S);
-}
-
 template <typename TResource>
 static void RemoveResources(std::vector<std::unique_ptr<TResource>> &vec,
                     std::unordered_set<unsigned> &immResID) {

+ 6 - 7
lib/DXIL/DxilTypeSystem.cpp

@@ -43,7 +43,6 @@ DxilMatrixAnnotation::DxilMatrixAnnotation()
 //
 DxilFieldAnnotation::DxilFieldAnnotation()
 : m_bPrecise(false)
-, m_ResourceAttribute(nullptr)
 , m_CBufferOffset(UINT_MAX)
 , m_bCBufferVarUsed(false)
 {}
@@ -53,14 +52,14 @@ void DxilFieldAnnotation::SetPrecise(bool b) { m_bPrecise = b; }
 bool DxilFieldAnnotation::HasMatrixAnnotation() const { return m_Matrix.Cols != 0; }
 const DxilMatrixAnnotation &DxilFieldAnnotation::GetMatrixAnnotation() const { return m_Matrix; }
 void DxilFieldAnnotation::SetMatrixAnnotation(const DxilMatrixAnnotation &MA) { m_Matrix = MA; }
-bool DxilFieldAnnotation::HasResourceAttribute() const {
-  return m_ResourceAttribute;
+bool DxilFieldAnnotation::HasResourceProperties() const {
+  return m_ResourceProps.isValid();
 }
-llvm::MDNode *DxilFieldAnnotation::GetResourceAttribute() const {
-  return m_ResourceAttribute;
+const DxilResourceProperties &DxilFieldAnnotation::GetResourceProperties() const {
+  return m_ResourceProps;
 }
-void DxilFieldAnnotation::SetResourceAttribute(llvm::MDNode *MD) {
-  m_ResourceAttribute = MD;
+void DxilFieldAnnotation::SetResourceProperties(const DxilResourceProperties &RP) {
+  m_ResourceProps = RP;
 }
 bool DxilFieldAnnotation::HasCBufferOffset() const { return m_CBufferOffset != UINT_MAX; }
 unsigned DxilFieldAnnotation::GetCBufferOffset() const { return m_CBufferOffset; }

+ 0 - 39
lib/HLSL/HLModule.cpp

@@ -664,45 +664,6 @@ void HLModule::LoadHLShaderProperties(const MDOperand &MDO) {
   return;
 }
 
-MDNode *HLModule::DxilSamplerToMDNode(const DxilSampler &S) {
-  MDNode *MD = m_pMDHelper->EmitDxilSampler(S);
-  ValueAsMetadata *ResClass =
-      m_pMDHelper->Uint32ToConstMD((unsigned)DXIL::ResourceClass::Sampler);
-
-  return MDNode::get(m_Ctx, {ResClass, MD});
-}
-MDNode *HLModule::DxilSRVToMDNode(const DxilResource &SRV) {
-  MDNode *MD = m_pMDHelper->EmitDxilSRV(SRV);
-  ValueAsMetadata *ResClass =
-      m_pMDHelper->Uint32ToConstMD((unsigned)DXIL::ResourceClass::SRV);
-
-  return MDNode::get(m_Ctx, {ResClass, MD});
-}
-MDNode *HLModule::DxilUAVToMDNode(const DxilResource &UAV) {
-  MDNode *MD = m_pMDHelper->EmitDxilUAV(UAV);
-  ValueAsMetadata *ResClass =
-      m_pMDHelper->Uint32ToConstMD((unsigned)DXIL::ResourceClass::UAV);
-
-  return MDNode::get(m_Ctx, {ResClass, MD});
-}
-MDNode *HLModule::DxilCBufferToMDNode(const DxilCBuffer &CB) {
-  MDNode *MD = m_pMDHelper->EmitDxilCBuffer(CB);
-  ValueAsMetadata *ResClass =
-      m_pMDHelper->Uint32ToConstMD((unsigned)DXIL::ResourceClass::CBuffer);
-
-  return MDNode::get(m_Ctx, {ResClass, MD});
-}
-
-void HLModule::LoadDxilResourceBaseFromMDNode(MDNode *MD, DxilResourceBase &R) {
-  return m_pMDHelper->LoadDxilResourceBaseFromMDNode(MD, R);
-}
-void HLModule::LoadDxilResourceFromMDNode(llvm::MDNode *MD, DxilResource &R) {
-  return m_pMDHelper->LoadDxilResourceFromMDNode(MD, R);
-}
-void HLModule::LoadDxilSamplerFromMDNode(llvm::MDNode *MD, DxilSampler &S) {
-  return m_pMDHelper->LoadDxilSamplerFromMDNode(MD, S);
-}
-
 DxilResourceBase *
 HLModule::AddResourceWithGlobalVariableAndProps(llvm::Constant *GV,
                                                  DxilResourceProperties &RP) {

+ 1 - 1
lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp

@@ -5268,7 +5268,7 @@ void SROA_Parameter_HLSL::flattenArgument(
       flatParamAnnotation.SetCompType(annotation.GetCompType().GetKind());
       flatParamAnnotation.SetMatrixAnnotation(annotation.GetMatrixAnnotation());
       flatParamAnnotation.SetPrecise(annotation.IsPrecise());
-      flatParamAnnotation.SetResourceAttribute(annotation.GetResourceAttribute());
+      flatParamAnnotation.SetResourceProperties(annotation.GetResourceProperties());
 
       // Add debug info.
       if (DDIs.size() && V != Arg) {

+ 1 - 57
tools/clang/lib/CodeGen/CGHLSLMS.cpp

@@ -80,8 +80,6 @@ private:
   llvm::DataLayout dataLayout;
   // decl map to constant id for program
   llvm::DenseMap<HLSLBufferDecl *, uint32_t> constantBufMap;
-  // Map for resource type to resource metadata value.
-  std::unordered_map<llvm::Type *, MDNode*> resMetadataMap;
   // Map from Constant to register bindings.
   llvm::DenseMap<llvm::Constant *,
                  llvm::SmallVector<std::pair<DXIL::ResourceClass, unsigned>, 1>>
@@ -211,7 +209,6 @@ private:
                                      DxilTypeSystem &dxilTypeSys);
   unsigned AddTypeAnnotation(QualType Ty, DxilTypeSystem &dxilTypeSys,
                              unsigned &arrayEltSize);
-  MDNode *GetOrAddResTypeMD(QualType resTy, bool bCreate);
   DxilResourceProperties BuildResourceProperty(QualType resTy);
   void ConstructFieldAttributedAnnotation(DxilFieldAnnotation &fieldAnnotation,
                                           QualType fieldTy,
@@ -671,56 +668,6 @@ static DxilSampler::SamplerKind KeywordToSamplerKind(llvm::StringRef keyword) {
     .Default(DxilSampler::SamplerKind::Invalid);
 }
 
-MDNode *CGMSHLSLRuntime::GetOrAddResTypeMD(QualType resTy, bool bCreate) {
-  const RecordType *RT = resTy->getAs<RecordType>();
-  if (!RT)
-    return nullptr;
-  RecordDecl *RD = RT->getDecl();
-  SourceLocation loc = RD->getLocation();
-
-  hlsl::DxilResourceBase::Class resClass = TypeToClass(resTy);
-  llvm::Type *Ty = CGM.getTypes().ConvertType(resTy);
-  auto it = resMetadataMap.find(Ty);
-  if (!bCreate && it != resMetadataMap.end())
-    return it->second;
-
-  // Save resource type metadata.
-  switch (resClass) {
-  case DXIL::ResourceClass::UAV: {
-    DxilResource UAV;
-    // TODO: save globalcoherent to variable in EmitHLSLBuiltinCallExpr.
-    SetUAVSRV(loc, resClass, &UAV, resTy);
-    // Set global symbol to save type.
-    UAV.SetGlobalSymbol(UndefValue::get(Ty->getPointerTo()));
-    MDNode *MD = m_pHLModule->DxilUAVToMDNode(UAV);
-    resMetadataMap[Ty] = MD;
-    return MD;
-  } break;
-  case DXIL::ResourceClass::SRV: {
-    DxilResource SRV;
-    SetUAVSRV(loc, resClass, &SRV, resTy);
-    // Set global symbol to save type.
-    SRV.SetGlobalSymbol(UndefValue::get(Ty->getPointerTo()));
-    MDNode *MD = m_pHLModule->DxilSRVToMDNode(SRV);
-    resMetadataMap[Ty] = MD;
-    return MD;
-  } break;
-  case DXIL::ResourceClass::Sampler: {
-    DxilSampler S;
-    DxilSampler::SamplerKind kind = KeywordToSamplerKind(RD->getName());
-    S.SetSamplerKind(kind);
-    // Set global symbol to save type.
-    S.SetGlobalSymbol(UndefValue::get(Ty->getPointerTo()));
-    MDNode *MD = m_pHLModule->DxilSamplerToMDNode(S);
-    resMetadataMap[Ty] = MD;
-    return MD;
-  }
-  default:
-    // Skip OutputStream for GS.
-    return nullptr;
-  }
-}
-
 
 namespace {
 MatrixOrientation GetMatrixMajor(QualType Ty, bool bDefaultRowMajor) {
@@ -839,10 +786,7 @@ void CGMSHLSLRuntime::ConstructFieldAttributedAnnotation(
     EltTy = hlsl::GetHLSLVecElementType(Ty);
 
   if (IsHLSLResourceType(Ty)) {
-    // Always create for llvm::Type could be same for different QualType.
-    // TODO: change to DxilProperties.
-    MDNode *MD = GetOrAddResTypeMD(Ty, /*bCreate*/ true);
-    fieldAnnotation.SetResourceAttribute(MD);
+    fieldAnnotation.SetResourceProperties(BuildResourceProperty(Ty));
   }
 
   bool bSNorm = false;

+ 2 - 20
tools/clang/lib/CodeGen/CGHLSLMSFinishCodeGen.cpp

@@ -648,26 +648,8 @@ DxilResourceProperties GetResourcePropsFromIntrinsicObjectArg(
           cast<ConstantInt>(gepIt.getOperand())->getLimitedValue();
 
       DxilFieldAnnotation &fieldAnno = Anno->GetFieldAnnotation(Index);
-      if (fieldAnno.HasResourceAttribute()) {
-        MDNode *resAttrib = fieldAnno.GetResourceAttribute();
-        DxilResourceBase R(DXIL::ResourceClass::Invalid);
-        HLM.LoadDxilResourceBaseFromMDNode(resAttrib, R);
-        switch (R.GetClass()) {
-        case DXIL::ResourceClass::SRV:
-        case DXIL::ResourceClass::UAV: {
-          DxilResource Res;
-          HLM.LoadDxilResourceFromMDNode(resAttrib, Res);
-          RP = resource_helper::loadPropsFromResourceBase(&Res);
-        } break;
-        case DXIL::ResourceClass::Sampler: {
-          DxilSampler Sampler;
-          HLM.LoadDxilSamplerFromMDNode(resAttrib, Sampler);
-          RP = resource_helper::loadPropsFromResourceBase(&Sampler);
-        } break;
-        default:
-          DXASSERT(0, "invalid resource attribute in filed annotation");
-          break;
-        }
+      if (fieldAnno.HasResourceProperties()) {
+        RP = fieldAnno.GetResourceProperties();
         break;
       }
     }

+ 13 - 0
tools/clang/test/HLSLFileCheck/hlsl/resource_binding/resource-in-struct.hlsl

@@ -1,7 +1,20 @@
 // RUN: %dxc -E main -T ps_6_0 %s  | FileCheck %s
+// RUN: %dxc -T lib_6_7 -validator-version 1.7 %s  | FileCheck %s -check-prefixes=CHECKTYPE,CHECKNORP
+// RUN: %dxc -T lib_6_8 %s  | FileCheck %s -check-prefixes=CHECKTYPE,CHECKRP
+// RUN: %dxc -T lib_6_x %s  | FileCheck %s -check-prefixes=CHECKTYPE,CHECKRP
 
 // CHECK: res.Tex1
 
+// Make sure ResourceProperties are emitted.
+// CHECKTYPE: !dx.typeAnnotations = !{![[TyAnn:[0-9]+]]
+// CHECKTYPE: ![[TyAnn]] =
+// CHECKTYPE-SAME: %struct.Resources undef, ![[Resources_Ann:[0-9]+]],
+// CHECKTYPE: ![[Resources_Ann]] = !{i32 16, ![[Tex1_Ann:[0-9]+]],
+// CHECKRP: ![[Tex1_Ann]] = !{i32 6, !"Tex1",
+// CHECKRP-SAME: i32 10, %dx.types.ResourceProperties { i32 2, i32 1033 }
+// CHECKNORP: ![[Tex1_Ann]] = !{i32 6, !"Tex1",
+// CHECKNORP-NOT: %dx.types.ResourceProperties
+
 SamplerState Samp;
 struct Resources
 {