[llvm-branch-commits] [llvm] [DirectX] Update resource type names in DXIL metadata to include element type (PR #140937)

Helena Kotas via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed May 21 11:31:14 PDT 2025


https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/140937

>From 3f882eb22c0035e5f9dfe7b7324fb44a7a66dea8 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Wed, 21 May 2025 09:18:02 -0700
Subject: [PATCH 1/3] [DirectX] Update resource type names in DXIL metadata to
 include element type

---
 llvm/lib/Analysis/DXILResource.cpp            | 116 +++++++++++++++---
 .../DXILResource/buffer-frombinding.ll        |  10 +-
 .../CodeGen/DirectX/Metadata/cbuffer-only.ll  |   4 +-
 .../DirectX/Metadata/cbuffer_metadata.ll      |   6 +-
 .../DirectX/Metadata/resource-symbols.ll      |  16 +--
 .../CodeGen/DirectX/Metadata/srv_metadata.ll  |  33 +++--
 .../CodeGen/DirectX/Metadata/uav_metadata.ll  |  43 ++++---
 7 files changed, 152 insertions(+), 76 deletions(-)

diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp
index f642603306713..fc01fa98605d1 100644
--- a/llvm/lib/Analysis/DXILResource.cpp
+++ b/llvm/lib/Analysis/DXILResource.cpp
@@ -64,7 +64,7 @@ static StringRef getResourceKindName(ResourceKind RK) {
   case ResourceKind::TextureCubeArray:
     return "TextureCubeArray";
   case ResourceKind::TypedBuffer:
-    return "TypedBuffer";
+    return "Buffer";
   case ResourceKind::RawBuffer:
     return "RawBuffer";
   case ResourceKind::StructuredBuffer:
@@ -132,6 +132,44 @@ static StringRef getElementTypeName(ElementType ET) {
   llvm_unreachable("Unhandled ElementType");
 }
 
+static StringRef getElementTypeNameForTemplate(ElementType ET) {
+  switch (ET) {
+  case ElementType::I1:
+    return "bool";
+  case ElementType::I16:
+    return "int16_t";
+  case ElementType::U16:
+    return "uint16_t";
+  case ElementType::I32:
+    return "int32_t";
+  case ElementType::U32:
+    return "uint32_t";
+  case ElementType::I64:
+    return "int64_t";
+  case ElementType::U64:
+    return "uint32_t";
+  case ElementType::F16:
+  case ElementType::SNormF16:
+  case ElementType::UNormF16:
+    return "half";
+  case ElementType::F32:
+  case ElementType::SNormF32:
+  case ElementType::UNormF32:
+    return "float";
+  case ElementType::F64:
+  case ElementType::SNormF64:
+  case ElementType::UNormF64:
+    return "double";
+  case ElementType::PackedS8x32:
+    return "int8_t4_packed";
+  case ElementType::PackedU8x32:
+    return "uint8_t4_packed";
+  case ElementType::Invalid:
+    return "<invalid>";
+  }
+  llvm_unreachable("Unhandled ElementType");
+}
+
 static StringRef getSamplerTypeName(SamplerType ST) {
   switch (ST) {
   case SamplerType::Default:
@@ -219,11 +257,46 @@ ResourceTypeInfo::ResourceTypeInfo(TargetExtType *HandleTy,
 }
 
 static void formatTypeName(SmallString<64> &Dest, StringRef Name,
-                           bool isWriteable, bool isROV) {
-  Dest = isWriteable ? (isROV ? "RasterizerOrdered" : "RW") : "";
+                           bool IsWriteable, bool IsROV) {
+  Dest = IsWriteable ? (IsROV ? "RasterizerOrdered" : "RW") : "";
   Dest += Name;
 }
 
+static void formatTypeName(SmallString<64> &Dest, StringRef Name,
+                           bool IsWriteable, bool IsROV, Type *ContainedType,
+                           bool IsSigned) {
+  raw_svector_ostream DestStream(Dest);
+  if (IsWriteable)
+    DestStream << (IsROV ? "RasterizerOrdered" : "RW");
+  DestStream << Name;
+
+  if (ContainedType) {
+    StringRef ElementName;
+    ElementType ET = toDXILElementType(ContainedType, IsSigned);
+    if (ET != ElementType::Invalid) {
+      ElementName = getElementTypeNameForTemplate(ET);
+    } else if (StructType *ST = dyn_cast<StructType>(ContainedType)) {
+      if (!ST->hasName())
+        return;
+      ElementName = ST->getStructName();
+    } else {
+      llvm_unreachable("invalid element type for raw buffer");
+    }
+
+    if (const FixedVectorType *VTy = dyn_cast<FixedVectorType>(ContainedType))
+      DestStream << "<" << ElementName << VTy->getNumElements() << ">";
+    else
+      DestStream << "<" << ElementName << ">";
+  }
+}
+
+static StructType *getOrCreateElementStruct(Type *ElemType, StringRef Name) {
+  StructType *Ty = StructType::getTypeByName(ElemType->getContext(), Name);
+  if (Ty && Ty->getNumElements() == 1 && Ty->getElementType(0) == ElemType)
+    return Ty;
+  return StructType::create(ElemType, Name);
+}
+
 StructType *ResourceTypeInfo::createElementStruct() {
   SmallString<64> TypeName;
 
@@ -237,51 +310,56 @@ StructType *ResourceTypeInfo::createElementStruct() {
   case ResourceKind::TextureCubeArray: {
     auto *RTy = cast<TextureExtType>(HandleTy);
     formatTypeName(TypeName, getResourceKindName(Kind), RTy->isWriteable(),
-                   RTy->isROV());
-    return StructType::create(RTy->getResourceType(), TypeName);
+                   RTy->isROV(), RTy->getResourceType(), RTy->isSigned());
+    return getOrCreateElementStruct(RTy->getResourceType(), TypeName);
   }
   case ResourceKind::Texture2DMS:
   case ResourceKind::Texture2DMSArray: {
     auto *RTy = cast<MSTextureExtType>(HandleTy);
     formatTypeName(TypeName, getResourceKindName(Kind), RTy->isWriteable(),
-                   /*IsROV=*/false);
-    return StructType::create(RTy->getResourceType(), TypeName);
+                   /*IsROV=*/false, RTy->getResourceType(), RTy->isSigned());
+    return getOrCreateElementStruct(RTy->getResourceType(), TypeName);
   }
   case ResourceKind::TypedBuffer: {
     auto *RTy = cast<TypedBufferExtType>(HandleTy);
     formatTypeName(TypeName, getResourceKindName(Kind), RTy->isWriteable(),
-                   RTy->isROV());
-    return StructType::create(RTy->getResourceType(), TypeName);
+                   RTy->isROV(), RTy->getResourceType(), RTy->isSigned());
+    return getOrCreateElementStruct(RTy->getResourceType(), TypeName);
   }
   case ResourceKind::RawBuffer: {
     auto *RTy = cast<RawBufferExtType>(HandleTy);
     formatTypeName(TypeName, "ByteAddressBuffer", RTy->isWriteable(),
                    RTy->isROV());
-    return StructType::create(Type::getInt32Ty(HandleTy->getContext()),
-                              TypeName);
+    return getOrCreateElementStruct(Type::getInt32Ty(HandleTy->getContext()),
+                                    TypeName);
   }
   case ResourceKind::StructuredBuffer: {
     auto *RTy = cast<RawBufferExtType>(HandleTy);
+    Type *Ty = RTy->getResourceType();
     formatTypeName(TypeName, "StructuredBuffer", RTy->isWriteable(),
-                   RTy->isROV());
-    return StructType::create(RTy->getResourceType(), TypeName);
+                   RTy->isROV(), RTy->getResourceType(), true);
+    return getOrCreateElementStruct(Ty, TypeName);
   }
   case ResourceKind::FeedbackTexture2D:
   case ResourceKind::FeedbackTexture2DArray: {
     auto *RTy = cast<FeedbackTextureExtType>(HandleTy);
     TypeName = formatv("{0}<{1}>", getResourceKindName(Kind),
                        llvm::to_underlying(RTy->getFeedbackType()));
-    return StructType::create(Type::getInt32Ty(HandleTy->getContext()),
-                              TypeName);
+    return getOrCreateElementStruct(Type::getInt32Ty(HandleTy->getContext()),
+                                    TypeName);
+  }
+  case ResourceKind::CBuffer: {
+    auto *RTy = cast<CBufferExtType>(HandleTy);
+    LayoutExtType *LayoutType = cast<LayoutExtType>(RTy->getResourceType());
+    StructType *Ty = cast<StructType>(LayoutType->getWrappedType());
+    return StructType::create(Ty->elements(), getResourceKindName(Kind));
   }
-  case ResourceKind::CBuffer:
-    return StructType::create(HandleTy->getContext(), "cbuffer");
   case ResourceKind::Sampler: {
     auto *RTy = cast<SamplerExtType>(HandleTy);
     TypeName = formatv("SamplerState<{0}>",
                        llvm::to_underlying(RTy->getSamplerType()));
-    return StructType::create(Type::getInt32Ty(HandleTy->getContext()),
-                              TypeName);
+    return getOrCreateElementStruct(Type::getInt32Ty(HandleTy->getContext()),
+                                    TypeName);
   }
   case ResourceKind::TBuffer:
   case ResourceKind::RTAccelerationStructure:
diff --git a/llvm/test/Analysis/DXILResource/buffer-frombinding.ll b/llvm/test/Analysis/DXILResource/buffer-frombinding.ll
index 6c8476617e693..2623e6f4d44f1 100644
--- a/llvm/test/Analysis/DXILResource/buffer-frombinding.ll
+++ b/llvm/test/Analysis/DXILResource/buffer-frombinding.ll
@@ -53,7 +53,7 @@ define void @test_typedbuffer() {
   ; CHECK:     Lower Bound: 3
   ; CHECK:     Size: 24
   ; CHECK:   Class: SRV
-  ; CHECK:   Kind: TypedBuffer
+  ; CHECK:   Kind: Buffer
   ; CHECK:   Element Type: u32
   ; CHECK:   Element Count: 4
 
@@ -70,7 +70,7 @@ define void @test_typedbuffer() {
   ; CHECK:   Globally Coherent: 0
   ; CHECK:   Counter Direction: Unknown
   ; CHECK:   Class: UAV
-  ; CHECK:   Kind: TypedBuffer
+  ; CHECK:   Kind: Buffer
   ; CHECK:   IsROV: 0
   ; CHECK:   Element Type: i32
   ; CHECK:   Element Count: 1
@@ -89,7 +89,7 @@ define void @test_typedbuffer() {
   ; CHECK:   Globally Coherent: 0
   ; CHECK:   Counter Direction: Decrement
   ; CHECK:   Class: UAV
-  ; CHECK:   Kind: TypedBuffer
+  ; CHECK:   Kind: Buffer
   ; CHECK:   IsROV: 0
   ; CHECK:   Element Type: f32
   ; CHECK:   Element Count: 4
@@ -112,7 +112,7 @@ define void @test_typedbuffer() {
   ; CHECK:   Globally Coherent: 0
   ; CHECK:   Counter Direction: Increment
   ; CHECK:   Class: UAV
-  ; CHECK:   Kind: TypedBuffer
+  ; CHECK:   Kind: Buffer
   ; CHECK:   IsROV: 0
   ; CHECK:   Element Type: f32
   ; CHECK:   Element Count: 4
@@ -132,7 +132,7 @@ define void @test_typedbuffer() {
   ; CHECK:   Globally Coherent: 0
   ; CHECK:   Counter Direction: Invalid
   ; CHECK:   Class: UAV
-  ; CHECK:   Kind: TypedBuffer
+  ; CHECK:   Kind: Buffer
   ; CHECK:   IsROV: 0
   ; CHECK:   Element Type: f32
   ; CHECK:   Element Count: 4
diff --git a/llvm/test/CodeGen/DirectX/Metadata/cbuffer-only.ll b/llvm/test/CodeGen/DirectX/Metadata/cbuffer-only.ll
index 959150f4c2c6a..b88ac118b3568 100644
--- a/llvm/test/CodeGen/DirectX/Metadata/cbuffer-only.ll
+++ b/llvm/test/CodeGen/DirectX/Metadata/cbuffer-only.ll
@@ -9,11 +9,11 @@ target triple = "dxil-pc-shadermodel6.6-compute"
 define void @cbuffer_is_only_binding() {
   %cbuf = call target("dx.CBuffer", target("dx.Layout", {float}, 4, 0))
       @llvm.dx.resource.handlefrombinding(i32 1, i32 8, i32 1, i32 0, i1 false, ptr null)
-  ; CHECK: %cbuffer = type
+  ; CHECK: %CBuffer = type { float }
 
   ret void
 }
 
-; CHECK:      @[[CB0:.*]] = external constant %cbuffer
+; CHECK:      @[[CB0:.*]] = external constant %CBuffer
 
 ; CHECK: !{i32 0, ptr @[[CB0]], !""
diff --git a/llvm/test/CodeGen/DirectX/Metadata/cbuffer_metadata.ll b/llvm/test/CodeGen/DirectX/Metadata/cbuffer_metadata.ll
index 7f878c9be63f2..dc94a67ca7ed2 100644
--- a/llvm/test/CodeGen/DirectX/Metadata/cbuffer_metadata.ll
+++ b/llvm/test/CodeGen/DirectX/Metadata/cbuffer_metadata.ll
@@ -66,9 +66,9 @@ define void @test() #0 {
 
 attributes #0 = { noinline nounwind "hlsl.shader"="compute" }
 
-; CHECK: @CB1 = external constant %cbuffer
-; CHECK: @CB2 = external constant %cbuffer.0
-; CHECK: @MyConstants = external constant %cbuffer.1
+; CHECK: @CB1 = external constant %CBuffer
+; CHECK: @CB2 = external constant %CBuffer.0
+; CHECK: @MyConstants = external constant %CBuffer.1
 
 ; CHECK: !dx.resources = !{[[ResList:[!][0-9]+]]}
 
diff --git a/llvm/test/CodeGen/DirectX/Metadata/resource-symbols.ll b/llvm/test/CodeGen/DirectX/Metadata/resource-symbols.ll
index f2edcb37513e9..440457b3d415e 100644
--- a/llvm/test/CodeGen/DirectX/Metadata/resource-symbols.ll
+++ b/llvm/test/CodeGen/DirectX/Metadata/resource-symbols.ll
@@ -11,22 +11,22 @@ define void @test() {
   ; Buffer<float4>
   %float4 = call target("dx.TypedBuffer", <4 x float>, 0, 0, 0)
       @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false, ptr @A.str)
-  ; CHECK: %TypedBuffer = type { <4 x float> }
+  ; CHECK: %"Buffer<float4>" = type { <4 x float> }
 
   ; Buffer<int>
   %int = call target("dx.TypedBuffer", i32, 0, 0, 1)
       @llvm.dx.resource.handlefrombinding(i32 0, i32 1, i32 1, i32 0, i1 false, ptr null)
-  ; CHECK: %TypedBuffer.0 = type { i32 }
+  ; CHECK: %"Buffer<int32_t>" = type { i32 }
 
   ; Buffer<uint3>
   %uint3 = call target("dx.TypedBuffer", <3 x i32>, 0, 0, 0)
       @llvm.dx.resource.handlefrombinding(i32 0, i32 2, i32 1, i32 0, i1 false, ptr null)
-  ; CHECK: %TypedBuffer.1 = type { <3 x i32> }
+  ; CHECK: %"Buffer<uint32_t3>" = type { <3 x i32> }
 
   ; StructuredBuffer<S>
   %struct0 = call target("dx.RawBuffer", %struct.S, 0, 0)
       @llvm.dx.resource.handlefrombinding(i32 0, i32 10, i32 1, i32 0, i1 true, ptr @SB.str)
-  ; CHECK: %StructuredBuffer = type { %struct.S }
+  ; CHECK: %"StructuredBuffer<struct.S>" = type { %struct.S }
 
   ; ByteAddressBuffer
   %byteaddr = call target("dx.RawBuffer", i8, 0, 0)
@@ -36,10 +36,10 @@ define void @test() {
   ret void
 }
 
-; CHECK:      @[[T0:.*]] = external constant %TypedBuffer
-; CHECK-NEXT: @[[T1:.*]] = external constant %TypedBuffer.0
-; CHECK-NEXT: @[[T2:.*]] = external constant %TypedBuffer.1
-; CHECK-NEXT: @[[S0:.*]] = external constant %StructuredBuffer
+; CHECK:      @[[T0:.*]] = external constant %"Buffer<float4>"
+; CHECK-NEXT: @[[T1:.*]] = external constant %"Buffer<int32_t>"
+; CHECK-NEXT: @[[T2:.*]] = external constant %"Buffer<uint32_t3>"
+; CHECK-NEXT: @[[S0:.*]] = external constant %"StructuredBuffer<struct.S>"
 ; CHECK-NEXT: @[[B0:.*]] = external constant %ByteAddressBuffer
 
 ; CHECK: !{i32 0, ptr @[[T0]], !"A"
diff --git a/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll b/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll
index 725bc97ae39d4..abab5c9fb1166 100644
--- a/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll
+++ b/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll
@@ -78,25 +78,24 @@ define void @test() #0 {
 
 attributes #0 = { noinline nounwind "hlsl.shader"="compute" }
 
-; CHECK: %TypedBuffer = type { <4 x half> }
-; CHECK: %TypedBuffer.0 = type { <2 x float> }
-; CHECK: %TypedBuffer.1 = type { double }
-; CHECK: %TypedBuffer.2 = type { <4 x i32> }
+; CHECK: %"Buffer<half4>" = type { <4 x half> }
+; CHECK: %"Buffer<float2>" = type { <2 x float> }
+; CHECK: %"Buffer<double>" = type { double }
+; CHECK: %"Buffer<int32_t4>" = type { <4 x i32> }
 ; CHECK: %ByteAddressBuffer = type { i32 }
-; CHECK: %StructuredBuffer = type { i16 }
-; CHECK: %TypedBuffer.3 = type { i64 }
-; CHECK: %TypedBuffer.4 = type { <4 x float> }
-; CHECK: %TypedBuffer.5 = type { i64 }
-
-; CHECK: @Zero = external constant %TypedBuffer
-; CHECK: @One = external constant %TypedBuffer.0
-; CHECK: @Two = external constant %TypedBuffer.1
-; CHECK: @Three = external constant %TypedBuffer.2
+; CHECK: %"StructuredBuffer<int16_t>" = type { i16 }
+; CHECK: %"Buffer<uint32_t>" = type { i64 }
+; CHECK: %"Buffer<float4>" = type { <4 x float> }
+
+; CHECK: @Zero = external constant %"Buffer<half4>"
+; CHECK: @One = external constant %"Buffer<float2>"
+; CHECK: @Two = external constant %"Buffer<double>"
+; CHECK: @Three = external constant %"Buffer<int32_t4>"
 ; CHECK: @Four = external constant %ByteAddressBuffer
-; CHECK: @Five = external constant %StructuredBuffer
-; CHECK: @Six = external constant %TypedBuffer.3
-; CHECK: @Array = external constant %TypedBuffer.4
-; CHECK: @Seven = external constant %TypedBuffer.5
+; CHECK: @Five = external constant %"StructuredBuffer<int16_t>"
+; CHECK: @Six = external constant %"Buffer<uint32_t>"
+; CHECK: @Array = external constant %"Buffer<float4>"
+; CHECK: @Seven = external constant %"Buffer<uint32_t>"
 
 ; CHECK: !dx.resources = !{[[ResList:[!][0-9]+]]}
 
diff --git a/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll b/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll
index bc589ef1752b6..9893f8b9ea4d7 100644
--- a/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll
+++ b/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll
@@ -85,7 +85,7 @@ define void @test() #0 {
   %Array_42_h = call target("dx.TypedBuffer", <4 x float>, 1, 0, 0)
             @llvm.dx.resource.handlefrombinding(i32 3, i32 4, i32 100, i32 42, i1 false, ptr @Array.str)
 
-  ; Same buffer type as Nine
+  ; Same buffer type as Nine - should have the same type in metadata
   ; RWBuffer<double> Ten : register(u2);
   %Ten_h = call target("dx.TypedBuffer", i64, 1, 0, 0)
             @llvm.dx.resource.handlefrombinding(i32 5, i32 22, i32 1, i32 0, i1 false, ptr @Ten.str)
@@ -95,31 +95,30 @@ define void @test() #0 {
 
 attributes #0 = { noinline nounwind "hlsl.shader"="compute" }
 
-; CHECK: %RWTypedBuffer = type { <4 x half> }
-; CHECK: %RWTypedBuffer.0 = type { <2 x float> }
-; CHECK: %RWTypedBuffer.1 = type { double }
-; CHECK: %RWTypedBuffer.2 = type { <4 x i32> }
+; CHECK: %"RWBuffer<half4>" = type { <4 x half> }
+; CHECK: %"RWBuffer<float2>" = type { <2 x float> }
+; CHECK: %"RWBuffer<double>" = type { double }
+; CHECK: %"RWBuffer<int32_t4>" = type { <4 x i32> }
 ; CHECK: %RWByteAddressBuffer = type { i32 }
-; CHECK: %RWStructuredBuffer = type { i16 }
-; CHECK: %RasterizerOrderedTypedBuffer = type { <4 x i32> }
-; CHECK: %RasterizerOrderedStructuredBuffer = type { <4 x i32> }
+; CHECK: %"RWStructuredBuffer<int16_t>" = type { i16 }
+; CHECK: %"RasterizerOrderedBuffer<int32_t4>" = type { <4 x i32> }
+; CHECK: %"RasterizerOrderedStructuredBuffer<int32_t4>" = type { <4 x i32> }
 ; CHECK: %RasterizerOrderedByteAddressBuffer = type { i32 }
-; CHECK: %RWTypedBuffer.3 = type { i64 }
-; CHECK: %RWTypedBuffer.4 = type { <4 x float> }
-; CHECK: %RWTypedBuffer.5 = type { i64 }
-
-; CHECK: @Zero = external constant %RWTypedBuffer
-; CHECK: @One = external constant %RWTypedBuffer.0
-; CHECK: @Two = external constant %RWTypedBuffer.1
-; CHECK: @Three = external constant %RWTypedBuffer.2
+; CHECK: %"RWBuffer<uint32_t>" = type { i64 }
+; CHECK: %"RWBuffer<float4>" = type { <4 x float> }
+
+; CHECK: @Zero = external constant %"RWBuffer<half4>"
+; CHECK: @One = external constant %"RWBuffer<float2>"
+; CHECK: @Two = external constant %"RWBuffer<double>"
+; CHECK: @Three = external constant %"RWBuffer<int32_t4>"
 ; CHECK: @Four = external constant %RWByteAddressBuffer
-; CHECK: @Five = external constant %RWStructuredBuffer
-; CHECK: @Six = external constant %RasterizerOrderedTypedBuffer
-; CHECK: @Seven = external constant %RasterizerOrderedStructuredBuffer
+; CHECK: @Five = external constant %"RWStructuredBuffer<int16_t>"
+; CHECK: @Six = external constant %"RasterizerOrderedBuffer<int32_t4>"
+; CHECK: @Seven = external constant %"RasterizerOrderedStructuredBuffer<int32_t4>"
 ; CHECK: @Eight = external constant %RasterizerOrderedByteAddressBuffer
-; CHECK: @Nine = external constant %RWTypedBuffer.3
-; CHECK: @Array = external constant %RWTypedBuffer.4
-; CHECK: @Ten = external constant %RWTypedBuffer.5
+; CHECK: @Nine = external constant %"RWBuffer<uint32_t>"
+; CHECK: @Array = external constant %"RWBuffer<float4>"
+; CHECK: @Ten = external constant %"RWBuffer<uint32_t>"
 
 ; CHECK: !dx.resources = !{[[ResList:[!][0-9]+]]}
 

>From b466f2a89e7f527a90fb5878a1acabe9aad26933 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Wed, 21 May 2025 09:56:24 -0700
Subject: [PATCH 2/3] Add cbuffer name to cbuffer type, it's a unique type

---
 llvm/include/llvm/Analysis/DXILResource.h           |  2 +-
 llvm/lib/Analysis/DXILResource.cpp                  |  9 +++++++--
 llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp   |  3 ++-
 .../CodeGen/DirectX/Metadata/cbuffer_metadata.ll    | 13 ++++++-------
 4 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h
index a274e2294561e..6e523341171bf 100644
--- a/llvm/include/llvm/Analysis/DXILResource.h
+++ b/llvm/include/llvm/Analysis/DXILResource.h
@@ -297,7 +297,7 @@ class ResourceTypeInfo {
       : ResourceTypeInfo(HandleTy, {}, dxil::ResourceKind::Invalid) {}
 
   TargetExtType *getHandleTy() const { return HandleTy; }
-  StructType *createElementStruct();
+  StructType *createElementStruct(StringRef CBufferName = "");
 
   // Conditions to check before accessing specific views.
   bool isUAV() const;
diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp
index fc01fa98605d1..6a68d5189f580 100644
--- a/llvm/lib/Analysis/DXILResource.cpp
+++ b/llvm/lib/Analysis/DXILResource.cpp
@@ -297,7 +297,7 @@ static StructType *getOrCreateElementStruct(Type *ElemType, StringRef Name) {
   return StructType::create(ElemType, Name);
 }
 
-StructType *ResourceTypeInfo::createElementStruct() {
+StructType *ResourceTypeInfo::createElementStruct(StringRef CBufferName) {
   SmallString<64> TypeName;
 
   switch (Kind) {
@@ -352,7 +352,12 @@ StructType *ResourceTypeInfo::createElementStruct() {
     auto *RTy = cast<CBufferExtType>(HandleTy);
     LayoutExtType *LayoutType = cast<LayoutExtType>(RTy->getResourceType());
     StructType *Ty = cast<StructType>(LayoutType->getWrappedType());
-    return StructType::create(Ty->elements(), getResourceKindName(Kind));
+    SmallString<64> Name = getResourceKindName(Kind);
+    if (!CBufferName.empty()) {
+      Name.append(".");
+      Name.append(CBufferName);
+    }
+    return StructType::create(Ty->elements(), Name);
   }
   case ResourceKind::Sampler: {
     auto *RTy = cast<SamplerExtType>(HandleTy);
diff --git a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
index e0dce3d750ed1..e08e071f3f6f6 100644
--- a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
+++ b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
@@ -78,7 +78,8 @@ static NamedMDNode *emitResourceMetadata(Module &M, DXILResourceMap &DRM,
 
   for (ResourceInfo &RI : DRM)
     if (!RI.hasSymbol())
-      RI.createSymbol(M, DRTM[RI.getHandleTy()].createElementStruct());
+      RI.createSymbol(M,
+                      DRTM[RI.getHandleTy()].createElementStruct(RI.getName()));
 
   SmallVector<Metadata *> SRVs, UAVs, CBufs, Smps;
   for (const ResourceInfo &RI : DRM.srvs())
diff --git a/llvm/test/CodeGen/DirectX/Metadata/cbuffer_metadata.ll b/llvm/test/CodeGen/DirectX/Metadata/cbuffer_metadata.ll
index dc94a67ca7ed2..9b3e8454552c2 100644
--- a/llvm/test/CodeGen/DirectX/Metadata/cbuffer_metadata.ll
+++ b/llvm/test/CodeGen/DirectX/Metadata/cbuffer_metadata.ll
@@ -11,7 +11,6 @@ target triple = "dxil-pc-shadermodel6.6-compute"
 
 %__cblayout_CB2 = type <{ float, double, float, half, i16, i64, i32 }>
 @CB2.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB2, 36, 0, 8, 16, 20, 22, 24, 32)) poison
- at CB2.str = private unnamed_addr constant [4 x i8] c"CB2\00", align 1
 
 %__cblayout_MyConstants = type <{ double, <3 x float>, float, <3 x double>, half, <2 x double>, float, <3 x half>, <3 x half> }>
 @MyConstants.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_MyConstants, 96, 0, 16, 28, 32, 56, 64, 80, 84, 90)) poison
@@ -22,7 +21,7 @@ target triple = "dxil-pc-shadermodel6.6-compute"
 ; PRINT-NEXT:; Name                                 Type  Format         Dim      ID      HLSL Bind  Count
 ; PRINT-NEXT:; ------------------------------ ---------- ------- ----------- ------- -------------- ------
 ; PRINT-NEXT:; CB1                               cbuffer      NA          NA     CB0            cb0     1
-; PRINT-NEXT:; CB2                               cbuffer      NA          NA     CB1            cb1     1
+; PRINT-NEXT:;                                   cbuffer      NA          NA     CB1            cb1     1
 ; PRINT-NEXT:; MyConstants                       cbuffer      NA          NA     CB2    cb5,space15     1
 
 define void @test() #0 {
@@ -46,7 +45,7 @@ define void @test() #0 {
   ;}
 
   %CB2.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB2, 36, 0, 8, 16, 20, 22, 24, 32))
-            @llvm.dx.resource.handlefrombinding(i32 0, i32 1, i32 1, i32 0, i1 false, ptr @CB2.str)
+            @llvm.dx.resource.handlefrombinding(i32 0, i32 1, i32 1, i32 0, i1 false, ptr null)
   ; cbuffer CB3 : register(b5) {
   ;   double B0;
   ;   float3 B1;
@@ -66,14 +65,14 @@ define void @test() #0 {
 
 attributes #0 = { noinline nounwind "hlsl.shader"="compute" }
 
-; CHECK: @CB1 = external constant %CBuffer
-; CHECK: @CB2 = external constant %CBuffer.0
-; CHECK: @MyConstants = external constant %CBuffer.1
+; CHECK: @CB1 = external constant %CBuffer.CB1
+; CHECK: @0 = external constant %CBuffer
+; CHECK: @MyConstants = external constant %CBuffer.MyConstants
 
 ; CHECK: !dx.resources = !{[[ResList:[!][0-9]+]]}
 
 ; CHECK: [[ResList]] = !{null, null, [[CBList:[!][0-9]+]], null}
 ; CHECK: [[CBList]] = !{![[CB1:[0-9]+]], ![[CB2:[0-9]+]], ![[MYCONSTANTS:[0-9]+]]}
 ; CHECK: ![[CB1]] = !{i32 0, ptr @CB1, !"CB1", i32 0, i32 0, i32 1, i32 24, null}
-; CHECK: ![[CB2]] = !{i32 1, ptr @CB2, !"CB2", i32 0, i32 1, i32 1, i32 36, null}
+; CHECK: ![[CB2]] = !{i32 1, ptr @0, !"", i32 0, i32 1, i32 1, i32 36, null}
 ; CHECK: ![[MYCONSTANTS]] = !{i32 2, ptr @MyConstants, !"MyConstants", i32 15, i32 5, i32 1, i32 96, null}

>From 1c12e6524bc2b5ebf4de6ab37e88fa095c18abe4 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Wed, 21 May 2025 11:30:48 -0700
Subject: [PATCH 3/3] Refactor formatTypeName, add CB2 back to test

---
 llvm/lib/Analysis/DXILResource.cpp            | 45 +++++++++----------
 .../DirectX/Metadata/cbuffer_metadata.ll      |  9 ++--
 2 files changed, 26 insertions(+), 28 deletions(-)

diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp
index 6a68d5189f580..1fb1340263cea 100644
--- a/llvm/lib/Analysis/DXILResource.cpp
+++ b/llvm/lib/Analysis/DXILResource.cpp
@@ -257,37 +257,34 @@ ResourceTypeInfo::ResourceTypeInfo(TargetExtType *HandleTy,
 }
 
 static void formatTypeName(SmallString<64> &Dest, StringRef Name,
-                           bool IsWriteable, bool IsROV) {
-  Dest = IsWriteable ? (IsROV ? "RasterizerOrdered" : "RW") : "";
-  Dest += Name;
-}
-
-static void formatTypeName(SmallString<64> &Dest, StringRef Name,
-                           bool IsWriteable, bool IsROV, Type *ContainedType,
-                           bool IsSigned) {
+                           bool IsWriteable, bool IsROV,
+                           Type *ContainedType = nullptr,
+                           bool IsSigned = true) {
   raw_svector_ostream DestStream(Dest);
   if (IsWriteable)
     DestStream << (IsROV ? "RasterizerOrdered" : "RW");
   DestStream << Name;
 
-  if (ContainedType) {
-    StringRef ElementName;
-    ElementType ET = toDXILElementType(ContainedType, IsSigned);
-    if (ET != ElementType::Invalid) {
-      ElementName = getElementTypeNameForTemplate(ET);
-    } else if (StructType *ST = dyn_cast<StructType>(ContainedType)) {
-      if (!ST->hasName())
-        return;
-      ElementName = ST->getStructName();
-    } else {
-      llvm_unreachable("invalid element type for raw buffer");
-    }
+  if (!ContainedType)
+    return;
 
-    if (const FixedVectorType *VTy = dyn_cast<FixedVectorType>(ContainedType))
-      DestStream << "<" << ElementName << VTy->getNumElements() << ">";
-    else
-      DestStream << "<" << ElementName << ">";
+  StringRef ElementName;
+  ElementType ET = toDXILElementType(ContainedType, IsSigned);
+  if (ET != ElementType::Invalid) {
+    ElementName = getElementTypeNameForTemplate(ET);
+  } else {
+    assert(isa<StructType>(ContainedType) &&
+           "invalid element type for raw buffer");
+    StructType *ST = cast<StructType>(ContainedType);
+    if (!ST->hasName())
+      return;
+    ElementName = ST->getStructName();
   }
+
+  DestStream << "<" << ElementName;
+  if (const FixedVectorType *VTy = dyn_cast<FixedVectorType>(ContainedType))
+    DestStream << VTy->getNumElements();
+  DestStream << ">";
 }
 
 static StructType *getOrCreateElementStruct(Type *ElemType, StringRef Name) {
diff --git a/llvm/test/CodeGen/DirectX/Metadata/cbuffer_metadata.ll b/llvm/test/CodeGen/DirectX/Metadata/cbuffer_metadata.ll
index 9b3e8454552c2..2699d9ae6e8c1 100644
--- a/llvm/test/CodeGen/DirectX/Metadata/cbuffer_metadata.ll
+++ b/llvm/test/CodeGen/DirectX/Metadata/cbuffer_metadata.ll
@@ -11,6 +11,7 @@ target triple = "dxil-pc-shadermodel6.6-compute"
 
 %__cblayout_CB2 = type <{ float, double, float, half, i16, i64, i32 }>
 @CB2.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB2, 36, 0, 8, 16, 20, 22, 24, 32)) poison
+ at CB2.str = private unnamed_addr constant [4 x i8] c"CB2\00", align 1
 
 %__cblayout_MyConstants = type <{ double, <3 x float>, float, <3 x double>, half, <2 x double>, float, <3 x half>, <3 x half> }>
 @MyConstants.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_MyConstants, 96, 0, 16, 28, 32, 56, 64, 80, 84, 90)) poison
@@ -21,7 +22,7 @@ target triple = "dxil-pc-shadermodel6.6-compute"
 ; PRINT-NEXT:; Name                                 Type  Format         Dim      ID      HLSL Bind  Count
 ; PRINT-NEXT:; ------------------------------ ---------- ------- ----------- ------- -------------- ------
 ; PRINT-NEXT:; CB1                               cbuffer      NA          NA     CB0            cb0     1
-; PRINT-NEXT:;                                   cbuffer      NA          NA     CB1            cb1     1
+; PRINT-NEXT:; CB2                               cbuffer      NA          NA     CB1            cb1     1
 ; PRINT-NEXT:; MyConstants                       cbuffer      NA          NA     CB2    cb5,space15     1
 
 define void @test() #0 {
@@ -45,7 +46,7 @@ define void @test() #0 {
   ;}
 
   %CB2.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB2, 36, 0, 8, 16, 20, 22, 24, 32))
-            @llvm.dx.resource.handlefrombinding(i32 0, i32 1, i32 1, i32 0, i1 false, ptr null)
+            @llvm.dx.resource.handlefrombinding(i32 0, i32 1, i32 1, i32 0, i1 false, ptr @CB2.str)
   ; cbuffer CB3 : register(b5) {
   ;   double B0;
   ;   float3 B1;
@@ -66,7 +67,7 @@ define void @test() #0 {
 attributes #0 = { noinline nounwind "hlsl.shader"="compute" }
 
 ; CHECK: @CB1 = external constant %CBuffer.CB1
-; CHECK: @0 = external constant %CBuffer
+; CHECK: @CB2 = external constant %CBuffer.CB2
 ; CHECK: @MyConstants = external constant %CBuffer.MyConstants
 
 ; CHECK: !dx.resources = !{[[ResList:[!][0-9]+]]}
@@ -74,5 +75,5 @@ attributes #0 = { noinline nounwind "hlsl.shader"="compute" }
 ; CHECK: [[ResList]] = !{null, null, [[CBList:[!][0-9]+]], null}
 ; CHECK: [[CBList]] = !{![[CB1:[0-9]+]], ![[CB2:[0-9]+]], ![[MYCONSTANTS:[0-9]+]]}
 ; CHECK: ![[CB1]] = !{i32 0, ptr @CB1, !"CB1", i32 0, i32 0, i32 1, i32 24, null}
-; CHECK: ![[CB2]] = !{i32 1, ptr @0, !"", i32 0, i32 1, i32 1, i32 36, null}
+; CHECK: ![[CB2]] = !{i32 1, ptr @CB2, !"CB2", i32 0, i32 1, i32 1, i32 36, null}
 ; CHECK: ![[MYCONSTANTS]] = !{i32 2, ptr @MyConstants, !"MyConstants", i32 15, i32 5, i32 1, i32 96, null}



More information about the llvm-branch-commits mailing list