[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
Thu May 22 21:42:04 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/4] [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/4] 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/4] 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}
>From a52dd679b4add6a5e1ef5b94eafa60d2a6689b62 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Thu, 22 May 2025 21:41:45 -0700
Subject: [PATCH 4/4] fix analysis unit test for cbuffer
---
llvm/unittests/Analysis/DXILResourceTest.cpp | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/llvm/unittests/Analysis/DXILResourceTest.cpp b/llvm/unittests/Analysis/DXILResourceTest.cpp
index f6d6ddf9cbb2d..ee37fad04f389 100644
--- a/llvm/unittests/Analysis/DXILResourceTest.cpp
+++ b/llvm/unittests/Analysis/DXILResourceTest.cpp
@@ -367,10 +367,12 @@ TEST(DXILResource, AnnotationsAndMetadata) {
// cbuffer cb0 { float4 g_X; float4 g_Y; }
{
- StructType *CBufType0 =
+ StructType *CBufStruct =
StructType::create(Context, {Floatx4Ty, Floatx4Ty}, "cb0");
- ResourceTypeInfo RTI(llvm::TargetExtType::get(Context, "dx.CBuffer",
- CBufType0, {/*Size=*/32}));
+ TargetExtType *CBufLayoutType =
+ llvm::TargetExtType::get(Context, "dx.Layout", CBufStruct, {32, 0, 16});
+ ResourceTypeInfo RTI(
+ llvm::TargetExtType::get(Context, "dx.CBuffer", CBufLayoutType));
EXPECT_EQ(RTI.getResourceClass(), ResourceClass::CBuffer);
EXPECT_EQ(RTI.getCBufferSize(DL), 32u);
EXPECT_EQ(RTI.getResourceKind(), ResourceKind::CBuffer);
More information about the llvm-branch-commits
mailing list