[llvm] 8e19573 - [DirectX] adding support to read/write descriptor table data using obj2yaml/yaml2obj (#138315)

via llvm-commits llvm-commits at lists.llvm.org
Thu May 29 12:21:23 PDT 2025


Author: joaosaffran
Date: 2025-05-29T12:21:20-07:00
New Revision: 8e19573682b6c53aa1df223e80aa46a3ab48cd35

URL: https://github.com/llvm/llvm-project/commit/8e19573682b6c53aa1df223e80aa46a3ab48cd35
DIFF: https://github.com/llvm/llvm-project/commit/8e19573682b6c53aa1df223e80aa46a3ab48cd35.diff

LOG: [DirectX] adding support to read/write descriptor table data using obj2yaml/yaml2obj (#138315)

Closes:
https://github.com/orgs/llvm/projects/4/views/22?sliceBy%5Bvalue%5D=joaosaffran&pane=issue&itemId=97332852&issue=llvm%7Cllvm-project%7C126635

---------

Co-authored-by: joaosaffran <joao.saffran at microsoft.com>

Added: 
    llvm/test/ObjectYAML/DXContainer/RootSignature-DescriptorTable1.0.yaml
    llvm/test/ObjectYAML/DXContainer/RootSignature-DescriptorTable1.1.yaml

Modified: 
    llvm/include/llvm/BinaryFormat/DXContainer.h
    llvm/include/llvm/BinaryFormat/DXContainerConstants.def
    llvm/include/llvm/MC/DXContainerRootSignature.h
    llvm/include/llvm/Object/DXContainer.h
    llvm/include/llvm/ObjectYAML/DXContainerYAML.h
    llvm/lib/MC/DXContainerRootSignature.cpp
    llvm/lib/ObjectYAML/DXContainerEmitter.cpp
    llvm/lib/ObjectYAML/DXContainerYAML.cpp
    llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml
    llvm/unittests/Object/DXContainerTest.cpp
    llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h
index 3494e0fe1a0e9..9bb182b6510d0 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainer.h
+++ b/llvm/include/llvm/BinaryFormat/DXContainer.h
@@ -163,6 +163,11 @@ enum class RootDescriptorFlag : uint32_t {
 #include "DXContainerConstants.def"
 };
 
+#define DESCRIPTOR_RANGE_FLAG(Num, Val) Val = 1ull << Num,
+enum class DescriptorRangeFlag : uint32_t {
+#include "DXContainerConstants.def"
+};
+
 #define ROOT_PARAMETER(Val, Enum) Enum = Val,
 enum class RootParameterType : uint32_t {
 #include "DXContainerConstants.def"
@@ -170,6 +175,13 @@ enum class RootParameterType : uint32_t {
 
 ArrayRef<EnumEntry<RootParameterType>> getRootParameterTypes();
 
+#define DESCRIPTOR_RANGE(Val, Enum) Enum = Val,
+enum class DescriptorRangeType : uint32_t {
+#include "DXContainerConstants.def"
+};
+
+ArrayRef<EnumEntry<DescriptorRangeType>> getDescriptorRangeTypes();
+
 #define ROOT_PARAMETER(Val, Enum)                                              \
   case Val:                                                                    \
     return true;
@@ -588,6 +600,21 @@ static_assert(sizeof(ProgramSignatureElement) == 32,
 
 namespace RTS0 {
 namespace v1 {
+struct DescriptorRange {
+  uint32_t RangeType;
+  uint32_t NumDescriptors;
+  uint32_t BaseShaderRegister;
+  uint32_t RegisterSpace;
+  uint32_t OffsetInDescriptorsFromTableStart;
+  void swapBytes() {
+    sys::swapByteOrder(RangeType);
+    sys::swapByteOrder(NumDescriptors);
+    sys::swapByteOrder(BaseShaderRegister);
+    sys::swapByteOrder(RegisterSpace);
+    sys::swapByteOrder(OffsetInDescriptorsFromTableStart);
+  }
+};
+
 struct RootDescriptor {
   uint32_t ShaderRegister;
   uint32_t RegisterSpace;
@@ -655,6 +682,14 @@ struct RootDescriptor : public v1::RootDescriptor {
     sys::swapByteOrder(Flags);
   }
 };
+
+struct DescriptorRange : public v1::DescriptorRange {
+  uint32_t Flags;
+  void swapBytes() {
+    v1::DescriptorRange::swapBytes();
+    sys::swapByteOrder(Flags);
+  }
+};
 } // namespace v2
 } // namespace RTS0
 

diff  --git a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
index 81d2c54b6e07c..a407dd0e8d2c2 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
+++ b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
@@ -86,8 +86,21 @@ ROOT_DESCRIPTOR_FLAG(3, DATA_STATIC)
 #endif // ROOT_DESCRIPTOR_FLAG
 
 
+// DESCRIPTOR_RANGE_FLAG(bit offset for the flag, name).
+#ifdef DESCRIPTOR_RANGE_FLAG
+
+DESCRIPTOR_RANGE_FLAG(0, NONE)
+DESCRIPTOR_RANGE_FLAG(1, DESCRIPTORS_VOLATILE)
+DESCRIPTOR_RANGE_FLAG(2, DATA_VOLATILE)
+DESCRIPTOR_RANGE_FLAG(3, DATA_STATIC_WHILE_SET_AT_EXECUTE)
+DESCRIPTOR_RANGE_FLAG(4, DATA_STATIC)
+DESCRIPTOR_RANGE_FLAG(16, DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS)
+#undef DESCRIPTOR_RANGE_FLAG
+#endif // DESCRIPTOR_RANGE_FLAG
+
 #ifdef ROOT_PARAMETER
 
+ROOT_PARAMETER(0, DescriptorTable)
 ROOT_PARAMETER(1, Constants32Bit)
 ROOT_PARAMETER(2, CBV)
 ROOT_PARAMETER(3, SRV)

diff  --git a/llvm/include/llvm/MC/DXContainerRootSignature.h b/llvm/include/llvm/MC/DXContainerRootSignature.h
index 5f5919122b3c5..63d7b508d87dd 100644
--- a/llvm/include/llvm/MC/DXContainerRootSignature.h
+++ b/llvm/include/llvm/MC/DXContainerRootSignature.h
@@ -25,11 +25,22 @@ struct RootParameterInfo {
       : Header(Header), Location(Location) {}
 };
 
+struct DescriptorTable {
+  SmallVector<dxbc::RTS0::v2::DescriptorRange> Ranges;
+  SmallVector<dxbc::RTS0::v2::DescriptorRange>::const_iterator begin() const {
+    return Ranges.begin();
+  }
+  SmallVector<dxbc::RTS0::v2::DescriptorRange>::const_iterator end() const {
+    return Ranges.end();
+  }
+};
+
 struct RootParametersContainer {
   SmallVector<RootParameterInfo> ParametersInfo;
 
   SmallVector<dxbc::RTS0::v1::RootConstants> Constants;
   SmallVector<dxbc::RTS0::v2::RootDescriptor> Descriptors;
+  SmallVector<DescriptorTable> Tables;
 
   void addInfo(dxbc::RTS0::v1::RootParameterHeader Header, size_t Location) {
     ParametersInfo.push_back(RootParameterInfo(Header, Location));
@@ -51,6 +62,12 @@ struct RootParametersContainer {
     Descriptors.push_back(Descriptor);
   }
 
+  void addParameter(dxbc::RTS0::v1::RootParameterHeader Header,
+                    DescriptorTable Table) {
+    addInfo(Header, Tables.size());
+    Tables.push_back(Table);
+  }
+
   const std::pair<uint32_t, uint32_t>
   getTypeAndLocForParameter(uint32_t Location) const {
     const RootParameterInfo &Info = ParametersInfo[Location];
@@ -70,6 +87,10 @@ struct RootParametersContainer {
     return Descriptors[Index];
   }
 
+  const DescriptorTable &getDescriptorTable(size_t Index) const {
+    return Tables[Index];
+  }
+
   size_t size() const { return ParametersInfo.size(); }
 
   SmallVector<RootParameterInfo>::const_iterator begin() const {

diff  --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index 37cd5ca7dc935..ef981a156e87d 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -20,6 +20,7 @@
 #include "llvm/ADT/Twine.h"
 #include "llvm/BinaryFormat/DXContainer.h"
 #include "llvm/Object/Error.h"
+#include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/MemoryBufferRef.h"
 #include "llvm/TargetParser/Triple.h"
@@ -177,6 +178,50 @@ struct RootDescriptorView : RootParameterView {
   }
 };
 
+struct DescriptorTable {
+  uint32_t NumRanges;
+  uint32_t RangesOffset;
+  ViewArray<dxbc::RTS0::v2::DescriptorRange> Ranges;
+
+  typename ViewArray<dxbc::RTS0::v2::DescriptorRange>::iterator begin() const {
+    return Ranges.begin();
+  }
+
+  typename ViewArray<dxbc::RTS0::v2::DescriptorRange>::iterator end() const {
+    return Ranges.end();
+  }
+};
+
+struct DescriptorTableView : RootParameterView {
+  static bool classof(const RootParameterView *V) {
+    return (V->Header.ParameterType ==
+            llvm::to_underlying(dxbc::RootParameterType::DescriptorTable));
+  }
+
+  // Define a type alias to access the template parameter from inside classof
+  llvm::Expected<DescriptorTable> read(uint32_t Version) {
+    const char *Current = ParamData.begin();
+    DescriptorTable Table;
+
+    Table.NumRanges =
+        support::endian::read<uint32_t, llvm::endianness::little>(Current);
+    Current += sizeof(uint32_t);
+
+    Table.RangesOffset =
+        support::endian::read<uint32_t, llvm::endianness::little>(Current);
+    Current += sizeof(uint32_t);
+
+    size_t RangeSize = sizeof(dxbc::RTS0::v1::DescriptorRange);
+    if (Version > 1)
+      RangeSize = sizeof(dxbc::RTS0::v2::DescriptorRange);
+
+    Table.Ranges.Stride = RangeSize;
+    Table.Ranges.Data =
+        ParamData.substr(2 * sizeof(uint32_t), Table.NumRanges * RangeSize);
+    return Table;
+  }
+};
+
 static Error parseFailed(const Twine &Msg) {
   return make_error<GenericBinaryError>(Msg.str(), object_error::parse_failed);
 }
@@ -213,6 +258,9 @@ class RootSignature {
   llvm::Expected<RootParameterView>
   getParameter(const dxbc::RTS0::v1::RootParameterHeader &Header) const {
     size_t DataSize;
+    size_t EndOfSectionByte = getNumStaticSamplers() == 0
+                                  ? PartData.size()
+                                  : getStaticSamplersOffset();
 
     if (!dxbc::isValidParameterType(Header.ParameterType))
       return parseFailed("invalid parameter type");
@@ -229,11 +277,23 @@ class RootSignature {
       else
         DataSize = sizeof(dxbc::RTS0::v2::RootDescriptor);
       break;
-    }
-    size_t EndOfSectionByte = getNumStaticSamplers() == 0
-                                  ? PartData.size()
-                                  : getStaticSamplersOffset();
+    case dxbc::RootParameterType::DescriptorTable:
+      if (Header.ParameterOffset + sizeof(uint32_t) > EndOfSectionByte)
+        return parseFailed("Reading structure out of file bounds");
 
+      uint32_t NumRanges =
+          support::endian::read<uint32_t, llvm::endianness::little>(
+              PartData.begin() + Header.ParameterOffset);
+      if (Version == 1)
+        DataSize = sizeof(dxbc::RTS0::v1::DescriptorRange) * NumRanges;
+      else
+        DataSize = sizeof(dxbc::RTS0::v2::DescriptorRange) * NumRanges;
+
+      // 4 bytes for the number of ranges in table and
+      // 4 bytes for the ranges offset
+      DataSize += 2 * sizeof(uint32_t);
+      break;
+    }
     if (Header.ParameterOffset + DataSize > EndOfSectionByte)
       return parseFailed("Reading structure out of file bounds");
 

diff  --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
index 3af1da552cc7a..33327e5a2de39 100644
--- a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
@@ -90,6 +90,25 @@ struct RootDescriptorYaml {
 #include "llvm/BinaryFormat/DXContainerConstants.def"
 };
 
+struct DescriptorRangeYaml {
+  uint32_t RangeType;
+  uint32_t NumDescriptors;
+  uint32_t BaseShaderRegister;
+  uint32_t RegisterSpace;
+  uint32_t OffsetInDescriptorsFromTableStart;
+
+  uint32_t getEncodedFlags() const;
+
+#define DESCRIPTOR_RANGE_FLAG(Num, Val) bool Val = false;
+#include "llvm/BinaryFormat/DXContainerConstants.def"
+};
+
+struct DescriptorTableYaml {
+  uint32_t NumRanges;
+  uint32_t RangesOffset;
+  SmallVector<DescriptorRangeYaml> Ranges;
+};
+
 struct RootParameterHeaderYaml {
   uint32_t Type;
   uint32_t Visibility;
@@ -113,6 +132,7 @@ struct RootParameterYamlDesc {
 
   SmallVector<RootConstantsYaml> Constants;
   SmallVector<RootDescriptorYaml> Descriptors;
+  SmallVector<DescriptorTableYaml> Tables;
 
   template <typename T>
   T &getOrInsertImpl(RootParameterLocationYaml &ParamDesc,
@@ -134,6 +154,10 @@ struct RootParameterYamlDesc {
     return getOrInsertImpl(ParamDesc, Descriptors);
   }
 
+  DescriptorTableYaml &getOrInsertTable(RootParameterLocationYaml &ParamDesc) {
+    return getOrInsertImpl(ParamDesc, Tables);
+  }
+
   void insertLocation(RootParameterLocationYaml &Location) {
     Locations.push_back(Location);
   }
@@ -263,6 +287,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::SignatureElement)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::PSVInfo::MaskVector)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::SignatureParameter)
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::RootParameterLocationYaml)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::DescriptorRangeYaml)
 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::SemanticKind)
 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::ComponentType)
 LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::InterpolationMode)
@@ -351,6 +376,14 @@ template <> struct MappingTraits<llvm::DXContainerYAML::RootDescriptorYaml> {
   static void mapping(IO &IO, llvm::DXContainerYAML::RootDescriptorYaml &D);
 };
 
+template <> struct MappingTraits<llvm::DXContainerYAML::DescriptorTableYaml> {
+  static void mapping(IO &IO, llvm::DXContainerYAML::DescriptorTableYaml &D);
+};
+
+template <> struct MappingTraits<llvm::DXContainerYAML::DescriptorRangeYaml> {
+  static void mapping(IO &IO, llvm::DXContainerYAML::DescriptorRangeYaml &D);
+};
+
 } // namespace yaml
 
 } // namespace llvm

diff  --git a/llvm/lib/MC/DXContainerRootSignature.cpp b/llvm/lib/MC/DXContainerRootSignature.cpp
index 3a4bd8321eb95..01531b4d4dbc9 100644
--- a/llvm/lib/MC/DXContainerRootSignature.cpp
+++ b/llvm/lib/MC/DXContainerRootSignature.cpp
@@ -47,6 +47,18 @@ size_t RootSignatureDesc::getSize() const {
         Size += sizeof(dxbc::RTS0::v2::RootDescriptor);
 
       break;
+    case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable):
+      const DescriptorTable &Table =
+          ParametersContainer.getDescriptorTable(I.Location);
+
+      // 4 bytes for the number of ranges in table and
+      // 4 bytes for the ranges offset
+      Size += 2 * sizeof(uint32_t);
+      if (Version == 1)
+        Size += sizeof(dxbc::RTS0::v1::DescriptorRange) * Table.Ranges.size();
+      else
+        Size += sizeof(dxbc::RTS0::v2::DescriptorRange) * Table.Ranges.size();
+      break;
     }
   }
   return Size;
@@ -106,6 +118,27 @@ void RootSignatureDesc::write(raw_ostream &OS) const {
         support::endian::write(BOS, Descriptor.Flags, llvm::endianness::little);
       break;
     }
+    case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {
+      const DescriptorTable &Table =
+          ParametersContainer.getDescriptorTable(Loc);
+      support::endian::write(BOS, (uint32_t)Table.Ranges.size(),
+                             llvm::endianness::little);
+      rewriteOffsetToCurrentByte(BOS, writePlaceholder(BOS));
+      for (const auto &Range : Table) {
+        support::endian::write(BOS, Range.RangeType, llvm::endianness::little);
+        support::endian::write(BOS, Range.NumDescriptors,
+                               llvm::endianness::little);
+        support::endian::write(BOS, Range.BaseShaderRegister,
+                               llvm::endianness::little);
+        support::endian::write(BOS, Range.RegisterSpace,
+                               llvm::endianness::little);
+        support::endian::write(BOS, Range.OffsetInDescriptorsFromTableStart,
+                               llvm::endianness::little);
+        if (Version > 1)
+          support::endian::write(BOS, Range.Flags, llvm::endianness::little);
+      }
+      break;
+    }
     }
   }
   assert(Storage.size() == getSize());

diff  --git a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
index d5fdf0bda68c3..233a79ea20fe9 100644
--- a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
@@ -303,6 +303,26 @@ void DXContainerWriter::writeParts(raw_ostream &OS) {
           RS.ParametersContainer.addParameter(Header, Descriptor);
           break;
         }
+        case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {
+          const DXContainerYAML::DescriptorTableYaml &TableYaml =
+              P.RootSignature->Parameters.getOrInsertTable(L);
+          mcdxbc::DescriptorTable Table;
+          for (const auto &R : TableYaml.Ranges) {
+
+            dxbc::RTS0::v2::DescriptorRange Range;
+            Range.RangeType = R.RangeType;
+            Range.NumDescriptors = R.NumDescriptors;
+            Range.BaseShaderRegister = R.BaseShaderRegister;
+            Range.RegisterSpace = R.RegisterSpace;
+            Range.OffsetInDescriptorsFromTableStart =
+                R.OffsetInDescriptorsFromTableStart;
+            if (RS.Version > 1)
+              Range.Flags = R.getEncodedFlags();
+            Table.Ranges.push_back(Range);
+          }
+          RS.ParametersContainer.addParameter(Header, Table);
+          break;
+        }
         default:
           // Handling invalid parameter type edge case. We intentionally let
           // obj2yaml/yaml2obj parse and emit invalid dxcontainer data, in order

diff  --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 22561ec0ac9b9..9af4a93b30644 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -105,6 +105,38 @@ DXContainerYAML::RootSignatureYamlDesc::create(
        llvm::to_underlying(dxbc::RootDescriptorFlag::Val)) > 0;
 #include "llvm/BinaryFormat/DXContainerConstants.def"
       }
+    } else if (auto *DTV =
+                   dyn_cast<object::DirectX::DescriptorTableView>(&ParamView)) {
+      llvm::Expected<object::DirectX::DescriptorTable> TableOrErr =
+          DTV->read(Version);
+      if (Error E = TableOrErr.takeError())
+        return std::move(E);
+      auto Table = *TableOrErr;
+      RootParameterLocationYaml Location(Header);
+      DescriptorTableYaml &TableYaml =
+          RootSigDesc.Parameters.getOrInsertTable(Location);
+      RootSigDesc.Parameters.insertLocation(Location);
+
+      TableYaml.NumRanges = Table.NumRanges;
+      TableYaml.RangesOffset = Table.RangesOffset;
+
+      for (const auto &R : Table) {
+        DescriptorRangeYaml NewR;
+
+        NewR.OffsetInDescriptorsFromTableStart =
+            R.OffsetInDescriptorsFromTableStart;
+        NewR.NumDescriptors = R.NumDescriptors;
+        NewR.BaseShaderRegister = R.BaseShaderRegister;
+        NewR.RegisterSpace = R.RegisterSpace;
+        NewR.RangeType = R.RangeType;
+        if (Version > 1) {
+#define DESCRIPTOR_RANGE_FLAG(Num, Val)                                        \
+  NewR.Val =                                                                   \
+      (R.Flags & llvm::to_underlying(dxbc::DescriptorRangeFlag::Val)) > 0;
+#include "llvm/BinaryFormat/DXContainerConstants.def"
+        }
+        TableYaml.Ranges.push_back(NewR);
+      }
     }
   }
 #define ROOT_ELEMENT_FLAG(Num, Val)                                            \
@@ -132,6 +164,15 @@ uint32_t DXContainerYAML::RootSignatureYamlDesc::getEncodedFlags() {
   return Flag;
 }
 
+uint32_t DXContainerYAML::DescriptorRangeYaml::getEncodedFlags() const {
+  uint64_t Flag = 0;
+#define DESCRIPTOR_RANGE_FLAG(Num, Val)                                        \
+  if (Val)                                                                     \
+    Flag |= (uint32_t)dxbc::DescriptorRangeFlag::Val;
+#include "llvm/BinaryFormat/DXContainerConstants.def"
+  return Flag;
+}
+
 uint64_t DXContainerYAML::ShaderFeatureFlags::getEncodedFlags() {
   uint64_t Flag = 0;
 #define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str)                      \
@@ -303,6 +344,37 @@ void MappingTraits<DXContainerYAML::RootSignatureYamlDesc>::mapping(
 #include "llvm/BinaryFormat/DXContainerConstants.def"
 }
 
+void MappingTraits<llvm::DXContainerYAML::DescriptorRangeYaml>::mapping(
+    IO &IO, llvm::DXContainerYAML::DescriptorRangeYaml &R) {
+  IO.mapRequired("RangeType", R.RangeType);
+  // handling the edge case where NumDescriptors might be -1
+  if (IO.outputting()) {
+    if (R.NumDescriptors == UINT_MAX) {
+      int32_t NegOne = -1;
+      IO.mapRequired("NumDescriptors", NegOne);
+    } else
+      IO.mapRequired("NumDescriptors", R.NumDescriptors);
+  } else {
+    int32_t TmpNumDesc = 0;
+    IO.mapRequired("NumDescriptors", TmpNumDesc);
+    R.NumDescriptors = static_cast<uint32_t>(TmpNumDesc);
+  }
+
+  IO.mapRequired("BaseShaderRegister", R.BaseShaderRegister);
+  IO.mapRequired("RegisterSpace", R.RegisterSpace);
+  IO.mapRequired("OffsetInDescriptorsFromTableStart",
+                 R.OffsetInDescriptorsFromTableStart);
+#define DESCRIPTOR_RANGE_FLAG(Num, Val) IO.mapOptional(#Val, R.Val, false);
+#include "llvm/BinaryFormat/DXContainerConstants.def"
+}
+
+void MappingTraits<llvm::DXContainerYAML::DescriptorTableYaml>::mapping(
+    IO &IO, llvm::DXContainerYAML::DescriptorTableYaml &T) {
+  IO.mapRequired("NumRanges", T.NumRanges);
+  IO.mapOptional("RangesOffset", T.RangesOffset);
+  IO.mapRequired("Ranges", T.Ranges);
+}
+
 void MappingContextTraits<DXContainerYAML::RootParameterLocationYaml,
                           DXContainerYAML::RootSignatureYamlDesc>::
     mapping(IO &IO, DXContainerYAML::RootParameterLocationYaml &L,
@@ -325,6 +397,12 @@ void MappingContextTraits<DXContainerYAML::RootParameterLocationYaml,
     IO.mapRequired("Descriptor", Descriptor);
     break;
   }
+  case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {
+    DXContainerYAML::DescriptorTableYaml &Table =
+        S.Parameters.getOrInsertTable(L);
+    IO.mapRequired("Table", Table);
+    break;
+  }
   }
 }
 

diff  --git a/llvm/test/ObjectYAML/DXContainer/RootSignature-DescriptorTable1.0.yaml b/llvm/test/ObjectYAML/DXContainer/RootSignature-DescriptorTable1.0.yaml
new file mode 100644
index 0000000000000..0441bb7a256b1
--- /dev/null
+++ b/llvm/test/ObjectYAML/DXContainer/RootSignature-DescriptorTable1.0.yaml
@@ -0,0 +1,57 @@
+# RUN: yaml2obj %s | obj2yaml | FileCheck %s
+
+--- !dxcontainer
+Header:
+      Hash:            [ 0x32, 0x9A, 0x53, 0xD8, 0xEC, 0xBE, 0x35, 0x6F, 0x5, 
+                        0x39, 0xE1, 0xFE, 0x31, 0x20, 0xF0, 0xC1 ]
+      Version:
+        Major:           1
+        Minor:           0
+      FileSize:        133
+      PartCount:       1
+      PartOffsets:     [ 36 ]
+Parts:
+- Name:            RTS0
+  Size:            89
+  RootSignature:
+    Version: 1
+    NumRootParameters: 1
+    RootParametersOffset: 24
+    NumStaticSamplers: 0
+    StaticSamplersOffset: 60
+    Parameters:         
+    - ParameterType: 0 # SRV
+      ShaderVisibility: 3 # Domain
+      Table:
+        NumRanges: 1
+        Ranges:
+          - RangeType: 0
+            NumDescriptors: -1
+            BaseShaderRegister: 42
+            RegisterSpace: 43
+            OffsetInDescriptorsFromTableStart: 41
+    AllowInputAssemblerInputLayout: true
+    DenyGeometryShaderRootAccess: true
+
+# CHECK: - Name:            RTS0
+# CHECK-NEXT:   Size:            89
+# CHECK-NEXT:   RootSignature:
+# CHECK-NEXT:     Version: 1
+# CHECK-NEXT:     NumRootParameters: 1
+# CHECK-NEXT:     RootParametersOffset: 24
+# CHECK-NEXT:     NumStaticSamplers: 0
+# CHECK-NEXT:     StaticSamplersOffset: 60
+# CHECK-NEXT:     Parameters:         
+# CHECK-NEXT:     - ParameterType: 0
+# CHECK-NEXT:       ShaderVisibility: 3
+# CHECK-NEXT:       Table:
+# CHECK-NEXT:         NumRanges: 1
+# CHECK-NEXT:         RangesOffset: 44
+# CHECK-NEXT:         Ranges:
+# CHECK-NEXT:           - RangeType: 0
+# CHECK-NEXT:             NumDescriptors: -1
+# CHECK-NEXT:             BaseShaderRegister: 42
+# CHECK-NEXT:             RegisterSpace: 43
+# CHECK-NEXT:             OffsetInDescriptorsFromTableStart: 41
+# CHECK-NEXT:     AllowInputAssemblerInputLayout: true
+# CHECK-NEXT:     DenyGeometryShaderRootAccess: true

diff  --git a/llvm/test/ObjectYAML/DXContainer/RootSignature-DescriptorTable1.1.yaml b/llvm/test/ObjectYAML/DXContainer/RootSignature-DescriptorTable1.1.yaml
new file mode 100644
index 0000000000000..d06be5e181418
--- /dev/null
+++ b/llvm/test/ObjectYAML/DXContainer/RootSignature-DescriptorTable1.1.yaml
@@ -0,0 +1,59 @@
+# RUN: yaml2obj %s | obj2yaml | FileCheck %s
+
+--- !dxcontainer
+Header:
+      Hash:            [ 0x32, 0x9A, 0x53, 0xD8, 0xEC, 0xBE, 0x35, 0x6F, 0x5, 
+                        0x39, 0xE1, 0xFE, 0x31, 0x20, 0xF0, 0xC1 ]
+      Version:
+        Major:           1
+        Minor:           0
+      FileSize:        133
+      PartCount:       1
+      PartOffsets:     [ 36 ]
+Parts:
+- Name:            RTS0
+  Size:            89
+  RootSignature:
+    Version: 2
+    NumRootParameters: 1
+    RootParametersOffset: 24
+    NumStaticSamplers: 0
+    StaticSamplersOffset: 60
+    Parameters:         
+    - ParameterType: 0 # SRV
+      ShaderVisibility: 3 # Domain
+      Table:
+        NumRanges: 1
+        Ranges:
+          - RangeType: 0
+            NumDescriptors: -1
+            BaseShaderRegister: 42
+            RegisterSpace: 43
+            OffsetInDescriptorsFromTableStart: 41
+            DATA_STATIC_WHILE_SET_AT_EXECUTE: true
+    AllowInputAssemblerInputLayout: true
+    DenyGeometryShaderRootAccess: true
+
+# CHECK: - Name:            RTS0
+# CHECK-NEXT:     Size:            89
+# CHECK-NEXT:     RootSignature:
+# CHECK-NEXT:       Version:         2
+# CHECK-NEXT:       NumRootParameters: 1
+# CHECK-NEXT:       RootParametersOffset: 24
+# CHECK-NEXT:       NumStaticSamplers: 0
+# CHECK-NEXT:       StaticSamplersOffset: 60
+# CHECK-NEXT:       Parameters:
+# CHECK-NEXT:         - ParameterType:   0
+# CHECK-NEXT:           ShaderVisibility: 3
+# CHECK-NEXT:           Table:
+# CHECK-NEXT:             NumRanges:       1
+# CHECK-NEXT:             RangesOffset:    44
+# CHECK-NEXT:             Ranges:
+# CHECK-NEXT:               - RangeType:       0
+# CHECK-NEXT:                 NumDescriptors:  -1
+# CHECK-NEXT:                 BaseShaderRegister: 42
+# CHECK-NEXT:                 RegisterSpace:   43
+# CHECK-NEXT:                 OffsetInDescriptorsFromTableStart: 41
+# CHECK-NEXT:                 DATA_STATIC_WHILE_SET_AT_EXECUTE: true
+# CHECK-NEXT:       AllowInputAssemblerInputLayout: true
+# CHECK-NEXT:       DenyGeometryShaderRootAccess: true

diff  --git a/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml b/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml
index debb459c3944e..947fc096a9207 100644
--- a/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml
+++ b/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml
@@ -11,7 +11,7 @@ Header:
   PartOffsets:     [ 60 ]
 Parts:
   - Name:            RTS0
-    Size:            96
+    Size:            200
     RootSignature:
       Version: 2
       NumRootParameters: 3
@@ -37,14 +37,25 @@ Parts:
           ShaderRegister: 31
           RegisterSpace: 32
           DATA_STATIC_WHILE_SET_AT_EXECUTE: true
+      - ParameterType: 0 # SRV
+        ShaderVisibility: 3 # Domain
+        Table:
+          NumRanges: 1
+          Ranges:
+            - RangeType: 0
+              NumDescriptors: -1
+              BaseShaderRegister: 42
+              RegisterSpace: 43
+              OffsetInDescriptorsFromTableStart: 41
+              DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS: true
       AllowInputAssemblerInputLayout: true
       DenyGeometryShaderRootAccess: true
 
 # CHECK:  - Name:            RTS0
-# CHECK-NEXT:    Size:            96
+# CHECK-NEXT:    Size:            200
 # CHECK-NEXT:    RootSignature:
 # CHECK-NEXT:      Version:         2
-# CHECK-NEXT:      NumRootParameters: 3
+# CHECK-NEXT:      NumRootParameters: 4
 # CHECK-NEXT:      RootParametersOffset: 24
 # CHECK-NEXT:      NumStaticSamplers: 0
 # CHECK-NEXT:      StaticSamplersOffset: 60
@@ -67,5 +78,17 @@ Parts:
 # CHECK-NEXT:            RegisterSpace:   32
 # CHECK-NEXT:            ShaderRegister:  31
 # CHECK-NEXT:            DATA_STATIC_WHILE_SET_AT_EXECUTE: true
+# CHECK-NEXT:        - ParameterType:   0
+# CHECK-NEXT:          ShaderVisibility: 3
+# CHECK-NEXT:          Table:
+# CHECK-NEXT:            NumRanges:       1
+# CHECK-NEXT:            RangesOffset:    116
+# CHECK-NEXT:            Ranges:
+# CHECK-NEXT:              - RangeType:       0
+# CHECK-NEXT:                NumDescriptors:  -1
+# CHECK-NEXT:                BaseShaderRegister: 42
+# CHECK-NEXT:                RegisterSpace:   43
+# CHECK-NEXT:                OffsetInDescriptorsFromTableStart: 41
+# CHECK-NEXT:                DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS: true
 # CHECK-NEXT:      AllowInputAssemblerInputLayout: true
 # CHECK-NEXT:      DenyGeometryShaderRootAccess: true

diff  --git a/llvm/unittests/Object/DXContainerTest.cpp b/llvm/unittests/Object/DXContainerTest.cpp
index 72f860a5039ff..71503729b5f34 100644
--- a/llvm/unittests/Object/DXContainerTest.cpp
+++ b/llvm/unittests/Object/DXContainerTest.cpp
@@ -1050,3 +1050,108 @@ TEST(RootSignature, ParseRootDescriptor) {
     ASSERT_EQ(Descriptor->Flags, 4u);
   }
 }
+
+TEST(RootSignature, ParseDescriptorTable) {
+  {
+    uint8_t Buffer[] = {
+        0x44, 0x58, 0x42, 0x43, 0x32, 0x9a, 0x53, 0xd8, 0xec, 0xbe, 0x35, 0x6f,
+        0x05, 0x39, 0xe1, 0xfe, 0x31, 0x20, 0xf0, 0xc1, 0x01, 0x00, 0x00, 0x00,
+        0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+        0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+        0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x03, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+        0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+        0x2a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00};
+    DXContainer C =
+        llvm::cantFail(DXContainer::create(getMemoryBuffer<133>(Buffer)));
+
+    auto MaybeRS = C.getRootSignature();
+    ASSERT_TRUE(MaybeRS.has_value());
+    const auto &RS = MaybeRS.value();
+    ASSERT_EQ(RS.getVersion(), 2u);
+    ASSERT_EQ(RS.getNumParameters(), 1u);
+    ASSERT_EQ(RS.getRootParametersOffset(), 24u);
+    ASSERT_EQ(RS.getNumStaticSamplers(), 0u);
+    ASSERT_EQ(RS.getStaticSamplersOffset(), 60u);
+    ASSERT_EQ(RS.getFlags(), 17u);
+
+    auto RootParam = *RS.param_headers().begin();
+    ASSERT_EQ((unsigned)RootParam.ParameterType, 0u);
+    ASSERT_EQ((unsigned)RootParam.ShaderVisibility, 3u);
+    auto ParamView = RS.getParameter(RootParam);
+    ASSERT_THAT_ERROR(ParamView.takeError(), Succeeded());
+
+    auto *DescriptorTableView =
+        dyn_cast<DirectX::DescriptorTableView>(&*ParamView);
+    ASSERT_TRUE(DescriptorTableView != nullptr);
+    auto Table = DescriptorTableView->read(2);
+
+    ASSERT_THAT_ERROR(Table.takeError(), Succeeded());
+
+    ASSERT_EQ(Table->NumRanges, 1u);
+
+    auto Range = *Table->begin();
+
+    ASSERT_EQ(Range.RangeType, 0u);
+    ASSERT_EQ(Range.NumDescriptors, -1u);
+    ASSERT_EQ(Range.BaseShaderRegister, 42u);
+    ASSERT_EQ(Range.RegisterSpace, 43u);
+    ASSERT_EQ(Range.OffsetInDescriptorsFromTableStart, 41u);
+    ASSERT_EQ(Range.Flags, 65536u);
+  }
+
+  {
+    uint8_t Buffer[] = {
+        0x44, 0x58, 0x42, 0x43, 0x32, 0x9a, 0x53, 0xd8, 0xec, 0xbe, 0x35, 0x6f,
+        0x05, 0x39, 0xe1, 0xfe, 0x31, 0x20, 0xf0, 0xc1, 0x01, 0x00, 0x00, 0x00,
+        0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+        0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+        0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x03, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+        0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+        0x2a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00};
+    DXContainer C =
+        llvm::cantFail(DXContainer::create(getMemoryBuffer<133>(Buffer)));
+
+    auto MaybeRS = C.getRootSignature();
+    ASSERT_TRUE(MaybeRS.has_value());
+    const auto &RS = MaybeRS.value();
+    ASSERT_EQ(RS.getVersion(), 1u);
+    ASSERT_EQ(RS.getNumParameters(), 1u);
+    ASSERT_EQ(RS.getRootParametersOffset(), 24u);
+    ASSERT_EQ(RS.getNumStaticSamplers(), 0u);
+    ASSERT_EQ(RS.getStaticSamplersOffset(), 60u);
+    ASSERT_EQ(RS.getFlags(), 17u);
+
+    auto RootParam = *RS.param_headers().begin();
+    ASSERT_EQ((unsigned)RootParam.ParameterType, 0u);
+    ASSERT_EQ((unsigned)RootParam.ShaderVisibility, 3u);
+    auto ParamView = RS.getParameter(RootParam);
+    ASSERT_THAT_ERROR(ParamView.takeError(), Succeeded());
+
+    auto *DescriptorTableView =
+        dyn_cast<DirectX::DescriptorTableView>(&*ParamView);
+    ASSERT_TRUE(DescriptorTableView != nullptr);
+    auto Table = DescriptorTableView->read(1);
+
+    ASSERT_THAT_ERROR(Table.takeError(), Succeeded());
+
+    ASSERT_EQ(Table->NumRanges, 1u);
+
+    auto Range = *Table->begin();
+
+    ASSERT_EQ(Range.RangeType, 0u);
+    ASSERT_EQ(Range.NumDescriptors, -1u);
+    ASSERT_EQ(Range.BaseShaderRegister, 42u);
+    ASSERT_EQ(Range.RegisterSpace, 43u);
+    ASSERT_EQ(Range.OffsetInDescriptorsFromTableStart, 41u);
+  }
+}

diff  --git a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
index b6a5cee24b29d..9215b609a485a 100644
--- a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
+++ b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
@@ -354,3 +354,116 @@ TEST(RootSignature, ParseRootDescriptorsV11) {
   EXPECT_EQ(Storage.size(), 133u);
   EXPECT_TRUE(memcmp(Buffer, Storage.data(), 133u) == 0);
 }
+
+TEST(RootSignature, ParseDescriptorTableV10) {
+  SmallString<128> Storage;
+
+  // First read a fully explicit yaml with all sizes and offsets provided
+  ASSERT_TRUE(convert(Storage, R"(--- !dxcontainer
+  Header:
+      Hash:            [ 0x32, 0x9A, 0x53, 0xD8, 0xEC, 0xBE, 0x35, 0x6F, 0x5, 
+                        0x39, 0xE1, 0xFE, 0x31, 0x20, 0xF0, 0xC1 ]
+      Version:
+        Major:           1
+        Minor:           0
+      FileSize:        133
+      PartCount:       1
+      PartOffsets:     [ 36 ]
+  Parts:
+  - Name:            RTS0
+    Size:            89
+    RootSignature:
+      Version: 1
+      NumRootParameters: 1
+      RootParametersOffset: 24
+      NumStaticSamplers: 0
+      StaticSamplersOffset: 60
+      Parameters:         
+      - ParameterType: 0 # SRV
+        ShaderVisibility: 3 # Domain
+        Table:
+          NumRanges: 1
+          Ranges:
+            - RangeType: 0
+              NumDescriptors: 41
+              BaseShaderRegister: 42
+              RegisterSpace: 43
+              OffsetInDescriptorsFromTableStart: 44
+      AllowInputAssemblerInputLayout: true
+      DenyGeometryShaderRootAccess: true
+    )"));
+
+  uint8_t Buffer[] = {
+      0x44, 0x58, 0x42, 0x43, 0x32, 0x9a, 0x53, 0xd8, 0xec, 0xbe, 0x35, 0x6f,
+      0x05, 0x39, 0xe1, 0xfe, 0x31, 0x20, 0xf0, 0xc1, 0x01, 0x00, 0x00, 0x00,
+      0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+      0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+      0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x03, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+      0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
+      0x2a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00};
+
+  EXPECT_EQ(Storage.size(), 133u);
+  EXPECT_TRUE(memcmp(Buffer, Storage.data(), 133u) == 0);
+}
+
+TEST(RootSignature, ParseDescriptorTableV11) {
+  SmallString<128> Storage;
+
+  // First read a fully explicit yaml with all sizes and offsets provided
+  ASSERT_TRUE(convert(Storage, R"(--- !dxcontainer
+  Header:
+      Hash:            [ 0x32, 0x9A, 0x53, 0xD8, 0xEC, 0xBE, 0x35, 0x6F, 0x5, 
+                        0x39, 0xE1, 0xFE, 0x31, 0x20, 0xF0, 0xC1 ]
+      Version:
+        Major:           1
+        Minor:           0
+      FileSize:        133
+      PartCount:       1
+      PartOffsets:     [ 36 ]
+  Parts:
+  - Name:            RTS0
+    Size:            89
+    RootSignature:
+      Version: 2
+      NumRootParameters: 1
+      RootParametersOffset: 24
+      NumStaticSamplers: 0
+      StaticSamplersOffset: 60
+      Parameters:         
+      - ParameterType: 0 # Descriptor Table
+        ShaderVisibility: 3 # Domain
+        Table:
+          NumRanges: 1
+          Ranges:
+            - RangeType: 0
+              NumDescriptors: -1
+              BaseShaderRegister: 42
+              RegisterSpace: 43
+              OffsetInDescriptorsFromTableStart: 41
+              DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS: true
+      AllowInputAssemblerInputLayout: true
+      DenyGeometryShaderRootAccess: true
+    )"));
+
+  uint8_t Buffer[] = {
+      0x44, 0x58, 0x42, 0x43, 0x32, 0x9a, 0x53, 0xd8, 0xec, 0xbe, 0x35, 0x6f,
+      0x05, 0x39, 0xe1, 0xfe, 0x31, 0x20, 0xf0, 0xc1, 0x01, 0x00, 0x00, 0x00,
+      0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+      0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+      0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x03, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+      0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+      0x2a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00};
+
+  EXPECT_EQ(Storage.size(), 133u);
+  EXPECT_TRUE(memcmp(Buffer, Storage.data(), 133u) == 0);
+}


        


More information about the llvm-commits mailing list