From 0cbd737298888d2a118090c6f19e064841ef7174 Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Tue, 5 Aug 2025 21:43:57 -0700 Subject: [PATCH 1/4] [DirectX] Overlapping binding detection - check for matching register space first --- llvm/include/llvm/Analysis/DXILResource.h | 4 ++- .../DirectX/Binding/binding-overlap-7.ll | 35 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/DirectX/Binding/binding-overlap-7.ll diff --git a/llvm/include/llvm/Analysis/DXILResource.h b/llvm/include/llvm/Analysis/DXILResource.h index 93c6bfb057ef5..7b3e1a19753c8 100644 --- a/llvm/include/llvm/Analysis/DXILResource.h +++ b/llvm/include/llvm/Analysis/DXILResource.h @@ -360,9 +360,11 @@ class ResourceInfo { std::tie(RHS.RecordID, RHS.Space, RHS.LowerBound, RHS.Size); } bool overlapsWith(const ResourceBinding &RHS) const { + if (Space != RHS.Space) + return false; if (Size == UINT32_MAX) return LowerBound < RHS.LowerBound; - return Space == RHS.Space && LowerBound + Size - 1 >= RHS.LowerBound; + return LowerBound + Size - 1 >= RHS.LowerBound; } }; diff --git a/llvm/test/CodeGen/DirectX/Binding/binding-overlap-7.ll b/llvm/test/CodeGen/DirectX/Binding/binding-overlap-7.ll new file mode 100644 index 0000000000000..25f81dd26b9db --- /dev/null +++ b/llvm/test/CodeGen/DirectX/Binding/binding-overlap-7.ll @@ -0,0 +1,35 @@ +; Use llc for this test so that we don't abort after the first error. +; RUN: not llc %s -o /dev/null 2>&1 | FileCheck %s + +; Check that there is no overlap with unbounded array in different space + + ; Buffer A[2] : register(t2, space4); + ; Buffer B : register(t20, space5); // does not overlap + ; Buffer C[] : register(t2, space4); // overlaps with A + +; CHECK: error: resource A at register 2 overlaps with resource C at register 2 in space 4 +; CHECK-NOT: error: resource C at register 2 overlaps with resource B at register 20 in space 5 + +target triple = "dxil-pc-shadermodel6.3-library" + +@A.str = private unnamed_addr constant [2 x i8] c"A\00", align 1 +@B.str = private unnamed_addr constant [2 x i8] c"B\00", align 1 +@C.str = private unnamed_addr constant [2 x i8] c"C\00", align 1 + +define void @test_not_overlapping_in_different_spaces() { +entry: + + ; Buffer A[2] : register(t2, space4); + %h0 = call target("dx.TypedBuffer", double, 0, 0, 0) + @llvm.dx.resource.handlefrombinding(i32 4, i32 2, i32 2, i32 10, i1 false, ptr @A.str) + + ; Buffer B : register(t20, space5); + %h1 = call target("dx.TypedBuffer", i64, 0, 0, 0) + @llvm.dx.resource.handlefrombinding(i32 5, i32 20, i32 1, i32 0, i1 false, ptr @B.str) + + ; Buffer C[] : register(t2, space4); + %h2 = call target("dx.TypedBuffer", double, 0, 0, 0) + @llvm.dx.resource.handlefrombinding(i32 4, i32 2, i32 -1, i32 10, i1 false, ptr @C.str) + + ret void +} From 3594a7af4e21daa461cb928fc1119bd09cc114e9 Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Tue, 5 Aug 2025 22:27:42 -0700 Subject: [PATCH 2/4] [DirectX] Fix resource binding analysis incorrectly removing duplicates --- llvm/lib/Frontend/HLSL/HLSLBinding.cpp | 2 +- .../DXILPostOptimizationValidation.cpp | 8 +-- .../CodeGen/DirectX/Metadata/srv_metadata.ll | 45 +++++++++++------ .../CodeGen/DirectX/Metadata/uav_metadata.ll | 49 ++++++++++++------- 4 files changed, 66 insertions(+), 38 deletions(-) diff --git a/llvm/lib/Frontend/HLSL/HLSLBinding.cpp b/llvm/lib/Frontend/HLSL/HLSLBinding.cpp index d581311f22028..45391460354d0 100644 --- a/llvm/lib/Frontend/HLSL/HLSLBinding.cpp +++ b/llvm/lib/Frontend/HLSL/HLSLBinding.cpp @@ -76,7 +76,7 @@ BindingInfo BindingInfoBuilder::calculateBindingInfo( // remove duplicates Binding *NewEnd = llvm::unique(Bindings); if (NewEnd != Bindings.end()) - Bindings.erase(NewEnd); + Bindings.erase(NewEnd, Bindings.end()); BindingInfo Info; diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp index 398dcbb8d1737..9d995bc70a997 100644 --- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp +++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp @@ -63,9 +63,7 @@ static void reportOverlappingError(Module &M, ResourceInfo R1, } static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) { - if (DRM.empty()) - return; - + bool ErrorFound = false; for (const auto &ResList : {DRM.srvs(), DRM.uavs(), DRM.cbuffers(), DRM.samplers()}) { if (ResList.empty()) @@ -77,11 +75,15 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) { while (RI != ResList.end() && PrevRI->getBinding().overlapsWith(RI->getBinding())) { reportOverlappingError(M, *PrevRI, *RI); + ErrorFound = true; RI++; } PrevRI = CurrentRI; } } + assert(ErrorFound && "this function should be called only when if " + "DXILResourceBindingInfo::hasOverlapingBinding() is " + "true, yet no overlapping binding was found"); } static void reportErrors(Module &M, DXILResourceMap &DRM, diff --git a/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll b/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll index abab5c9fb1166..5c9fb93d7f570 100644 --- a/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll +++ b/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll @@ -1,6 +1,6 @@ ; RUN: opt -S -dxil-translate-metadata < %s | FileCheck %s ; RUN: opt -S --passes="dxil-pretty-printer" < %s 2>&1 | FileCheck %s --check-prefix=PRINT -; RUN: llc %s --filetype=asm -o - < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,PRINT +; RUN: llc %s --filetype=asm -o - 2>&1 | FileCheck %s --check-prefixes=CHECK,PRINT 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" @@ -14,20 +14,22 @@ target triple = "dxil-pc-shadermodel6.6-compute" @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 +@Array2.str = private unnamed_addr constant [7 x i8] c"Array2\00", align 1 ; PRINT:; Resource Bindings: ; PRINT-NEXT:; -; PRINT-NEXT:; Name Type Format Dim ID HLSL Bind Count -; PRINT-NEXT:; ------------------------------ ---------- ------- ----------- ------- -------------- ------ -; 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 +; PRINT-NEXT:; Name Type Format Dim ID HLSL Bind Count +; PRINT-NEXT:; ------------------------------ ---------- ------- ----------- ------- -------------- -------- +; 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:; Array2 texture f64 buf T8 t2,space4 unbounded +; PRINT-NEXT:; Seven texture u64 buf T9 t20,space5 1 ; define void @test() #0 { @@ -60,19 +62,28 @@ define void @test() #0 { @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 Seven : register(t10, space2); + ; Buffer Seven : register(t20, space5); %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 Array[100] : register(t4, space3); ; Buffer B1 = Array[30]; - ; Buffer B1 = Array[42]; + ; Buffer B2 = 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 @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 @Array.str) + ; test unbounded resource array + ; Buffer Array2[] : register(t2, space4); + ; Buffer C1 = Array[10]; + ; Buffer C2 = Array[20]; + %Array2_10_h = call target("dx.TypedBuffer", double, 0, 0, 0) + @llvm.dx.resource.handlefrombinding(i32 4, i32 2, i32 -1, i32 10, i1 false, ptr @Array2.str) + %Array2_20_h = call target("dx.TypedBuffer", double, 0, 0, 0) + @llvm.dx.resource.handlefrombinding(i32 4, i32 2, i32 -1, i32 20, i1 false, ptr @Array2.str) + ret void } @@ -95,6 +106,7 @@ attributes #0 = { noinline nounwind "hlsl.shader"="compute" } ; CHECK: @Five = external constant %"StructuredBuffer" ; CHECK: @Six = external constant %"Buffer" ; CHECK: @Array = external constant %"Buffer" +; CHECK: @Array2 = external constant %"Buffer" ; CHECK: @Seven = external constant %"Buffer" ; CHECK: !dx.resources = !{[[ResList:[!][0-9]+]]} @@ -102,7 +114,7 @@ attributes #0 = { noinline nounwind "hlsl.shader"="compute" } ; 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]+]], ![[Seven:[0-9]+]]} +; CHECK-SAME: ![[Six:[0-9]+]], ![[Array:[0-9]+]], ![[Array2:[0-9]+]], ![[Seven:[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} @@ -118,4 +130,5 @@ attributes #0 = { noinline nounwind "hlsl.shader"="compute" } ; 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 @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]]} +; CHECK: ![[Array2]] = !{i32 8, ptr @Array2, !"Array2", i32 4, i32 2, i32 -1, i32 10, i32 0, ![[Double]]} +; CHECK: ![[Seven]] = !{i32 9, ptr @Seven, !"Seven", i32 5, i32 20, i32 1, i32 10, i32 0, ![[U64]]} diff --git a/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll b/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll index 9893f8b9ea4d7..77f36dd40fd7c 100644 --- a/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll +++ b/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll @@ -1,6 +1,6 @@ ; RUN: opt -S -dxil-translate-metadata < %s | FileCheck %s ; RUN: opt -S --passes="dxil-pretty-printer" < %s 2>&1 | FileCheck %s --check-prefix=PRINT -; RUN: llc %s --filetype=asm -o - < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,PRINT +; RUN: llc %s --filetype=asm -o - 2>&1 | FileCheck %s --check-prefixes=CHECK,PRINT 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" @@ -17,23 +17,25 @@ target triple = "dxil-pc-shadermodel6.6-compute" @Nine.str = private unnamed_addr constant [5 x i8] c"Nine\00", align 1 @Ten.str = private unnamed_addr constant [4 x i8] c"Ten\00", align 1 @Array.str = private unnamed_addr constant [6 x i8] c"Array\00", align 1 +@Array2.str = private unnamed_addr constant [7 x i8] c"Array2\00", align 1 ; PRINT:; Resource Bindings: ; PRINT-NEXT:; -; PRINT-NEXT:; Name Type Format Dim ID HLSL Bind Count -; PRINT-NEXT:; ------------------------------ ---------- ------- ----------- ------- -------------- ------ -; PRINT-NEXT:; Zero UAV f16 buf U0 u0 1 -; PRINT-NEXT:; One UAV f32 buf U1 u1 1 -; PRINT-NEXT:; Two UAV f64 buf U2 u2 1 -; PRINT-NEXT:; Three UAV i32 buf U3 u3 1 -; PRINT-NEXT:; Four UAV byte r/w U4 u5 1 -; PRINT-NEXT:; Five UAV struct r/w U5 u6 1 -; PRINT-NEXT:; Six UAV i32 buf U6 u7 1 -; PRINT-NEXT:; Seven UAV struct r/w U7 u8 1 -; PRINT-NEXT:; Eight UAV byte r/w U8 u9 1 -; PRINT-NEXT:; Nine UAV u64 buf U9 u10,space2 1 -; PRINT-NEXT:; Array UAV f32 buf U10 u4,space3 100 -; PRINT-NEXT:; Ten UAV u64 buf U11 u22,space5 1 +; PRINT-NEXT:; Name Type Format Dim ID HLSL Bind Count +; PRINT-NEXT:; ------------------------------ ---------- ------- ----------- ------- -------------- --------- +; PRINT-NEXT:; Zero UAV f16 buf U0 u0 1 +; PRINT-NEXT:; One UAV f32 buf U1 u1 1 +; PRINT-NEXT:; Two UAV f64 buf U2 u2 1 +; PRINT-NEXT:; Three UAV i32 buf U3 u3 1 +; PRINT-NEXT:; Four UAV byte r/w U4 u5 1 +; PRINT-NEXT:; Five UAV struct r/w U5 u6 1 +; PRINT-NEXT:; Six UAV i32 buf U6 u7 1 +; PRINT-NEXT:; Seven UAV struct r/w U7 u8 1 +; PRINT-NEXT:; Eight UAV byte r/w U8 u9 1 +; PRINT-NEXT:; Nine UAV u64 buf U9 u10,space2 1 +; PRINT-NEXT:; Array UAV f32 buf U10 u4,space3 100 +; PRINT-NEXT:; Array2 UAV f64 buf U11 u2,space4 unbounded +; PRINT-NEXT:; Ten UAV u64 buf U12 u22,space5 1 define void @test() #0 { ; RWBuffer Zero : register(u0) @@ -78,13 +80,22 @@ define void @test() #0 { ; RWBuffer Array[100] : register(u4, space3); ; RWBuffer B1 = Array[30]; - ; RWBuffer B1 = Array[42]; + ; RWBuffer B2 = Array[42]; ; resource array accesses should produce one metadata entry %Array_30_h = call target("dx.TypedBuffer", <4 x float>, 1, 0, 0) @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>, 1, 0, 0) @llvm.dx.resource.handlefrombinding(i32 3, i32 4, i32 100, i32 42, i1 false, ptr @Array.str) + ; test unbounded resource array + ; RWBuffer Array2[] : register(u2, space4); + ; RWBuffer C1 = Array[10]; + ; RWBuffer C2 = Array[20]; + %Array2_10_h = call target("dx.TypedBuffer", double, 1, 0, 0) + @llvm.dx.resource.handlefrombinding(i32 4, i32 2, i32 -1, i32 10, i1 false, ptr @Array2.str) + %Array2_20_h = call target("dx.TypedBuffer", double, 1, 0, 0) + @llvm.dx.resource.handlefrombinding(i32 4, i32 2, i32 -1, i32 20, i1 false, ptr @Array2.str) + ; Same buffer type as Nine - should have the same type in metadata ; RWBuffer Ten : register(u2); %Ten_h = call target("dx.TypedBuffer", i64, 1, 0, 0) @@ -118,6 +129,7 @@ attributes #0 = { noinline nounwind "hlsl.shader"="compute" } ; CHECK: @Eight = external constant %RasterizerOrderedByteAddressBuffer ; CHECK: @Nine = external constant %"RWBuffer" ; CHECK: @Array = external constant %"RWBuffer" +; CHECK: @Array2 = external constant %"RWBuffer" ; CHECK: @Ten = external constant %"RWBuffer" ; CHECK: !dx.resources = !{[[ResList:[!][0-9]+]]} @@ -126,7 +138,7 @@ attributes #0 = { noinline nounwind "hlsl.shader"="compute" } ; CHECK: [[UAVList]] = !{![[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]+]], ![[Seven:[0-9]+]], ![[Eight:[0-9]+]], -; CHECK-SAME: ![[Nine:[0-9]+]], ![[Array:[0-9]+]], ![[Ten:[0-9]+]]} +; CHECK-SAME: ![[Nine:[0-9]+]], ![[Array:[0-9]+]], ![[Array2:[0-9]+]], ![[Ten:[0-9]+]]} ; CHECK: ![[Zero]] = !{i32 0, ptr @Zero, !"Zero", i32 0, i32 0, i32 1, i32 10, i1 false, i1 false, i1 false, ![[Half:[0-9]+]]} ; CHECK: ![[Half]] = !{i32 0, i32 8} @@ -146,4 +158,5 @@ attributes #0 = { noinline nounwind "hlsl.shader"="compute" } ; CHECK: ![[Nine]] = !{i32 9, ptr @Nine, !"Nine", i32 2, i32 10, i32 1, i32 10, i1 false, i1 false, i1 false, ![[U64:[0-9]+]]} ; CHECK: ![[U64]] = !{i32 0, i32 7} ; CHECK: ![[Array]] = !{i32 10, ptr @Array, !"Array", i32 3, i32 4, i32 100, i32 10, i1 false, i1 false, i1 false, ![[Float]]} -; CHECK: ![[Ten]] = !{i32 11, ptr @Ten, !"Ten", i32 5, i32 22, i32 1, i32 10, i1 false, i1 false, i1 false, ![[U64:[0-9]+]]} +; CHECK: ![[Array2]] = !{i32 11, ptr @Array2, !"Array2", i32 4, i32 2, i32 -1, i32 10, i1 false, i1 false, i1 false, ![[Double]]} +; CHECK: ![[Ten]] = !{i32 12, ptr @Ten, !"Ten", i32 5, i32 22, i32 1, i32 10, i1 false, i1 false, i1 false, ![[U64:[0-9]+]]} From 4da01296c830dba300c408b99f93850d4ebdeb7f Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Tue, 5 Aug 2025 23:05:42 -0700 Subject: [PATCH 3/4] adjust padding --- .../CodeGen/DirectX/Metadata/srv_metadata.ll | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll b/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll index 5c9fb93d7f570..b27020633e3a2 100644 --- a/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll +++ b/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll @@ -18,18 +18,18 @@ target triple = "dxil-pc-shadermodel6.6-compute" ; PRINT:; Resource Bindings: ; PRINT-NEXT:; -; PRINT-NEXT:; Name Type Format Dim ID HLSL Bind Count -; PRINT-NEXT:; ------------------------------ ---------- ------- ----------- ------- -------------- -------- -; 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:; Name Type Format Dim ID HLSL Bind Count +; PRINT-NEXT:; ------------------------------ ---------- ------- ----------- ------- -------------- --------- +; 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:; Array2 texture f64 buf T8 t2,space4 unbounded -; PRINT-NEXT:; Seven texture u64 buf T9 t20,space5 1 +; PRINT-NEXT:; Seven texture u64 buf T9 t20,space5 1 ; define void @test() #0 { From c9f45e919b3a305ca685f82512bdce3cf441458b Mon Sep 17 00:00:00 2001 From: Helena Kotas Date: Tue, 5 Aug 2025 18:23:53 -0700 Subject: [PATCH 4/4] [HLSL] Update DXIL resource metadata code to support resource arrays Closes #145422 --- llvm/lib/Analysis/DXILResource.cpp | 7 ++++++- llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll | 4 ++-- llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Analysis/DXILResource.cpp b/llvm/lib/Analysis/DXILResource.cpp index 629fa7cddb9d4..109c0568a6f9e 100644 --- a/llvm/lib/Analysis/DXILResource.cpp +++ b/llvm/lib/Analysis/DXILResource.cpp @@ -612,7 +612,12 @@ void ResourceTypeInfo::print(raw_ostream &OS, const DataLayout &DL) const { GlobalVariable *ResourceInfo::createSymbol(Module &M, StructType *Ty) { assert(!Symbol && "Symbol has already been created"); - Symbol = new GlobalVariable(M, Ty, /*isConstant=*/true, + Type *ResTy = Ty; + int64_t Size = Binding.Size; + if (Size != 1) + // unbounded arrays are represented as zero-sized arrays in LLVM IR + ResTy = ArrayType::get(Ty, Size == ~0u ? 0 : Size); + Symbol = new GlobalVariable(M, ResTy, /*isConstant=*/true, GlobalValue::ExternalLinkage, /*Initializer=*/nullptr, Name); return Symbol; diff --git a/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll b/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll index b27020633e3a2..86d69abc75760 100644 --- a/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll +++ b/llvm/test/CodeGen/DirectX/Metadata/srv_metadata.ll @@ -105,8 +105,8 @@ attributes #0 = { noinline nounwind "hlsl.shader"="compute" } ; CHECK: @Four = external constant %ByteAddressBuffer ; CHECK: @Five = external constant %"StructuredBuffer" ; CHECK: @Six = external constant %"Buffer" -; CHECK: @Array = external constant %"Buffer" -; CHECK: @Array2 = external constant %"Buffer" +; CHECK: @Array = external constant [100 x %"Buffer"] +; CHECK: @Array2 = external constant [0 x %"Buffer"] ; CHECK: @Seven = external constant %"Buffer" ; 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 77f36dd40fd7c..4928b1d0bab97 100644 --- a/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll +++ b/llvm/test/CodeGen/DirectX/Metadata/uav_metadata.ll @@ -128,8 +128,8 @@ attributes #0 = { noinline nounwind "hlsl.shader"="compute" } ; CHECK: @Seven = external constant %"RasterizerOrderedStructuredBuffer" ; CHECK: @Eight = external constant %RasterizerOrderedByteAddressBuffer ; CHECK: @Nine = external constant %"RWBuffer" -; CHECK: @Array = external constant %"RWBuffer" -; CHECK: @Array2 = external constant %"RWBuffer" +; CHECK: @Array = external constant [100 x %"RWBuffer"] +; CHECK: @Array2 = external constant [0 x %"RWBuffer"] ; CHECK: @Ten = external constant %"RWBuffer" ; CHECK: !dx.resources = !{[[ResList:[!][0-9]+]]}