Skip to content

[DirectX] Get resource information via TargetExtType #119772

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

Merged
merged 5 commits into from
Dec 16, 2024

Conversation

bogner
Copy link
Contributor

@bogner bogner commented Dec 12, 2024

Instead of storing an auxilliary structure with the information from the DXIL resource target extension types duplicated, access the information that we can via the type itself.

This also means we need to handle some of the target extension types we haven't fully defined yet, like Texture and CBuffer. For now we make an educated guess to what those should look like based on llvm/wg-hlsl#76, and we can update them fairly easily when we've defined them more thoroughly.

First part of #118400

Instead of storing an auxilliary structure with the information from the
DXIL resource target extension types duplicated, access the information
that we can via the type itself.

This also means we need to handle some of the target extension types we
haven't fully defined yet, like Texture and CBuffer. For now we make an
educated guess to what those should look like based on llvm/wg-hlsl#76,
and we can update them fairly easily when we've defined them more
thoroughly.

First part of llvm#118400
@llvmbot llvmbot added backend:DirectX llvm:analysis Includes value tracking, cost tables and constant folding labels Dec 12, 2024
@llvmbot
Copy link
Member

llvmbot commented Dec 12, 2024

@llvm/pr-subscribers-backend-directx

@llvm/pr-subscribers-llvm-analysis

Author: Justin Bogner (bogner)

Changes

Instead of storing an auxilliary structure with the information from the DXIL resource target extension types duplicated, access the information that we can via the type itself.

This also means we need to handle some of the target extension types we haven't fully defined yet, like Texture and CBuffer. For now we make an educated guess to what those should look like based on llvm/wg-hlsl#76, and we can update them fairly easily when we've defined them more thoroughly.

First part of #118400


Patch is 75.78 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/119772.diff

6 Files Affected:

  • (modified) llvm/include/llvm/Analysis/DXILResource.h (+226-158)
  • (modified) llvm/lib/Analysis/DXILResource.cpp (+308-411)
  • (modified) llvm/lib/Target/DirectX/DXILOpLowering.cpp (+1-1)
  • (modified) llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp (+1-1)
  • (modified) llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp (+4-4)
  • (modified) llvm/unittests/Analysis/DXILResourceTest.cpp (+255-140)
diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h
index 6b577c02f05450..0205356af54443 100644
--- a/llvm/include/llvm/Analysis/DXILResource.h
+++ b/llvm/include/llvm/Analysis/DXILResource.h
@@ -11,6 +11,7 @@
 
 #include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/IR/GlobalVariable.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/Alignment.h"
@@ -18,12 +19,183 @@
 
 namespace llvm {
 class CallInst;
+class DataLayout;
 class LLVMContext;
 class MDTuple;
+class TargetExtType;
 class Value;
 
 namespace dxil {
 
+/// The dx.RawBuffer target extension type
+///
+/// `target("dx.RawBuffer", Type, IsWriteable, IsROV)`
+class RawBufferExtType : public TargetExtType {
+public:
+  RawBufferExtType() = delete;
+  RawBufferExtType(const RawBufferExtType &) = delete;
+  RawBufferExtType &operator=(const RawBufferExtType &) = delete;
+
+  bool isStructured() const {
+    // TODO: We need to be more prescriptive here, but since there's some debate
+    // over whether byte address buffer should have a void type or an i8 type,
+    // accept either for now.
+    Type *Ty = getTypeParameter(0);
+    return !Ty->isVoidTy() && !Ty->isIntegerTy(8);
+  }
+
+  Type *getResourceType() const {
+    return isStructured() ? getTypeParameter(0) : nullptr;
+  }
+  bool isWriteable() const { return getIntParameter(0); }
+  bool isROV() const { return getIntParameter(1); }
+
+  static bool classof(const TargetExtType *T) {
+    return T->getName() == "dx.RawBuffer";
+  }
+  static bool classof(const Type *T) {
+    return isa<TargetExtType>(T) && classof(cast<TargetExtType>(T));
+  }
+};
+
+/// The dx.TypedBuffer target extension type
+///
+/// `target("dx.TypedBuffer", Type, IsWriteable, IsROV, IsSigned)`
+class TypedBufferExtType : public TargetExtType {
+public:
+  TypedBufferExtType() = delete;
+  TypedBufferExtType(const TypedBufferExtType &) = delete;
+  TypedBufferExtType &operator=(const TypedBufferExtType &) = delete;
+
+  Type *getResourceType() const { return getTypeParameter(0); }
+  bool isWriteable() const { return getIntParameter(0); }
+  bool isROV() const { return getIntParameter(1); }
+  bool isSigned() const { return getIntParameter(2); }
+
+  static bool classof(const TargetExtType *T) {
+    return T->getName() == "dx.TypedBuffer";
+  }
+  static bool classof(const Type *T) {
+    return isa<TargetExtType>(T) && classof(cast<TargetExtType>(T));
+  }
+};
+
+/// The dx.Texture target extension type
+///
+/// `target("dx.Texture", Type, IsWriteable, IsROV, IsSigned, Dimension)`
+class TextureExtType : public TargetExtType {
+public:
+  TextureExtType() = delete;
+  TextureExtType(const TextureExtType &) = delete;
+  TextureExtType &operator=(const TextureExtType &) = delete;
+
+  Type *getResourceType() const { return getTypeParameter(0); }
+  bool isWriteable() const { return getIntParameter(0); }
+  bool isROV() const { return getIntParameter(1); }
+  bool isSigned() const { return getIntParameter(2); }
+  dxil::ResourceKind getDimension() const {
+    return static_cast<dxil::ResourceKind>(getIntParameter(3));
+  }
+
+  static bool classof(const TargetExtType *T) {
+    return T->getName() == "dx.Texture";
+  }
+  static bool classof(const Type *T) {
+    return isa<TargetExtType>(T) && classof(cast<TargetExtType>(T));
+  }
+};
+
+/// The dx.MSTexture target extension type
+///
+/// `target("dx.MSTexture", Type, IsWriteable, Samples, IsSigned, Dimension)`
+class MSTextureExtType : public TargetExtType {
+public:
+  MSTextureExtType() = delete;
+  MSTextureExtType(const MSTextureExtType &) = delete;
+  MSTextureExtType &operator=(const MSTextureExtType &) = delete;
+
+  Type *getResourceType() const { return getTypeParameter(0); }
+  bool isWriteable() const { return getIntParameter(0); }
+  uint32_t getSampleCount() const { return getIntParameter(1); }
+  bool isSigned() const { return getIntParameter(2); }
+  dxil::ResourceKind getDimension() const {
+    return static_cast<dxil::ResourceKind>(getIntParameter(3));
+  }
+
+  static bool classof(const TargetExtType *T) {
+    return T->getName() == "dx.MSTexture";
+  }
+  static bool classof(const Type *T) {
+    return isa<TargetExtType>(T) && classof(cast<TargetExtType>(T));
+  }
+};
+
+/// The dx.FeedbackTexture target extension type
+///
+/// `target("dx.FeedbackTexture", FeedbackType, Dimension)`
+class FeedbackTextureExtType : public TargetExtType {
+public:
+  FeedbackTextureExtType() = delete;
+  FeedbackTextureExtType(const FeedbackTextureExtType &) = delete;
+  FeedbackTextureExtType &operator=(const FeedbackTextureExtType &) = delete;
+
+  dxil::SamplerFeedbackType getFeedbackType() const {
+    return static_cast<dxil::SamplerFeedbackType>(getIntParameter(0));
+  }
+  dxil::ResourceKind getDimension() const {
+    return static_cast<dxil::ResourceKind>(getIntParameter(1));
+  }
+
+  static bool classof(const TargetExtType *T) {
+    return T->getName() == "dx.FeedbackTexture";
+  }
+  static bool classof(const Type *T) {
+    return isa<TargetExtType>(T) && classof(cast<TargetExtType>(T));
+  }
+};
+
+/// The dx.CBuffer target extension type
+///
+/// `target("dx.CBuffer", <Type>, ...)`
+class CBufferExtType : public TargetExtType {
+public:
+  CBufferExtType() = delete;
+  CBufferExtType(const CBufferExtType &) = delete;
+  CBufferExtType &operator=(const CBufferExtType &) = delete;
+
+  Type *getResourceType() const { return getTypeParameter(0); }
+
+  static bool classof(const TargetExtType *T) {
+    return T->getName() == "dx.CBuffer";
+  }
+  static bool classof(const Type *T) {
+    return isa<TargetExtType>(T) && classof(cast<TargetExtType>(T));
+  }
+};
+
+/// The dx.Sampler target extension type
+///
+/// `target("dx.Sampler", SamplerType)`
+class SamplerExtType : public TargetExtType {
+public:
+  SamplerExtType() = delete;
+  SamplerExtType(const SamplerExtType &) = delete;
+  SamplerExtType &operator=(const SamplerExtType &) = delete;
+
+  dxil::SamplerType getSamplerType() const {
+    return static_cast<dxil::SamplerType>(getIntParameter(0));
+  }
+
+  static bool classof(const TargetExtType *T) {
+    return T->getName() == "dx.Sampler";
+  }
+  static bool classof(const Type *T) {
+    return isa<TargetExtType>(T) && classof(cast<TargetExtType>(T));
+  }
+};
+
+//===----------------------------------------------------------------------===//
+
 class ResourceInfo {
 public:
   struct ResourceBinding {
@@ -93,55 +265,27 @@ class ResourceInfo {
     }
   };
 
-  struct MSInfo {
-    uint32_t Count;
-
-    bool operator==(const MSInfo &RHS) const { return Count == RHS.Count; }
-    bool operator!=(const MSInfo &RHS) const { return !(*this == RHS); }
-    bool operator<(const MSInfo &RHS) const { return Count < RHS.Count; }
-  };
-
-  struct FeedbackInfo {
-    dxil::SamplerFeedbackType Type;
-
-    bool operator==(const FeedbackInfo &RHS) const { return Type == RHS.Type; }
-    bool operator!=(const FeedbackInfo &RHS) const { return !(*this == RHS); }
-    bool operator<(const FeedbackInfo &RHS) const { return Type < RHS.Type; }
-  };
-
 private:
-  // Universal properties.
-  Value *Symbol;
-  StringRef Name;
+  ResourceBinding Binding;
+  TargetExtType *HandleTy;
+
+  // GloballyCoherent and HasCounter aren't really part of the type and need to
+  // be determined by analysis, so they're just provided directly when we
+  // construct these.
+  bool GloballyCoherent;
+  bool HasCounter;
 
   dxil::ResourceClass RC;
   dxil::ResourceKind Kind;
 
-  ResourceBinding Binding = {};
-
-  // Resource class dependent properties.
-  // CBuffer, Sampler, and RawBuffer end here.
-  union {
-    UAVInfo UAVFlags;            // UAV
-    uint32_t CBufferSize;        // CBuffer
-    dxil::SamplerType SamplerTy; // Sampler
-  };
-
-  // Resource kind dependent properties.
-  union {
-    StructInfo Struct;     // StructuredBuffer
-    TypedInfo Typed;       // All SRV/UAV except Raw/StructuredBuffer
-    FeedbackInfo Feedback; // FeedbackTexture
-  };
-
-  MSInfo MultiSample;
-
 public:
-  ResourceInfo(dxil::ResourceClass RC, dxil::ResourceKind Kind, Value *Symbol,
-               StringRef Name)
-      : Symbol(Symbol), Name(Name), RC(RC), Kind(Kind) {}
+  ResourceInfo(uint32_t RecordID, uint32_t Space, uint32_t LowerBound,
+               uint32_t Size, TargetExtType *HandleTy,
+               bool GloballyCoherent = false, bool HasCounter = false);
+
+  TargetExtType *getHandleTy() const { return HandleTy; }
 
-  // Conditions to check before accessing union members.
+  // Conditions to check before accessing specific views.
   bool isUAV() const;
   bool isCBuffer() const;
   bool isSampler() const;
@@ -150,148 +294,69 @@ class ResourceInfo {
   bool isFeedback() const;
   bool isMultiSample() const;
 
-  void bind(uint32_t RecordID, uint32_t Space, uint32_t LowerBound,
-            uint32_t Size) {
-    Binding.RecordID = RecordID;
-    Binding.Space = Space;
-    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;
-  }
-  void setSampler(dxil::SamplerType Ty) { SamplerTy = Ty; }
-  void setStruct(uint32_t Stride, MaybeAlign Alignment) {
-    assert(isStruct() && "Not a Struct");
-    Struct.Stride = Stride;
-    Struct.AlignLog2 = Alignment ? Log2(*Alignment) : 0;
-  }
-  void setTyped(dxil::ElementType ElementTy, uint32_t ElementCount) {
-    assert(isTyped() && "Not Typed");
-    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;
-  }
-  void setMultiSample(uint32_t Count) {
-    assert(isMultiSample() && "Not MultiSampled");
-    MultiSample.Count = Count;
+  // Views into the type.
+  UAVInfo getUAV() const;
+  uint32_t getCBufferSize(const DataLayout &DL) const;
+  dxil::SamplerType getSamplerType() const;
+  StructInfo getStruct(const DataLayout &DL) const;
+  TypedInfo getTyped() const;
+  dxil::SamplerFeedbackType getFeedbackType() const;
+  uint32_t getMultiSampleCount() const;
+
+  StringRef getName() const {
+    // TODO: Get the name from the symbol once we include one here.
+    return "";
   }
-  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; }
 
+  void setBindingID(unsigned ID) { Binding.RecordID = ID; }
+
+  const ResourceBinding &getBinding() const { return Binding; }
+
+  MDTuple *getAsMetadata(Module &M) const;
+  std::pair<uint32_t, uint32_t> getAnnotateProps(Module &M) const;
+
   bool operator==(const ResourceInfo &RHS) const;
   bool operator!=(const ResourceInfo &RHS) const { return !(*this == RHS); }
   bool operator<(const ResourceInfo &RHS) const;
 
-  static ResourceInfo SRV(Value *Symbol, StringRef Name,
-                          dxil::ElementType ElementTy, uint32_t ElementCount,
-                          dxil::ResourceKind Kind);
-  static ResourceInfo RawBuffer(Value *Symbol, StringRef Name);
-  static ResourceInfo StructuredBuffer(Value *Symbol, StringRef Name,
-                                       uint32_t Stride, MaybeAlign Alignment);
-  static ResourceInfo Texture2DMS(Value *Symbol, StringRef Name,
-                                  dxil::ElementType ElementTy,
-                                  uint32_t ElementCount, uint32_t SampleCount);
-  static ResourceInfo Texture2DMSArray(Value *Symbol, StringRef Name,
-                                       dxil::ElementType ElementTy,
-                                       uint32_t ElementCount,
-                                       uint32_t SampleCount);
-
-  static ResourceInfo UAV(Value *Symbol, StringRef Name,
-                          dxil::ElementType ElementTy, uint32_t ElementCount,
-                          bool GloballyCoherent, bool IsROV,
-                          dxil::ResourceKind Kind);
-  static ResourceInfo RWRawBuffer(Value *Symbol, StringRef Name,
-                                  bool GloballyCoherent, bool IsROV);
-  static ResourceInfo RWStructuredBuffer(Value *Symbol, StringRef Name,
-                                         uint32_t Stride, MaybeAlign Alignment,
-                                         bool GloballyCoherent, bool IsROV,
-                                         bool HasCounter);
-  static ResourceInfo RWTexture2DMS(Value *Symbol, StringRef Name,
-                                    dxil::ElementType ElementTy,
-                                    uint32_t ElementCount, uint32_t SampleCount,
-                                    bool GloballyCoherent);
-  static ResourceInfo RWTexture2DMSArray(Value *Symbol, StringRef Name,
-                                         dxil::ElementType ElementTy,
-                                         uint32_t ElementCount,
-                                         uint32_t SampleCount,
-                                         bool GloballyCoherent);
-  static ResourceInfo FeedbackTexture2D(Value *Symbol, StringRef Name,
-                                        dxil::SamplerFeedbackType FeedbackTy);
-  static ResourceInfo
-  FeedbackTexture2DArray(Value *Symbol, StringRef Name,
-                         dxil::SamplerFeedbackType FeedbackTy);
-
-  static ResourceInfo CBuffer(Value *Symbol, StringRef Name, uint32_t Size);
-
-  static ResourceInfo Sampler(Value *Symbol, StringRef Name,
-                              dxil::SamplerType SamplerTy);
-
-  MDTuple *getAsMetadata(LLVMContext &Ctx) const;
-
-  std::pair<uint32_t, uint32_t> getAnnotateProps() const;
-
-  void print(raw_ostream &OS) const;
+  void print(raw_ostream &OS, const DataLayout &DL) const;
 };
 
 } // namespace dxil
 
+//===----------------------------------------------------------------------===//
+
 class DXILResourceMap {
-  SmallVector<dxil::ResourceInfo> Resources;
+  SmallVector<dxil::ResourceInfo> Infos;
   DenseMap<CallInst *, unsigned> CallMap;
   unsigned FirstUAV = 0;
   unsigned FirstCBuffer = 0;
   unsigned FirstSampler = 0;
 
+  /// Populate the map given the resource binding calls in the given module.
+  void populate(Module &M);
+
 public:
   using iterator = SmallVector<dxil::ResourceInfo>::iterator;
   using const_iterator = SmallVector<dxil::ResourceInfo>::const_iterator;
 
-  DXILResourceMap(
-      SmallVectorImpl<std::pair<CallInst *, dxil::ResourceInfo>> &&CIToRI);
+  iterator begin() { return Infos.begin(); }
+  const_iterator begin() const { return Infos.begin(); }
+  iterator end() { return Infos.end(); }
+  const_iterator end() const { return Infos.end(); }
 
-  iterator begin() { return Resources.begin(); }
-  const_iterator begin() const { return Resources.begin(); }
-  iterator end() { return Resources.end(); }
-  const_iterator end() const { return Resources.end(); }
-
-  bool empty() const { return Resources.empty(); }
+  bool empty() const { return Infos.empty(); }
 
   iterator find(const CallInst *Key) {
     auto Pos = CallMap.find(Key);
-    return Pos == CallMap.end() ? Resources.end()
-                                : (Resources.begin() + Pos->second);
+    return Pos == CallMap.end() ? Infos.end() : (Infos.begin() + Pos->second);
   }
 
   const_iterator find(const CallInst *Key) const {
     auto Pos = CallMap.find(Key);
-    return Pos == CallMap.end() ? Resources.end()
-                                : (Resources.begin() + Pos->second);
+    return Pos == CallMap.end() ? Infos.end() : (Infos.begin() + Pos->second);
   }
 
   iterator srv_begin() { return begin(); }
@@ -334,7 +399,10 @@ class DXILResourceMap {
     return make_range(sampler_begin(), sampler_end());
   }
 
-  void print(raw_ostream &OS) const;
+  void print(raw_ostream &OS, const DataLayout &DL) const;
+
+  friend class DXILResourceAnalysis;
+  friend class DXILResourceWrapperPass;
 };
 
 class DXILResourceAnalysis : public AnalysisInfoMixin<DXILResourceAnalysis> {
@@ -362,7 +430,7 @@ class DXILResourcePrinterPass : public PassInfoMixin<DXILResourcePrinterPass> {
 };
 
 class DXILResourceWrapperPass : public ModulePass {
-  std::unique_ptr<DXILResourceMap> ResourceMap;
+  std::unique_ptr<DXILResourceMap> Map;
 
 public:
   static char ID; // Class identification, replacement for typeinfo
@@ -370,8 +438,8 @@ class DXILResourceWrapperPass : public ModulePass {
   DXILResourceWrapperPass();
   ~DXILResourceWrapperPass() override;
 
-  const DXILResourceMap &getResourceMap() const { return *ResourceMap; }
-  DXILResourceMap &getResourceMap() { return *ResourceMap; }
+  const DXILResourceMap &getResourceMap() const { return *Map; }
+  DXILResourceMap &getResourceMap() { return *Map; }
 
   void getAnalysisUsage(AnalysisUsage &AU) const override;
   bool runOnModule(Module &M) override;
diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp
index 2802480481690d..f96a9468d6bc54 100644
--- a/llvm/lib/Analysis/DXILResource.cpp
+++ b/llvm/lib/Analysis/DXILResource.cpp
@@ -8,6 +8,7 @@
 
 #include "llvm/Analysis/DXILResource.h"
 #include "llvm/ADT/APInt.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/DiagnosticInfo.h"
@@ -17,6 +18,7 @@
 #include "llvm/IR/Metadata.h"
 #include "llvm/IR/Module.h"
 #include "llvm/InitializePasses.h"
+#include "llvm/Support/FormatVariadic.h"
 
 #define DEBUG_TYPE "dxil-resource"
 
@@ -148,11 +150,74 @@ static StringRef getSamplerFeedbackTypeName(SamplerFeedbackType SFT) {
   llvm_unreachable("Unhandled SamplerFeedbackType");
 }
 
+static dxil::ElementType toDXILElementType(Type *Ty, bool IsSigned) {
+  // TODO: Handle unorm, snorm, and packed.
+  Ty = Ty->getScalarType();
+
+  if (Ty->isIntegerTy()) {
+    switch (Ty->getIntegerBitWidth()) {
+    case 16:
+      return IsSigned ? ElementType::I16 : ElementType::U16;
+    case 32:
+      return IsSigned ? ElementType::I32 : ElementType::U32;
+    case 64:
+      return IsSigned ? ElementType::I64 : ElementType::U64;
+    case 1:
+    default:
+      return ElementType::Invalid;
+    }
+  } else if (Ty->isFloatTy()) {
+    return ElementType::F32;
+  } else if (Ty->isDoubleTy()) {
+    return ElementType::F64;
+  } else if (Ty->isHalfTy()) {
+    return ElementType::F16;
+  }
+
+  return ElementType::Invalid;
+}
+
+ResourceInfo::ResourceInfo(uint32_t RecordID, uint32_t Space,
+                           uint32_t LowerBound, uint32_t Size,
+                           TargetExtType *HandleTy, bool GloballyCoherent,
+                           bool HasCounter)
+    : Binding{RecordID, Space, LowerBound, Size}, HandleTy(HandleTy),
+      GloballyCoherent(GloballyCoherent), HasCounter(HasCounter) {
+  if (auto *Ty = dyn_cast<RawBufferExtType>(HandleTy)) {
+    RC = Ty->isWriteable() ? ResourceClass::UAV : ResourceClass::SRV;
+    Kind = Ty->isStructured() ? ResourceKind::StructuredBuffer
+                              : ResourceKind::RawBuffer;
+  } else if (auto *Ty = dyn_cast<TypedBufferExtType>(HandleTy)) {
+    RC = Ty->isWriteable() ? ResourceClass::UAV : ResourceClass::SRV;
+    Kind = ResourceKind::TypedBuffer;
+  } else if (auto *Ty = dyn_cast<TextureExtType>(HandleTy)) {
+    RC = Ty->isWriteable() ? ResourceClass::UAV : ResourceClass::SRV;
+    Kind = Ty->getDimension();
+  } else if (auto *Ty = dyn_cast<MSTextureExtType>(HandleTy)) {
+    RC = Ty->isWriteable() ? ResourceClass::UAV : ResourceClass::SRV;
+    Kind = Ty->getDimension();
+  } else if (auto *Ty = dyn_cast<FeedbackTextureExtType>(HandleTy)) {
+    RC = ResourceClass::UAV;
+    Kind = Ty->getDimension();
+  } else if (isa<CBufferExtType>(HandleTy)) {
+    RC = ResourceClass::CBuffer;
+    Kind = ResourceKind::CBuffer;
+  } else if (isa<SamplerExtType>(Ha...
[truncated]

Copy link

github-actions bot commented Dec 12, 2024

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

Copy link

github-actions bot commented Dec 12, 2024

⚠️ undef deprecator found issues in your code. ⚠️

You can test this locally with the following command:
git diff -U0 --pickaxe-regex -S '([^a-zA-Z0-9#_-]undef[^a-zA-Z0-9_-]|UndefValue::get)' a480d5172215ce8e49b492e5c0295de1f397954d 4ca71fdf31be9b91ea40eec71ef4c9de7ff493fd llvm/include/llvm/Analysis/DXILResource.h llvm/lib/Analysis/DXILResource.cpp llvm/lib/Target/DirectX/DXILOpLowering.cpp llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp llvm/test/Analysis/DXILResource/buffer-frombinding.ll llvm/unittests/Analysis/DXILResourceTest.cpp

The following files introduce new uses of undef:

  • llvm/unittests/Analysis/DXILResourceTest.cpp

Undef is now deprecated and should only be used in the rare cases where no replacement is possible. For example, a load of uninitialized memory yields undef. You should use poison values for placeholders instead.

In tests, avoid using undef and having tests that trigger undefined behavior. If you need an operand with some unimportant value, you can add a new argument to the function and use that instead.

For example, this is considered a bad practice:

define void @fn() {
  ...
  br i1 undef, ...
}

Please use the following instead:

define void @fn(i1 %cond) {
  ...
  br i1 %cond, ...
}

Please refer to the Undefined Behavior Manual for more information.

@bogner
Copy link
Contributor Author

bogner commented Dec 12, 2024

⚠️ undef deprecator found issues in your code. ⚠️

You can test this locally with the following command:
The following files introduce new uses of undef:

  • llvm/unittests/Analysis/DXILResourceTest.cpp

These are all resolved in #119775, and really this is just exposing that we were already doing the wrong thing here. I don't think there's anything that needs to be done in this PR.

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! Lots of code churn, but fairly easy to follow. One small suggestion related to cbuffers which can be addressed later.

Copy link
Collaborator

@llvm-beanz llvm-beanz left a comment

Choose a reason for hiding this comment

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

One nit, otherwise LGTM.

class LLVMContext;
class MDTuple;
class TargetExtType;
Copy link
Collaborator

Choose a reason for hiding this comment

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

You can't derive from a forward-declared type so you must be including the header or depending on an include ordering.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. I've replaced this with an explicit include of DerivedTypes.h

@bogner bogner merged commit 482237e into llvm:main Dec 16, 2024
4 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:DirectX llvm:analysis Includes value tracking, cost tables and constant folding
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

4 participants