Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DirectX] Add resource handling to the DXIL pretty printer #104448

Conversation

bogner
Copy link
Contributor

@bogner bogner commented Aug 15, 2024

Handle target extension type resources when printing resources to textual IR.

bogner added 2 commits August 15, 2024 16:51
Created using spr 1.3.5-bogner

[skip ci]
Created using spr 1.3.5-bogner
@llvmbot
Copy link
Member

llvmbot commented Aug 15, 2024

@llvm/pr-subscribers-backend-directx

@llvm/pr-subscribers-llvm-analysis

Author: Justin Bogner (bogner)

Changes

Handle target extension type resources when printing resources to textual IR.


Full diff: https://github.com/llvm/llvm-project/pull/104448.diff

5 Files Affected:

  • (modified) llvm/include/llvm/Analysis/DXILResource.h (+15-1)
  • (modified) llvm/lib/Target/DirectX/DXILOpLowering.cpp (+2-2)
  • (modified) llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp (+222-5)
  • (modified) llvm/test/CodeGen/DirectX/CreateHandle.ll (+9)
  • (modified) llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll (+9)
diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h
index 2ed508b28a908..faee9f5dac1b4 100644
--- a/llvm/include/llvm/Analysis/DXILResource.h
+++ b/llvm/include/llvm/Analysis/DXILResource.h
@@ -142,12 +142,17 @@ class ResourceInfo {
     Binding.LowerBound = LowerBound;
     Binding.Size = Size;
   }
+  const ResourceBinding &getBinding() const { return Binding; }
   void setUAV(bool GloballyCoherent, bool HasCounter, bool IsROV) {
     assert(isUAV() && "Not a UAV");
     UAVFlags.GloballyCoherent = GloballyCoherent;
     UAVFlags.HasCounter = HasCounter;
     UAVFlags.IsROV = IsROV;
   }
+  const UAVInfo &getUAV() const {
+    assert(isUAV() && "Not a UAV");
+    return UAVFlags;
+  }
   void setCBuffer(uint32_t Size) {
     assert(isCBuffer() && "Not a CBuffer");
     CBufferSize = Size;
@@ -163,6 +168,10 @@ class ResourceInfo {
     Typed.ElementTy = ElementTy;
     Typed.ElementCount = ElementCount;
   }
+  const TypedInfo &getTyped() const {
+    assert(isTyped() && "Not typed");
+    return Typed;
+  }
   void setFeedback(dxil::SamplerFeedbackType Type) {
     assert(isFeedback() && "Not Feedback");
     Feedback.Type = Type;
@@ -171,8 +180,14 @@ class ResourceInfo {
     assert(isMultiSample() && "Not MultiSampled");
     MultiSample.Count = Count;
   }
+  const MSInfo &getMultiSample() const {
+    assert(isMultiSample() && "Not MultiSampled");
+    return MultiSample;
+  }
 
+  StringRef getName() const { return Name; }
   dxil::ResourceClass getResourceClass() const { return RC; }
+  dxil::ResourceKind getResourceKind() const { return Kind; }
 
   bool operator==(const ResourceInfo &RHS) const;
 
@@ -222,7 +237,6 @@ class ResourceInfo {
 
   MDTuple *getAsMetadata(LLVMContext &Ctx) const;
 
-  ResourceBinding getBinding() const { return Binding; }
   std::pair<uint32_t, uint32_t> getAnnotateProps() const;
 
   void print(raw_ostream &OS) const;
diff --git a/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
index f34302cc95065..e7c36ead1cc34 100644
--- a/llvm/lib/Target/DirectX/DXILOpLowering.cpp
+++ b/llvm/lib/Target/DirectX/DXILOpLowering.cpp
@@ -175,7 +175,7 @@ class OpLowerer {
       IRB.SetInsertPoint(CI);
 
       dxil::ResourceInfo &RI = DRM[CI];
-      dxil::ResourceInfo::ResourceBinding Binding = RI.getBinding();
+      const auto &Binding = RI.getBinding();
 
       std::array<Value *, 4> Args{
           ConstantInt::get(Int8Ty, llvm::to_underlying(RI.getResourceClass())),
@@ -201,7 +201,7 @@ class OpLowerer {
       IRB.SetInsertPoint(CI);
 
       dxil::ResourceInfo &RI = DRM[CI];
-      dxil::ResourceInfo::ResourceBinding Binding = RI.getBinding();
+      const auto &Binding = RI.getBinding();
       std::pair<uint32_t, uint32_t> Props = RI.getAnnotateProps();
 
       Constant *ResBind = OpBuilder.getResBind(
diff --git a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
index c57631cc4c8b6..76a40dbfc5845 100644
--- a/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
+++ b/llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp
@@ -10,23 +10,235 @@
 #include "DXILResourceAnalysis.h"
 #include "DirectX.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Analysis/DXILResource.h"
 #include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
 #include "llvm/Pass.h"
+#include "llvm/Support/FormatAdapters.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
 
-static void prettyPrintResources(raw_ostream &OS,
+static constexpr StringRef getRCName(dxil::ResourceClass RC) {
+  switch (RC) {
+  case dxil::ResourceClass::SRV:
+    return "SRV";
+  case dxil::ResourceClass::UAV:
+    return "UAV";
+  case dxil::ResourceClass::CBuffer:
+    return "cbuffer";
+  case dxil::ResourceClass::Sampler:
+    return "sampler";
+  }
+  llvm_unreachable("covered switch");
+}
+
+static constexpr StringRef getRCPrefix(dxil::ResourceClass RC) {
+  switch (RC) {
+  case dxil::ResourceClass::SRV:
+    return "t";
+  case dxil::ResourceClass::UAV:
+    return "u";
+  case dxil::ResourceClass::CBuffer:
+    return "cb";
+  case dxil::ResourceClass::Sampler:
+    return "s";
+  }
+}
+
+static constexpr StringRef getFormatName(const dxil::ResourceInfo &RI) {
+  if (RI.isTyped()) {
+    switch (RI.getTyped().ElementTy) {
+    case dxil::ElementType::I1:
+      return "i1";
+    case dxil::ElementType::I16:
+      return "i16";
+    case dxil::ElementType::U16:
+      return "u16";
+    case dxil::ElementType::I32:
+      return "i32";
+    case dxil::ElementType::U32:
+      return "u32";
+    case dxil::ElementType::I64:
+      return "i64";
+    case dxil::ElementType::U64:
+      return "u64";
+    case dxil::ElementType::F16:
+      return "f16";
+    case dxil::ElementType::F32:
+      return "f32";
+    case dxil::ElementType::F64:
+      return "f64";
+    case dxil::ElementType::SNormF16:
+      return "snorm_f16";
+    case dxil::ElementType::UNormF16:
+      return "unorm_f16";
+    case dxil::ElementType::SNormF32:
+      return "snorm_f32";
+    case dxil::ElementType::UNormF32:
+      return "unorm_f32";
+    case dxil::ElementType::SNormF64:
+      return "snorm_f64";
+    case dxil::ElementType::UNormF64:
+      return "unorm_f64";
+    case dxil::ElementType::PackedS8x32:
+      return "p32i8";
+    case dxil::ElementType::PackedU8x32:
+      return "p32u8";
+    case dxil::ElementType::Invalid:
+      llvm_unreachable("Invalid ElementType");
+    }
+    llvm_unreachable("Unhandled ElementType");
+  } else if (RI.isStruct())
+    return "struct";
+  else if (RI.isCBuffer() || RI.isSampler())
+    return "NA";
+  return "byte";
+}
+
+static constexpr StringRef getTextureDimName(dxil::ResourceKind RK) {
+  switch (RK) {
+  case dxil::ResourceKind::Texture1D:
+    return "1d";
+  case dxil::ResourceKind::Texture2D:
+    return "2d";
+  case dxil::ResourceKind::Texture3D:
+    return "3d";
+  case dxil::ResourceKind::TextureCube:
+    return "cube";
+  case dxil::ResourceKind::Texture1DArray:
+    return "1darray";
+  case dxil::ResourceKind::Texture2DArray:
+    return "2darray";
+  case dxil::ResourceKind::TextureCubeArray:
+    return "cubearray";
+  case dxil::ResourceKind::TBuffer:
+    return "tbuffer";
+  case dxil::ResourceKind::FeedbackTexture2D:
+    return "fbtex2d";
+  case dxil::ResourceKind::FeedbackTexture2DArray:
+    return "fbtex2darray";
+  case dxil::ResourceKind::Texture2DMS:
+    return "2dMS";
+  case dxil::ResourceKind::Texture2DMSArray:
+    return "2darrayMS";
+  case dxil::ResourceKind::Invalid:
+  case dxil::ResourceKind::NumEntries:
+  case dxil::ResourceKind::CBuffer:
+  case dxil::ResourceKind::RawBuffer:
+  case dxil::ResourceKind::Sampler:
+  case dxil::ResourceKind::StructuredBuffer:
+  case dxil::ResourceKind::TypedBuffer:
+  case dxil::ResourceKind::RTAccelerationStructure:
+    llvm_unreachable("Invalid ResourceKind for texture");
+  }
+  llvm_unreachable("Unhandled ResourceKind");
+}
+
+namespace {
+struct FormatResourceDimension
+    : public llvm::FormatAdapter<const dxil::ResourceInfo &> {
+  explicit FormatResourceDimension(const dxil::ResourceInfo &RI)
+      : llvm::FormatAdapter<const dxil::ResourceInfo &>(RI) {}
+
+  void format(llvm::raw_ostream &OS, StringRef Style) override {
+    dxil::ResourceKind RK = Item.getResourceKind();
+    switch (RK) {
+    default: {
+      OS << getTextureDimName(RK);
+      if (Item.isMultiSample())
+        OS << Item.getMultiSample().Count;
+      break;;
+    }
+    case dxil::ResourceKind::RawBuffer:
+    case dxil::ResourceKind::StructuredBuffer:
+      if (!Item.isUAV())
+        OS << "r/o";
+      else if (Item.getUAV().HasCounter)
+        OS << "r/w+cnt";
+      else
+        OS << "r/w";
+      break;
+    case dxil::ResourceKind::TypedBuffer:
+      OS << "buf";
+      break;
+    case dxil::ResourceKind::RTAccelerationStructure:
+      // TODO: dxc would print "ras" here. Can/should this happen?
+      llvm_unreachable("RTAccelerationStructure printing is not implemented");
+    }
+  }
+};
+
+struct FormatBindingID
+    : public llvm::FormatAdapter<const dxil::ResourceInfo &> {
+  explicit FormatBindingID(const dxil::ResourceInfo &RI)
+      : llvm::FormatAdapter<const dxil::ResourceInfo &>(RI) {}
+
+  void format(llvm::raw_ostream &OS, StringRef Style) override {
+    OS << getRCPrefix(Item.getResourceClass()).upper()
+       << Item.getBinding().RecordID;
+  }
+};
+
+struct FormatBindingLocation
+    : public llvm::FormatAdapter<const dxil::ResourceInfo &> {
+  explicit FormatBindingLocation(const dxil::ResourceInfo &RI)
+      : llvm::FormatAdapter<const dxil::ResourceInfo &>(RI) {}
+
+  void format(llvm::raw_ostream &OS, StringRef Style) override {
+    const auto &Binding = Item.getBinding();
+    OS << getRCPrefix(Item.getResourceClass()) << Binding.LowerBound;
+    if (Binding.Space)
+      OS << ",space" << Binding.Space;
+  }
+};
+
+struct FormatBindingSize
+    : public llvm::FormatAdapter<const dxil::ResourceInfo &> {
+  explicit FormatBindingSize(const dxil::ResourceInfo &RI)
+      : llvm::FormatAdapter<const dxil::ResourceInfo &>(RI) {}
+
+  void format(llvm::raw_ostream &OS, StringRef Style) override {
+    uint32_t Size = Item.getBinding().Size;
+    if (Size == std::numeric_limits<uint32_t>::max())
+      OS << "unbounded";
+    else
+      OS << Size;
+  }
+};
+
+} // namespace
+
+static void prettyPrintResources(raw_ostream &OS, const DXILResourceMap &DRM,
                                  const dxil::Resources &MDResources) {
   // Column widths are arbitrary but match the widths DXC uses.
   OS << ";\n; Resource Bindings:\n;\n";
-  OS << formatv("; {0,-30} {1,10} {2,7} {3,11} {4,7} {5,14} {6,16}\n",
+  OS << formatv("; {0,-30} {1,10} {2,7} {3,11} {4,7} {5,14} {6,9}\n",
                 "Name", "Type", "Format", "Dim", "ID", "HLSL Bind", "Count");
   OS << formatv(
-      "; {0,-+30} {1,-+10} {2,-+7} {3,-+11} {4,-+7} {5,-+14} {6,-+16}\n", "",
+      "; {0,-+30} {1,-+10} {2,-+7} {3,-+11} {4,-+7} {5,-+14} {6,-+9}\n", "",
       "", "", "", "", "", "");
 
+  // TODO: Do we want to sort these by binding or something like that?
+  for (auto [_, RI] : DRM) {
+    dxil::ResourceClass RC = RI.getResourceClass();
+    assert((RC != dxil::ResourceClass::CBuffer || !MDResources.hasCBuffers()) &&
+           "Old and new cbuffer representations can't coexist");
+    assert((RC != dxil::ResourceClass::UAV || !MDResources.hasUAVs()) &&
+           "Old and new UAV representations can't coexist");
+
+    StringRef Name(RI.getName());
+    StringRef Type(getRCName(RC));
+    StringRef Format(getFormatName(RI));
+    FormatResourceDimension Dim(RI);
+    FormatBindingID ID(RI);
+    FormatBindingLocation Bind(RI);
+    FormatBindingSize Count(RI);
+    OS << formatv("; {0,-30} {1,10} {2,7} {3,11} {4,7} {5,14} {6,9}\n",
+                  Name, Type, Format, Dim, ID, Bind, Count);
+  }
+
   if (MDResources.hasCBuffers())
     MDResources.printCBuffers(OS);
   if (MDResources.hasUAVs())
@@ -37,8 +249,9 @@ static void prettyPrintResources(raw_ostream &OS,
 
 PreservedAnalyses DXILPrettyPrinterPass::run(Module &M,
                                              ModuleAnalysisManager &MAM) {
+  const DXILResourceMap &DRM = MAM.getResult<DXILResourceAnalysis>(M);
   const dxil::Resources &MDResources = MAM.getResult<DXILResourceMDAnalysis>(M);
-  prettyPrintResources(OS, MDResources);
+  prettyPrintResources(OS, DRM, MDResources);
   return PreservedAnalyses::all();
 }
 
@@ -63,6 +276,7 @@ class DXILPrettyPrinterLegacy : public llvm::ModulePass {
   bool runOnModule(Module &M) override;
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.setPreservesAll();
+    AU.addRequired<DXILResourceWrapperPass>();
     AU.addRequired<DXILResourceMDWrapper>();
   }
 };
@@ -71,13 +285,16 @@ class DXILPrettyPrinterLegacy : public llvm::ModulePass {
 char DXILPrettyPrinterLegacy::ID = 0;
 INITIALIZE_PASS_BEGIN(DXILPrettyPrinterLegacy, "dxil-pretty-printer",
                       "DXIL Metadata Pretty Printer", true, true)
+INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass)
 INITIALIZE_PASS_DEPENDENCY(DXILResourceMDWrapper)
 INITIALIZE_PASS_END(DXILPrettyPrinterLegacy, "dxil-pretty-printer",
                     "DXIL Metadata Pretty Printer", true, true)
 
 bool DXILPrettyPrinterLegacy::runOnModule(Module &M) {
+  const DXILResourceMap &DRM =
+      getAnalysis<DXILResourceWrapperPass>().getResourceMap();
   dxil::Resources &Res = getAnalysis<DXILResourceMDWrapper>().getDXILResource();
-  prettyPrintResources(OS, Res);
+  prettyPrintResources(OS, DRM, Res);
   return false;
 }
 
diff --git a/llvm/test/CodeGen/DirectX/CreateHandle.ll b/llvm/test/CodeGen/DirectX/CreateHandle.ll
index f0d1c8da5a425..cbb7359642c27 100644
--- a/llvm/test/CodeGen/DirectX/CreateHandle.ll
+++ b/llvm/test/CodeGen/DirectX/CreateHandle.ll
@@ -1,4 +1,13 @@
 ; RUN: opt -S -passes=dxil-op-lower,dxil-translate-metadata %s | FileCheck %s
+; RUN: opt -S -passes=dxil-pretty-printer %s 2>&1 >/dev/null | FileCheck --check-prefix=CHECK-PRETTY %s
+
+; CHECK-PRETTY:       Type  Format         Dim      ID      HLSL Bind     Count
+; CHECK-PRETTY: ---------- ------- ----------- ------- -------------- ---------
+; CHECK-PRETTY:        UAV     f32         buf      U0      u5,space3         1
+; CHECK-PRETTY:        UAV     i32         buf      U1      u7,space2         1
+; CHECK-PRETTY:        SRV     u32         buf      T0      t3,space5        24
+; CHECK-PRETTY:        SRV  struct         r/o      T1      t2,space4         1
+; CHECK-PRETTY:        SRV    byte         r/o      T2      t8,space1         1
 
 target triple = "dxil-pc-shadermodel6.0-compute"
 
diff --git a/llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll b/llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll
index 345459a60c5ab..aea251a3612ef 100644
--- a/llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll
+++ b/llvm/test/CodeGen/DirectX/CreateHandleFromBinding.ll
@@ -1,4 +1,13 @@
 ; RUN: opt -S -passes=dxil-op-lower,dxil-translate-metadata %s | FileCheck %s
+; RUN: opt -S -passes=dxil-pretty-printer %s 2>&1 >/dev/null | FileCheck --check-prefix=CHECK-PRETTY %s
+
+; CHECK-PRETTY:       Type  Format         Dim      ID      HLSL Bind     Count
+; CHECK-PRETTY: ---------- ------- ----------- ------- -------------- ---------
+; CHECK-PRETTY:        UAV     f32         buf      U0      u5,space3         1
+; CHECK-PRETTY:        UAV     i32         buf      U1      u7,space2         1
+; CHECK-PRETTY:        SRV     u32         buf      T0      t3,space5        24
+; CHECK-PRETTY:        SRV  struct         r/o      T1      t2,space4         1
+; CHECK-PRETTY:        SRV    byte         r/o      T2      t8,space1         1
 
 target triple = "dxil-pc-shadermodel6.6-compute"
 

@bogner
Copy link
Contributor Author

bogner commented Aug 15, 2024

Depends on #104251 and #104446

Copy link

github-actions bot commented Aug 15, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Contributor

@coopp coopp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. This is the first time I have seen a switch 'default:' come before the 'case:' entries. (void format(llvm::raw_ostream &OS, StringRef Style) override)

Copy link
Member

@hekota hekota left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

; CHECK-PRETTY: UAV i32 buf U1 u7,space2 1
; CHECK-PRETTY: SRV u32 buf T0 t3,space5 24
; CHECK-PRETTY: SRV struct r/o T1 t2,space4 1
; CHECK-PRETTY: SRV byte r/o T2 t8,space1 1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change one of the cases to use the default space0?

FormatBindingID ID(RI);
FormatBindingLocation Bind(RI);
FormatBindingSize Count(RI);
OS << formatv("; {0,-30} {1,10} {2,7} {3,11} {4,7} {5,14} {6,9}\n",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neat use of the llvm::FormatAdapter. Bit of a overkill for the simple cases but it looks elegant. ;).

bogner added 2 commits August 21, 2024 18:09
Created using spr 1.3.5-bogner

[skip ci]
Created using spr 1.3.5-bogner
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

static void prettyPrintResources(raw_ostream &OS,
static constexpr StringRef getRCName(dxil::ResourceClass RC) {
Copy link
Member

@farzonl farzonl Aug 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to ignore, I was thinking of a different way to do this that would have a tighter coupling of Names and prefixes:

struct ResourceClassNameInfo {
  const StringRef name;
  const StringRef prefix;
};

llvm::DenseMap<dxil::ResourceClass, ResourceClassNameInfo> createResourceClassMap() {
  return {
    {dxil::ResourceClass::SRV, {"SRV", "t"}},
    {dxil::ResourceClass::UAV, {"UAV", "u"}},
    {dxil::ResourceClass::CBuffer, {"cbuffer", "cb"}},
    {dxil::ResourceClass::Sampler, {"sampler", "s"}}
  };
}

static const llvm::DenseMap<dxil::ResourceClass, ResourceClassNameInfo> ResourceClassMap = createResourceClassMap();

StringRef getRCName(dxil::ResourceClass RC) {
  return ResourceClassMap.lookup(RC).name;
}

StringRef getRCPrefix(dxil::ResourceClass RC) {
  return ResourceClassMap.lookup(RC).prefix;
}

Copy link
Contributor Author

@bogner bogner Aug 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This generates noticeably worse code because of the hash table lookup and also introduces a static initializer, which should really be avoided. It is possible to do something similar with a static table, but you need to break the abstraction of the enum a bit to do that and adding static asserts to make sure it's correct undoes most of the potential clarity it adds.

I suppose we could do something like this to couple the names, but I'm not entirely sold that the usability hit is worth it:

struct ResourceClassNameInfo {
  const StringRef Name;
  const StringRef Prefix;
};

static ResourceClassNameInfo getRCNameInfo(dxil::ResourceClass RC) {
  switch (RC) {
  case dxil::ResourceClass::SRV:
    return {"SRV", "t"};
  case dxil::ResourceClass::UAV:
    return {"UAV", "u"};
  case dxil::ResourceClass::CBuffer:
    return {"cbuffer", "cb"};
  case dxil::ResourceClass::Sampler:
    return {"sampler", "s"};
  }
  llvm_unreachable("covered switch");
}

Copy link
Member

@farzonl farzonl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

bogner and others added 5 commits August 26, 2024 16:05
Created using spr 1.3.5-bogner

[skip ci]
Created using spr 1.3.5-bogner
Created using spr 1.3.5-bogner

[skip ci]
Created using spr 1.3.5-bogner
@bogner bogner changed the base branch from users/bogner/sprmain.directx-add-resource-handling-to-the-dxil-pretty-printer to main August 27, 2024 00:42
@bogner bogner merged commit 87157ab into main Aug 27, 2024
6 of 10 checks passed
@bogner bogner deleted the users/bogner/sprdirectx-add-resource-handling-to-the-dxil-pretty-printer branch August 27, 2024 00:42
5c4lar pushed a commit to 5c4lar/llvm-project that referenced this pull request Aug 29, 2024
Handle target extension type resources when printing resources to textual IR.

Pull Request: llvm#104448
dmpolukhin pushed a commit to dmpolukhin/llvm-project that referenced this pull request Sep 2, 2024
Handle target extension type resources when printing resources to textual IR.

Pull Request: llvm#104448
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

7 participants