Skip to content

[DirectX] Use resource names when generating DXIL metadata #140635

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 11 commits into from
May 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion llvm/lib/Analysis/DXILResource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ MDTuple *ResourceInfo::getAsMetadata(Module &M,
MDVals.push_back(getIntMD(Binding.RecordID));
assert(Symbol && "Cannot yet create useful resource metadata without symbol");
MDVals.push_back(ValueAsMetadata::get(Symbol));
MDVals.push_back(MDString::get(Ctx, Symbol->getName()));
MDVals.push_back(MDString::get(Ctx, Name));
MDVals.push_back(getIntMD(Binding.Space));
MDVals.push_back(getIntMD(Binding.LowerBound));
MDVals.push_back(getIntMD(Binding.Size));
Expand Down
38 changes: 20 additions & 18 deletions llvm/test/CodeGen/DirectX/Metadata/cbuffer_metadata.ll
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,23 @@ target triple = "dxil-pc-shadermodel6.6-compute"

%__cblayout_CB1 = type <{ float, i32, double, <2 x i32> }>
@CB1.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB1, 24, 0, 4, 8, 16)) poison
@CB1.str = private unnamed_addr constant [4 x i8] c"CB1\00", align 1

%__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
@CB2.str = private unnamed_addr constant [4 x i8] c"CB2\00", align 1

%__cblayout_CB3 = type <{ double, <3 x float>, float, <3 x double>, half, <2 x double>, float, <3 x half>, <3 x half> }>
@CB3.cb = global target("dx.CBuffer", target("dx.Layout", %__cblayout_CB3, 96, 0, 16, 28, 32, 56, 64, 80, 84, 90)) poison
%__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
@MyConstants.str = private unnamed_addr constant [12 x i8] c"MyConstants\00", align 1

; PRINT:; Resource Bindings:
; PRINT-NEXT:;
; PRINT-NEXT:; Name Type Format Dim ID HLSL Bind Count
; PRINT-NEXT:; ------------------------------ ---------- ------- ----------- ------- -------------- ------
; PRINT-NEXT:; cbuffer NA NA CB0 cb0 1
; PRINT-NEXT:; cbuffer NA NA CB1 cb1 1
; PRINT-NEXT:; cbuffer NA NA CB2 cb5,space15 1
; PRINT-NEXT:; CB1 cbuffer NA NA CB0 cb0 1
; PRINT-NEXT:; CB2 cbuffer NA NA CB1 cb1 1
; PRINT-NEXT:; MyConstants cbuffer NA NA CB2 cb5,space15 1

define void @test() #0 {

Expand All @@ -31,9 +34,7 @@ define void @test() #0 {
; int2 d;
; }
%CB1.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB1, 24, 0, 4, 8, 16))
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false, ptr null)
store target("dx.CBuffer", target("dx.Layout", %__cblayout_CB1, 24, 0, 4, 8, 16)) %CB1.cb_h, ptr @CB1.cb, align 4

@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false, ptr @CB1.str)
; cbuffer CB2 : register(b0) {
; float a;
; double b;
Expand All @@ -45,9 +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)
store target("dx.CBuffer", target("dx.Layout", %__cblayout_CB2, 36, 0, 8, 16, 20, 22, 24, 32)) %CB2.cb_h, ptr @CB2.cb, align 4

@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;
Expand All @@ -59,19 +58,22 @@ define void @test() #0 {
; half3 B7;
; half3 B8;
; }
%CB3.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB3, 96, 0, 16, 28, 32, 56, 64, 80, 84, 90))
@llvm.dx.resource.handlefrombinding(i32 15, i32 5, i32 1, i32 0, i1 false, ptr null)
store target("dx.CBuffer", target("dx.Layout", %__cblayout_CB3, 96, 0, 16, 28, 32, 56, 64, 80, 84, 90)) %CB3.cb_h, ptr @CB3.cb, align 4
%CB3.cb_h = call target("dx.CBuffer", target("dx.Layout", %__cblayout_MyConstants, 96, 0, 16, 28, 32, 56, 64, 80, 84, 90))
@llvm.dx.resource.handlefrombinding(i32 15, i32 5, i32 1, i32 0, i1 false, ptr @MyConstants.str)

ret void
}

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: !dx.resources = !{[[ResList:[!][0-9]+]]}

; CHECK: [[ResList]] = !{null, null, [[CBList:[!][0-9]+]], null}
; CHECK: [[CBList]] = !{![[CB1:[0-9]+]], ![[CB2:[0-9]+]], ![[CB3:[0-9]+]]}
; CHECK: ![[CB1]] = !{i32 0, ptr @0, !"", i32 0, i32 0, i32 1, i32 24, null}
; CHECK: ![[CB2]] = !{i32 1, ptr @1, !"", i32 0, i32 1, i32 1, i32 36, null}
; CHECK: ![[CB3]] = !{i32 2, ptr @2, !"", i32 15, i32 5, i32 1, i32 96, 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: ![[MYCONSTANTS]] = !{i32 2, ptr @MyConstants, !"MyConstants", i32 15, i32 5, i32 1, i32 96, null}
11 changes: 7 additions & 4 deletions llvm/test/CodeGen/DirectX/Metadata/resource-symbols.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

target triple = "dxil-pc-shadermodel6.6-compute"

@A.str = private unnamed_addr constant [2 x i8] c"A\00", align 1
@SB.str = private unnamed_addr constant [3 x i8] c"SB\00", align 1

%struct.S = type { <4 x float>, <4 x i32> }

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 null)
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false, ptr @A.str)
; CHECK: %TypedBuffer = type { <4 x float> }

; Buffer<int>
Expand All @@ -22,7 +25,7 @@ define void @test() {

; 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 null)
@llvm.dx.resource.handlefrombinding(i32 0, i32 10, i32 1, i32 0, i1 true, ptr @SB.str)
; CHECK: %StructuredBuffer = type { %struct.S }

; ByteAddressBuffer
Expand All @@ -39,10 +42,10 @@ define void @test() {
; CHECK-NEXT: @[[S0:.*]] = external constant %StructuredBuffer
; CHECK-NEXT: @[[B0:.*]] = external constant %ByteAddressBuffer

; CHECK: !{i32 0, ptr @[[T0]], !""
; CHECK: !{i32 0, ptr @[[T0]], !"A"
; CHECK: !{i32 1, ptr @[[T1]], !""
; CHECK: !{i32 2, ptr @[[T2]], !""
; CHECK: !{i32 3, ptr @[[S0]], !""
; CHECK: !{i32 3, ptr @[[S0]], !"SB"
; CHECK: !{i32 4, ptr @[[B0]], !""

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) }
122 changes: 64 additions & 58 deletions llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll
Original file line number Diff line number Diff line change
Expand Up @@ -5,112 +5,118 @@
target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64"
target triple = "dxil-pc-shadermodel6.6-compute"

%"class.hlsl::Buffer" = type { target("dx.TypedBuffer", <4 x half>, 0, 0, 0) }
%"class.hlsl::Buffer.1" = type { target("dx.TypedBuffer", <2 x float>, 0, 0, 0) }
%"class.hlsl::Buffer.2" = type { target("dx.TypedBuffer", double, 0, 0, 0) }
%"class.hlsl::Buffer.3" = type { target("dx.TypedBuffer", i32, 0, 0, 1) }
%"class.hlsl::ByteAddressBuffer" = type { target("dx.RawBuffer", i8, 0, 0) }
%"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", i16, 0, 0) }
%"class.hlsl::Buffer.4" = type { target("dx.TypedBuffer", i64, 0, 0, 0) }

@Zero = internal global %"class.hlsl::Buffer" poison, align 4
@One = internal global %"class.hlsl::Buffer.1" poison, align 4
@Two = internal global %"class.hlsl::Buffer.2" poison, align 4
@Three = internal global %"class.hlsl::Buffer.3" poison, align 4
@Four = internal global %"class.hlsl::ByteAddressBuffer" poison, align 4
@Five = internal global %"class.hlsl::StructuredBuffer" poison, align 4
@Six = internal global %"class.hlsl::Buffer.4" poison, align 4
@Zero.str = private unnamed_addr constant [5 x i8] c"Zero\00", align 1
@One.str = private unnamed_addr constant [4 x i8] c"One\00", align 1
@Two.str = private unnamed_addr constant [4 x i8] c"Two\00", align 1
@Three.str = private unnamed_addr constant [6 x i8] c"Three\00", align 1
@Four.str = private unnamed_addr constant [5 x i8] c"Four\00", align 1
@Five.str = private unnamed_addr constant [5 x i8] c"Five\00", align 1
@Six.str = private unnamed_addr constant [4 x i8] c"Six\00", align 1
@Seven.str = private unnamed_addr constant [6 x i8] c"Seven\00", align 1
@Array.str = private unnamed_addr constant [6 x i8] c"Array\00", align 1

; PRINT:; Resource Bindings:
; PRINT-NEXT:;
; PRINT-NEXT:; Name Type Format Dim ID HLSL Bind Count
; PRINT-NEXT:; ------------------------------ ---------- ------- ----------- ------- -------------- ------
; PRINT-NEXT:; texture f16 buf T0 t0 1
; PRINT-NEXT:; texture f32 buf T1 t1 1
; PRINT-NEXT:; texture f64 buf T2 t2 1
; PRINT-NEXT:; texture i32 buf T3 t3 1
; PRINT-NEXT:; texture byte r/o T4 t5 1
; PRINT-NEXT:; texture struct r/o T5 t6 1
; PRINT-NEXT:; texture u64 buf T6 t10,space2 1
; PRINT-NEXT:; texture f32 buf T7 t4,space3 100
; PRINT-NEXT:; Zero texture f16 buf T0 t0 1
; PRINT-NEXT:; One texture f32 buf T1 t1 1
; PRINT-NEXT:; Two texture f64 buf T2 t2 1
; PRINT-NEXT:; Three texture i32 buf T3 t3 1
; PRINT-NEXT:; Four texture byte r/o T4 t5 1
; PRINT-NEXT:; Five texture struct r/o T5 t6 1
; PRINT-NEXT:; Six texture u64 buf T6 t10,space2 1
; PRINT-NEXT:; Array texture f32 buf T7 t4,space3 100
; PRINT-NEXT:; Seven texture u64 buf T8 t20,space5 1
;

define void @test() #0 {
; Buffer<half4> Buf : register(t0)
; Buffer<half4> Zero : register(t0)
%Zero_h = call target("dx.TypedBuffer", <4 x half>, 0, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false, ptr null)
store target("dx.TypedBuffer", <4 x half>, 0, 0, 0) %Zero_h, ptr @Zero, align 4
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false, ptr @Zero.str)

; Buffer<float4> Buf : register(t1)
; Buffer<float4> One : register(t1)
%One_h = call target("dx.TypedBuffer", <2 x float>, 0, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 0, i32 1, i32 1, i32 0, i1 false, ptr null)
store target("dx.TypedBuffer", <2 x float>, 0, 0, 0) %One_h, ptr @One, align 4
@llvm.dx.resource.handlefrombinding(i32 0, i32 1, i32 1, i32 0, i1 false, ptr @One.str)

; Buffer<double> Two : register(t2);
%Two_h = call target("dx.TypedBuffer", double, 0, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 0, i32 2, i32 1, i32 0, i1 false, ptr null)
store target("dx.TypedBuffer", double, 0, 0, 0) %Two_h, ptr @Two, align 4
@llvm.dx.resource.handlefrombinding(i32 0, i32 2, i32 1, i32 0, i1 false, ptr @Two.str)

; Buffer<int4> Three : register(t3);
%Three_h = call target("dx.TypedBuffer", <4 x i32>, 0, 0, 1)
@llvm.dx.resource.handlefrombinding(i32 0, i32 3, i32 1, i32 0, i1 false, ptr null)
store target("dx.TypedBuffer", <4 x i32>, 0, 0, 1) %Three_h, ptr @Three, align 4
@llvm.dx.resource.handlefrombinding(i32 0, i32 3, i32 1, i32 0, i1 false, ptr @Three.str)

; ByteAddressBuffer Four : register(t4)
%Four_h = call target("dx.RawBuffer", i8, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 0, i32 5, i32 1, i32 0, i1 false, ptr null)
store target("dx.RawBuffer", i8, 0, 0) %Four_h, ptr @Four, align 4
@llvm.dx.resource.handlefrombinding(i32 0, i32 5, i32 1, i32 0, i1 false, ptr @Four.str)

; StructuredBuffer<int16_t> Five : register(t6);
%Five_h = call target("dx.RawBuffer", i16, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 0, i32 6, i32 1, i32 0, i1 false, ptr null)
store target("dx.RawBuffer", i16, 0, 0) %Five_h, ptr @Five, align 4
@llvm.dx.resource.handlefrombinding(i32 0, i32 6, i32 1, i32 0, i1 false, ptr @Five.str)

; Buffer<double> Six : register(t10, space2);
%Six_h = call target("dx.TypedBuffer", i64, 0, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 2, i32 10, i32 1, i32 0, i1 false, ptr null)
store target("dx.TypedBuffer", i64, 0, 0, 0) %Six_h, ptr @Six, align 4
@llvm.dx.resource.handlefrombinding(i32 2, i32 10, i32 1, i32 0, i1 false, ptr @Six.str)

; Same buffer type as Six - should have the same type in metadata
; Buffer<double> Seven : register(t10, space2);
%Seven_h = call target("dx.TypedBuffer", i64, 0, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 5, i32 20, i32 1, i32 0, i1 false, ptr @Seven.str)

; Buffer<float4> Array[100] : register(t4, space3);
; Buffer<float4> B1 = Array[30];
; Buffer<float4> B1 = Array[42];
; resource array accesses should produce one metadata entry
%Array_30_h = call target("dx.TypedBuffer", <4 x float>, 0, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 3, i32 4, i32 100, i32 30, i1 false, ptr null)
@llvm.dx.resource.handlefrombinding(i32 3, i32 4, i32 100, i32 30, i1 false, ptr @Array.str)
%Array_42_h = call target("dx.TypedBuffer", <4 x float>, 0, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 3, i32 4, i32 100, i32 42, i1 false, ptr null)
@llvm.dx.resource.handlefrombinding(i32 3, i32 4, i32 100, i32 42, i1 false, ptr @Array.str)

ret void
}

attributes #0 = { noinline nounwind "hlsl.shader"="compute" }

; CHECK: @0 = external constant %TypedBuffer
; CHECK: @1 = external constant %TypedBuffer.0
; CHECK: @2 = external constant %TypedBuffer.1
; CHECK: @3 = external constant %TypedBuffer.2
; CHECK: @4 = external constant %ByteAddressBuffer
; CHECK: @5 = external constant %StructuredBuffer
; CHECK: @6 = external constant %TypedBuffer.3
; CHECK: @7 = external constant %TypedBuffer.4
; 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: %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: @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: !dx.resources = !{[[ResList:[!][0-9]+]]}

; CHECK: [[ResList]] = !{[[SRVList:[!][0-9]+]], null, null, null}
; CHECK: [[SRVList]] = !{![[Zero:[0-9]+]], ![[One:[0-9]+]], ![[Two:[0-9]+]],
; CHECK-SAME: ![[Three:[0-9]+]], ![[Four:[0-9]+]], ![[Five:[0-9]+]],
; CHECK-SAME: ![[Six:[0-9]+]], ![[Array:[0-9]+]]}
; CHECK-SAME: ![[Six:[0-9]+]], ![[Array:[0-9]+]], ![[Seven:[0-9]+]]}

; CHECK: ![[Zero]] = !{i32 0, ptr @0, !"", i32 0, i32 0, i32 1, i32 10, i32 0, ![[Half:[0-9]+]]}
; CHECK: ![[Zero]] = !{i32 0, ptr @Zero, !"Zero", i32 0, i32 0, i32 1, i32 10, i32 0, ![[Half:[0-9]+]]}
; CHECK: ![[Half]] = !{i32 0, i32 8}
; CHECK: ![[One]] = !{i32 1, ptr @1, !"", i32 0, i32 1, i32 1, i32 10, i32 0, ![[Float:[0-9]+]]}
; CHECK: ![[One]] = !{i32 1, ptr @One, !"One", i32 0, i32 1, i32 1, i32 10, i32 0, ![[Float:[0-9]+]]}
; CHECK: ![[Float]] = !{i32 0, i32 9}
; CHECK: ![[Two]] = !{i32 2, ptr @2, !"", i32 0, i32 2, i32 1, i32 10, i32 0, ![[Double:[0-9]+]]}
; CHECK: ![[Two]] = !{i32 2, ptr @Two, !"Two", i32 0, i32 2, i32 1, i32 10, i32 0, ![[Double:[0-9]+]]}
; CHECK: ![[Double]] = !{i32 0, i32 10}
; CHECK: ![[Three]] = !{i32 3, ptr @3, !"", i32 0, i32 3, i32 1, i32 10, i32 0, ![[I32:[0-9]+]]}
; CHECK: ![[Three]] = !{i32 3, ptr @Three, !"Three", i32 0, i32 3, i32 1, i32 10, i32 0, ![[I32:[0-9]+]]}
; CHECK: ![[I32]] = !{i32 0, i32 4}
; CHECK: ![[Four]] = !{i32 4, ptr @4, !"", i32 0, i32 5, i32 1, i32 11, i32 0, null}
; CHECK: ![[Five]] = !{i32 5, ptr @5, !"", i32 0, i32 6, i32 1, i32 12, i32 0, ![[FiveStride:[0-9]+]]}
; CHECK: ![[Four]] = !{i32 4, ptr @Four, !"Four", i32 0, i32 5, i32 1, i32 11, i32 0, null}
; CHECK: ![[Five]] = !{i32 5, ptr @Five, !"Five", i32 0, i32 6, i32 1, i32 12, i32 0, ![[FiveStride:[0-9]+]]}
; CHECK: ![[FiveStride]] = !{i32 1, i32 2}
; CHECK: ![[Six]] = !{i32 6, ptr @6, !"", i32 2, i32 10, i32 1, i32 10, i32 0, ![[U64:[0-9]+]]}
; CHECK: ![[Six]] = !{i32 6, ptr @Six, !"Six", i32 2, i32 10, i32 1, i32 10, i32 0, ![[U64:[0-9]+]]}
; CHECK: ![[U64]] = !{i32 0, i32 7}
; CHECK: ![[Array]] = !{i32 7, ptr @7, !"", i32 3, i32 4, i32 100, i32 10, i32 0, ![[Float]]}
; CHECK: ![[Array]] = !{i32 7, ptr @Array, !"Array", i32 3, i32 4, i32 100, i32 10, i32 0, ![[Float]]}
; CHECK: ![[Seven]] = !{i32 8, ptr @Seven, !"Seven", i32 5, i32 20, i32 1, i32 10, i32 0, ![[U64]]}
Loading