https://github.com/joaosaffran updated https://github.com/llvm/llvm-project/pull/147573
>From 01a558be2b36a6bb00e1027c4d042c7bacd4ed5a Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Mon, 7 Jul 2025 19:26:24 +0000 Subject: [PATCH 01/10] add validation --- .../DXILPostOptimizationValidation.cpp | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp index a52a04323514c..1a57cd56f8eef 100644 --- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp +++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp @@ -18,6 +18,7 @@ #include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/Module.h" #include "llvm/InitializePasses.h" +#include "llvm/Support/Casting.h" #define DEBUG_TYPE "dxil-post-optimization-validation" @@ -85,6 +86,16 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) { } } +static void reportTextureBoundInRs(Module &M, Twine Type, + ResourceInfo::ResourceBinding Binding) { + SmallString<128> Message; + raw_svector_ostream OS(Message); + OS << "register " << Type << " (space=" << Binding.Space + << ", register=" << Binding.LowerBound << ")" + << " is bound to a texture."; + M.getContext().diagnose(DiagnosticInfoGeneric(Message)); +} + static void reportRegNotBound(Module &M, Twine Type, ResourceInfo::ResourceBinding Binding) { SmallString<128> Message; @@ -155,24 +166,40 @@ static void reportErrors(Module &M, DXILResourceMap &DRM, for (const ResourceInfo &CBuf : DRM.cbuffers()) { ResourceInfo::ResourceBinding Binding = CBuf.getBinding(); + + if (auto *TB = dyn_cast<TextureExtType>(CBuf.getHandleTy())) + reportTextureBoundInRs(M, "cbuffer", Binding); + if (!Validation.checkCRegBinding(Binding)) reportRegNotBound(M, "cbuffer", Binding); } for (const ResourceInfo &SRV : DRM.srvs()) { ResourceInfo::ResourceBinding Binding = SRV.getBinding(); + + if (auto *TB = dyn_cast<TextureExtType>(SRV.getHandleTy())) + reportTextureBoundInRs(M, "srv", Binding); + if (!Validation.checkTRegBinding(Binding)) reportRegNotBound(M, "srv", Binding); } for (const ResourceInfo &UAV : DRM.uavs()) { ResourceInfo::ResourceBinding Binding = UAV.getBinding(); + + if (auto *TB = dyn_cast<TextureExtType>(UAV.getHandleTy())) + reportTextureBoundInRs(M, "uav", Binding); + if (!Validation.checkURegBinding(Binding)) reportRegNotBound(M, "uav", Binding); } for (const ResourceInfo &Sampler : DRM.samplers()) { ResourceInfo::ResourceBinding Binding = Sampler.getBinding(); + + if (auto *TB = dyn_cast<TextureExtType>(Sampler.getHandleTy())) + reportTextureBoundInRs(M, "sampler", Binding); + if (!Validation.checkSamplerBinding(Binding)) reportRegNotBound(M, "sampler", Binding); } >From 43eb04ecebd44ec86a688abc9f067db0dfce2620 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Tue, 8 Jul 2025 02:01:02 +0000 Subject: [PATCH 02/10] adding validation --- .../RootSignature-Validation-Textures.hlsl | 13 ++++++++ .../SemaHLSL/RootSignature-Validation.hlsl | 6 ++-- .../DXILPostOptimizationValidation.cpp | 33 ++++++++++--------- 3 files changed, 34 insertions(+), 18 deletions(-) create mode 100644 clang/test/SemaHLSL/RootSignature-Validation-Textures.hlsl diff --git a/clang/test/SemaHLSL/RootSignature-Validation-Textures.hlsl b/clang/test/SemaHLSL/RootSignature-Validation-Textures.hlsl new file mode 100644 index 0000000000000..9daf38e30dd67 --- /dev/null +++ b/clang/test/SemaHLSL/RootSignature-Validation-Textures.hlsl @@ -0,0 +1,13 @@ +// RUN: not %clang_dxc -T cs_6_6 -E CSMain %s 2>&1 | FileCheck %s + +// CHECK: error: register srv (space=0, register=0) is bound to a texture or typed buffer. + +RWStructuredBuffer<int> Out : register(u0); +Buffer<float> B : register(t0); +// Compute Shader for UAV testing +[numthreads(8, 8, 1)] +[RootSignature("SRV(t0), UAV(u0)")] +void CSMain(uint id : SV_GroupID) +{ + Out[0] = B[0]; +} diff --git a/clang/test/SemaHLSL/RootSignature-Validation.hlsl b/clang/test/SemaHLSL/RootSignature-Validation.hlsl index 5a7f5baf00619..c4ea897c6f490 100644 --- a/clang/test/SemaHLSL/RootSignature-Validation.hlsl +++ b/clang/test/SemaHLSL/RootSignature-Validation.hlsl @@ -16,11 +16,11 @@ cbuffer CB : register(b3, space1) { StructuredBuffer<int> In : register(t0, space0); RWStructuredBuffer<int> Out : register(u0); -RWBuffer<float> UAV : register(u4294967294); +RWStructuredBuffer<float> UAV : register(u4294967294); -RWBuffer<float> UAV1 : register(u2), UAV2 : register(u4); +RWStructuredBuffer<float> UAV1 : register(u2), UAV2 : register(u4); -RWBuffer<float> UAV3 : register(space0); +RWStructuredBuffer<float> UAV3 : register(space0); diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp index 1a57cd56f8eef..13ac6a28d44f7 100644 --- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp +++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp @@ -86,13 +86,14 @@ static void reportOverlappingBinding(Module &M, DXILResourceMap &DRM) { } } -static void reportTextureBoundInRs(Module &M, Twine Type, - ResourceInfo::ResourceBinding Binding) { +static void +reportInvalidHandleTyBoundInRs(Module &M, Twine Type, + ResourceInfo::ResourceBinding Binding) { SmallString<128> Message; raw_svector_ostream OS(Message); OS << "register " << Type << " (space=" << Binding.Space << ", register=" << Binding.LowerBound << ")" - << " is bound to a texture."; + << " is bound to a texture or typed buffer."; M.getContext().diagnose(DiagnosticInfoGeneric(Message)); } @@ -167,9 +168,6 @@ static void reportErrors(Module &M, DXILResourceMap &DRM, for (const ResourceInfo &CBuf : DRM.cbuffers()) { ResourceInfo::ResourceBinding Binding = CBuf.getBinding(); - if (auto *TB = dyn_cast<TextureExtType>(CBuf.getHandleTy())) - reportTextureBoundInRs(M, "cbuffer", Binding); - if (!Validation.checkCRegBinding(Binding)) reportRegNotBound(M, "cbuffer", Binding); } @@ -177,29 +175,34 @@ static void reportErrors(Module &M, DXILResourceMap &DRM, for (const ResourceInfo &SRV : DRM.srvs()) { ResourceInfo::ResourceBinding Binding = SRV.getBinding(); - if (auto *TB = dyn_cast<TextureExtType>(SRV.getHandleTy())) - reportTextureBoundInRs(M, "srv", Binding); - if (!Validation.checkTRegBinding(Binding)) reportRegNotBound(M, "srv", Binding); + else { + const auto *Handle = + dyn_cast_or_null<RawBufferExtType>(SRV.getHandleTy()); + + if (!Handle) + reportInvalidHandleTyBoundInRs(M, "srv", Binding); + } } for (const ResourceInfo &UAV : DRM.uavs()) { ResourceInfo::ResourceBinding Binding = UAV.getBinding(); - if (auto *TB = dyn_cast<TextureExtType>(UAV.getHandleTy())) - reportTextureBoundInRs(M, "uav", Binding); - if (!Validation.checkURegBinding(Binding)) reportRegNotBound(M, "uav", Binding); + else { + const auto *Handle = + dyn_cast_or_null<RawBufferExtType>(UAV.getHandleTy()); + + if (!Handle) + reportInvalidHandleTyBoundInRs(M, "srv", Binding); + } } for (const ResourceInfo &Sampler : DRM.samplers()) { ResourceInfo::ResourceBinding Binding = Sampler.getBinding(); - if (auto *TB = dyn_cast<TextureExtType>(Sampler.getHandleTy())) - reportTextureBoundInRs(M, "sampler", Binding); - if (!Validation.checkSamplerBinding(Binding)) reportRegNotBound(M, "sampler", Binding); } >From d7b4cf44541866a47160ac005e85223b3b7b076d Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Tue, 8 Jul 2025 17:06:19 +0000 Subject: [PATCH 03/10] format --- llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp index 13ac6a28d44f7..c34f31fbe35e5 100644 --- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp +++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp @@ -18,7 +18,6 @@ #include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/Module.h" #include "llvm/InitializePasses.h" -#include "llvm/Support/Casting.h" #define DEBUG_TYPE "dxil-post-optimization-validation" @@ -167,14 +166,12 @@ static void reportErrors(Module &M, DXILResourceMap &DRM, for (const ResourceInfo &CBuf : DRM.cbuffers()) { ResourceInfo::ResourceBinding Binding = CBuf.getBinding(); - if (!Validation.checkCRegBinding(Binding)) reportRegNotBound(M, "cbuffer", Binding); } for (const ResourceInfo &SRV : DRM.srvs()) { ResourceInfo::ResourceBinding Binding = SRV.getBinding(); - if (!Validation.checkTRegBinding(Binding)) reportRegNotBound(M, "srv", Binding); else { @@ -188,7 +185,6 @@ static void reportErrors(Module &M, DXILResourceMap &DRM, for (const ResourceInfo &UAV : DRM.uavs()) { ResourceInfo::ResourceBinding Binding = UAV.getBinding(); - if (!Validation.checkURegBinding(Binding)) reportRegNotBound(M, "uav", Binding); else { @@ -202,7 +198,6 @@ static void reportErrors(Module &M, DXILResourceMap &DRM, for (const ResourceInfo &Sampler : DRM.samplers()) { ResourceInfo::ResourceBinding Binding = Sampler.getBinding(); - if (!Validation.checkSamplerBinding(Binding)) reportRegNotBound(M, "sampler", Binding); } >From aea75dac9df35611a5e8d46be8091621985e8ca7 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Tue, 8 Jul 2025 20:51:49 +0000 Subject: [PATCH 04/10] fix test --- .../rootsignature-validation-textures.ll | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-textures.ll diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-textures.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-textures.ll new file mode 100644 index 0000000000000..8c407fdd60205 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-textures.ll @@ -0,0 +1,87 @@ +; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 +; CHECK: error: register srv (space=0, register=0) is bound to a texture or typed buffer. + +; +; Resource Bindings: +; +; Name Type Format Dim ID HLSL Bind Count +; ------------------------------ ---------- ------- ----------- ------- -------------- --------- +; B texture f32 buf T0 t0 1 +; Out UAV struct r/w U0 u0 1 +; +; ModuleID = '../clang/test/SemaHLSL/RootSignature-Validation-Textures.hlsl' +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 = "dxilv1.5-unknown-shadermodel6.5-compute" + +%"Buffer<float>" = type { float } +%"RWStructuredBuffer<int32_t>" = type { i32 } + +@.str = private unnamed_addr constant [4 x i8] c"Out\00", align 1 +@.str.2 = private unnamed_addr constant [2 x i8] c"B\00", align 1 +@B = external constant %"Buffer<float>" +@Out = external constant %"RWStructuredBuffer<int32_t>" + +; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none) +define void @CSMain() local_unnamed_addr #0 { +entry: + %0 = tail call target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @.str) + %1 = tail call target("dx.TypedBuffer", float, 0, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_0_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @.str.2) + %2 = call { float, i1 } @llvm.dx.resource.load.typedbuffer.f32.tdx.TypedBuffer_f32_0_0_0t(target("dx.TypedBuffer", float, 0, 0, 0) %1, i32 0) + %3 = extractvalue { float, i1 } %2, 0 + %conv.i = fptosi float %3 to i32 + call void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i32_1_0t.i32(target("dx.RawBuffer", i32, 1, 0) %0, i32 0, i32 0, i32 %conv.i) + ret void +} + +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) +declare target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32, i32, i32, i32, i1, ptr) #1 + +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) +declare target("dx.TypedBuffer", float, 0, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_0_0_0t(i32, i32, i32, i32, i1, ptr) #1 + +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) +declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_1_0t(target("dx.RawBuffer", i32, 1, 0), i32) #1 + +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) +declare ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_f32_0_0_0t(target("dx.TypedBuffer", float, 0, 0, 0), i32) #1 + +; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read) +declare { float, i1 } @llvm.dx.resource.load.typedbuffer.f32.tdx.TypedBuffer_f32_0_0_0t(target("dx.TypedBuffer", float, 0, 0, 0), i32) #2 + +; Function Attrs: nocallback nofree nosync nounwind willreturn memory(write) +declare void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i32_1_0t.i32(target("dx.RawBuffer", i32, 1, 0), i32, i32, i32) #3 + +attributes #0 = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none) "approx-func-fp-math"="true" "frame-pointer"="all" "hlsl.numthreads"="8,8,1" "hlsl.shader"="compute" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) } +attributes #2 = { nocallback nofree nosync nounwind willreturn memory(read) } +attributes #3 = { nocallback nofree nosync nounwind willreturn memory(write) } + +!dx.rootsignatures = !{!0} +!llvm.module.flags = !{!4, !5} +!dx.valver = !{!6} +!llvm.ident = !{!7} +!dx.shaderModel = !{!8} +!dx.version = !{!9} +!dx.resources = !{!10} +!dx.entryPoints = !{!17} + +!0 = !{ptr @CSMain, !1, i32 2} +!1 = !{!2, !3} +!2 = !{!"RootSRV", i32 0, i32 0, i32 0, i32 4} +!3 = !{!"RootUAV", i32 0, i32 0, i32 0, i32 2} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 7, !"frame-pointer", i32 2} +!6 = !{i32 1, i32 8} +!7 = !{!"clang version 21.0.0git (https://github.com/joaosaffran/llvm-project.git c16f15b4cd469a3f6efc2e4b0e098190d7fd0787)"} +!8 = !{!"cs", i32 6, i32 5} +!9 = !{i32 1, i32 5} +!10 = !{!11, !14, null, null} +!11 = !{!12} +!12 = !{i32 0, ptr @B, !"B", i32 0, i32 0, i32 1, i32 10, i32 0, !13} +!13 = !{i32 0, i32 9} +!14 = !{!15} +!15 = !{i32 0, ptr @Out, !"Out", i32 0, i32 0, i32 1, i32 12, i1 false, i1 false, i1 false, !16} +!16 = !{i32 1, i32 4} +!17 = !{ptr @CSMain, !"CSMain", null, !10, !18} +!18 = !{i32 0, i64 16, i32 4, !19} +!19 = !{i32 8, i32 8, i32 1} >From 5af919957fbe8dd2617ffb8452ef7aa65309a886 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Mon, 14 Jul 2025 23:32:44 +0000 Subject: [PATCH 05/10] update --- .../DXILPostOptimizationValidation.cpp | 49 +++++++++++++++++++ .../rootsignature-validation-textures-fail.ll | 31 ++++++++++++ .../DirectX/rootsignature-validation.ll | 30 +++--------- 3 files changed, 86 insertions(+), 24 deletions(-) create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-textures-fail.ll diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp index c34f31fbe35e5..06f917867987a 100644 --- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp +++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp @@ -13,11 +13,13 @@ #include "llvm/ADT/SmallString.h" #include "llvm/Analysis/DXILMetadataAnalysis.h" #include "llvm/Analysis/DXILResource.h" +#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/Module.h" #include "llvm/InitializePasses.h" +#include "llvm/Support/Casting.h" #define DEBUG_TYPE "dxil-post-optimization-validation" @@ -90,7 +92,11 @@ reportInvalidHandleTyBoundInRs(Module &M, Twine Type, ResourceInfo::ResourceBinding Binding) { SmallString<128> Message; raw_svector_ostream OS(Message); +<<<<<<< Updated upstream OS << "register " << Type << " (space=" << Binding.Space +======= + OS << "resource " << Type << " at register (space=" << Binding.Space +>>>>>>> Stashed changes << ", register=" << Binding.LowerBound << ")" << " is bound to a texture or typed buffer."; M.getContext().diagnose(DiagnosticInfoGeneric(Message)); @@ -146,6 +152,37 @@ getRootSignature(RootSignatureBindingInfo &RSBI, return RootSigDesc; } +<<<<<<< Updated upstream +======= +static void reportInvalidRegistersBinding( + Module &M, + const std::vector<llvm::dxil::ResourceInfo::ResourceBinding> &Bindings, + iterator_range<SmallVector<dxil::ResourceInfo>::iterator> &Resources) { + for (auto Res = Resources.begin(), End = Resources.end(); Res != End; Res++) { + bool Bound = false; + ResourceInfo::ResourceBinding ResBinding = Res->getBinding(); + for (const auto &Binding : Bindings) { + if (ResBinding.Space == Binding.Space && + ResBinding.LowerBound >= Binding.LowerBound && + ResBinding.LowerBound < Binding.LowerBound + Binding.Size) { + Bound = true; + break; + } + } + if (!Bound) { + reportRegNotBound(M, Res->getName(), Res->getBinding()); + } else { + TargetExtType *Handle = Res->getHandleTy(); + auto *TypedBuffer = dyn_cast_or_null<TypedBufferExtType>(Handle); + auto *Texture = dyn_cast_or_null<TextureExtType>(Handle); + + if (TypedBuffer != nullptr || Texture != nullptr) + reportInvalidHandleTyBoundInRs(M, Res->getName(), Res->getBinding()); + } + } +} + +>>>>>>> Stashed changes static void reportErrors(Module &M, DXILResourceMap &DRM, DXILResourceBindingInfo &DRBI, RootSignatureBindingInfo &RSBI, @@ -170,6 +207,7 @@ static void reportErrors(Module &M, DXILResourceMap &DRM, reportRegNotBound(M, "cbuffer", Binding); } +<<<<<<< Updated upstream for (const ResourceInfo &SRV : DRM.srvs()) { ResourceInfo::ResourceBinding Binding = SRV.getBinding(); if (!Validation.checkTRegBinding(Binding)) @@ -201,6 +239,17 @@ static void reportErrors(Module &M, DXILResourceMap &DRM, if (!Validation.checkSamplerBinding(Binding)) reportRegNotBound(M, "sampler", Binding); } +======= + reportInvalidRegistersBinding( + M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::CBV), Cbufs); + reportInvalidRegistersBinding( + M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::UAV), UAVs); + reportInvalidRegistersBinding( + M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::Sampler), + Samplers); + reportInvalidRegistersBinding( + M, Validation.getBindingsOfType(dxbc::DescriptorRangeType::SRV), SRVs); +>>>>>>> Stashed changes } } } // namespace diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-textures-fail.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-textures-fail.ll new file mode 100644 index 0000000000000..4f4015702b713 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-textures-fail.ll @@ -0,0 +1,31 @@ +; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 | FileCheck %s +; CHECK: error: resource TB at register (space=0, register=0) is bound to a texture or typed buffer. + + +; Root Signature( +; CBV(b3, space=1, visibility=SHADER_VISIBILITY_ALL) +; DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL) +; DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_VERTEX) +; DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL) + +@TB.str = private unnamed_addr constant [3 x i8] c"TB\00", align 1 + +define void @CSMain() "hlsl.shader"="compute" { +entry: + + %TB = tail call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @TB.str) + + ret void +} + +!dx.rootsignatures = !{!0} + +!0 = !{ptr @CSMain, !1, i32 2} +!1 = !{!2, !3, !5, !7} +!2 = !{!"RootCBV", i32 0, i32 3, i32 1, i32 4} +!3 = !{!"DescriptorTable", i32 0, !4} +!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 0} +!5 = !{!"DescriptorTable", i32 0, !6} +!6 = !{!"Sampler", i32 5, i32 3, i32 2, i32 -1, i32 0} +!7 = !{!"DescriptorTable", i32 0, !8} +!8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2} diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation.ll index eaf8512c284a7..b8515506c8853 100644 --- a/llvm/test/CodeGen/DirectX/rootsignature-validation.ll +++ b/llvm/test/CodeGen/DirectX/rootsignature-validation.ll @@ -43,30 +43,12 @@ declare target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx ; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none) define void @CSMain() local_unnamed_addr #1 { entry: - %CB.cb_h.i.i = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(i32 1, i32 3, i32 1, i32 0, i1 false, ptr nonnull @CB.str) - store target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) %CB.cb_h.i.i, ptr @CB.cb, align 4 - %0 = tail call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @.str) - %1 = tail call target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @.str.2) - %2 = tail call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 -2, i32 1, i32 0, i1 false, ptr nonnull @.str.4) - %3 = tail call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 2, i32 1, i32 0, i1 false, ptr nonnull @.str.6) - %4 = call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0t(i32 0, i32 1, i32 1, i32 0, i1 false, ptr @.str.10) - %5 = call { float, float, float, float } @llvm.dx.resource.load.cbufferrow.4.f32.f32.f32.f32.tdx.CBuffer_tdx.Layout_s___cblayout_CBs_4_0tt(target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) %CB.cb_h.i.i, i32 0) - %6 = extractvalue { float, float, float, float } %5, 0 - %7 = call { i32, i1 } @llvm.dx.resource.load.rawbuffer.i32.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0) %0, i32 0, i32 0) - %8 = extractvalue { i32, i1 } %7, 0 - %conv.i = sitofp i32 %8 to float - %add.i = fadd reassoc nnan ninf nsz arcp afn float %6, %conv.i - %9 = call { float, i1 } @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %2, i32 0, i32 0) - %10 = extractvalue { float, i1 } %9, 0 - %add2.i = fadd reassoc nnan ninf nsz arcp afn float %add.i, %10 - %11 = call { float, i1 } @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %3, i32 0, i32 0) - %12 = extractvalue { float, i1 } %11, 0 - %add4.i = fadd reassoc nnan ninf nsz arcp afn float %add2.i, %12 - %13 = call { float, i1 } @llvm.dx.resource.load.rawbuffer.f32.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %4, i32 0, i32 0) - %14 = extractvalue { float, i1 } %13, 0 - %add6.i = fadd reassoc nnan ninf nsz arcp afn float %add4.i, %14 - %conv7.i = fptosi float %add6.i to i32 - call void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i32_1_0t.i32(target("dx.RawBuffer", i32, 1, 0) %1, i32 0, i32 0, i32 %conv7.i) + + %CB = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding(i32 1, i32 3, i32 1, i32 0, i1 false, ptr nonnull @CB.str) + %Sampler = call target("dx.Sampler", 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 3, i32 1, i32 0, i1 false, ptr nonnull @Smp.str) + %SB = tail call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @SB.str) + %RWB = tail call target("dx.RawBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @RWB.str) + ret void } >From 91ff1bf501ec158422102f10875c11cbe8d55f5c Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Tue, 15 Jul 2025 00:21:44 +0000 Subject: [PATCH 06/10] clean up --- .../DXILPostOptimizationValidation.cpp | 2 - .../rootsignature-validation-textures.ll | 87 ------------------- 2 files changed, 89 deletions(-) delete mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-textures.ll diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp index 91605b7ba9943..7fefdb65a75d9 100644 --- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp +++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp @@ -12,13 +12,11 @@ #include "llvm/ADT/SmallString.h" #include "llvm/Analysis/DXILMetadataAnalysis.h" #include "llvm/Analysis/DXILResource.h" -#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/Module.h" #include "llvm/InitializePasses.h" -#include "llvm/Support/Casting.h" #define DEBUG_TYPE "dxil-post-optimization-validation" diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-textures.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-textures.ll deleted file mode 100644 index 8c407fdd60205..0000000000000 --- a/llvm/test/CodeGen/DirectX/rootsignature-validation-textures.ll +++ /dev/null @@ -1,87 +0,0 @@ -; RUN: not opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 -; CHECK: error: register srv (space=0, register=0) is bound to a texture or typed buffer. - -; -; Resource Bindings: -; -; Name Type Format Dim ID HLSL Bind Count -; ------------------------------ ---------- ------- ----------- ------- -------------- --------- -; B texture f32 buf T0 t0 1 -; Out UAV struct r/w U0 u0 1 -; -; ModuleID = '../clang/test/SemaHLSL/RootSignature-Validation-Textures.hlsl' -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 = "dxilv1.5-unknown-shadermodel6.5-compute" - -%"Buffer<float>" = type { float } -%"RWStructuredBuffer<int32_t>" = type { i32 } - -@.str = private unnamed_addr constant [4 x i8] c"Out\00", align 1 -@.str.2 = private unnamed_addr constant [2 x i8] c"B\00", align 1 -@B = external constant %"Buffer<float>" -@Out = external constant %"RWStructuredBuffer<int32_t>" - -; Function Attrs: mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none) -define void @CSMain() local_unnamed_addr #0 { -entry: - %0 = tail call target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @.str) - %1 = tail call target("dx.TypedBuffer", float, 0, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_0_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @.str.2) - %2 = call { float, i1 } @llvm.dx.resource.load.typedbuffer.f32.tdx.TypedBuffer_f32_0_0_0t(target("dx.TypedBuffer", float, 0, 0, 0) %1, i32 0) - %3 = extractvalue { float, i1 } %2, 0 - %conv.i = fptosi float %3 to i32 - call void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i32_1_0t.i32(target("dx.RawBuffer", i32, 1, 0) %0, i32 0, i32 0, i32 %conv.i) - ret void -} - -; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) -declare target("dx.RawBuffer", i32, 1, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_1_0t(i32, i32, i32, i32, i1, ptr) #1 - -; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) -declare target("dx.TypedBuffer", float, 0, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_0_0_0t(i32, i32, i32, i32, i1, ptr) #1 - -; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) -declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_1_0t(target("dx.RawBuffer", i32, 1, 0), i32) #1 - -; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(none) -declare ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_f32_0_0_0t(target("dx.TypedBuffer", float, 0, 0, 0), i32) #1 - -; Function Attrs: nocallback nofree nosync nounwind willreturn memory(read) -declare { float, i1 } @llvm.dx.resource.load.typedbuffer.f32.tdx.TypedBuffer_f32_0_0_0t(target("dx.TypedBuffer", float, 0, 0, 0), i32) #2 - -; Function Attrs: nocallback nofree nosync nounwind willreturn memory(write) -declare void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_i32_1_0t.i32(target("dx.RawBuffer", i32, 1, 0), i32, i32, i32) #3 - -attributes #0 = { mustprogress nofree noinline norecurse nosync nounwind willreturn memory(readwrite, inaccessiblemem: none) "approx-func-fp-math"="true" "frame-pointer"="all" "hlsl.numthreads"="8,8,1" "hlsl.shader"="compute" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } -attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(none) } -attributes #2 = { nocallback nofree nosync nounwind willreturn memory(read) } -attributes #3 = { nocallback nofree nosync nounwind willreturn memory(write) } - -!dx.rootsignatures = !{!0} -!llvm.module.flags = !{!4, !5} -!dx.valver = !{!6} -!llvm.ident = !{!7} -!dx.shaderModel = !{!8} -!dx.version = !{!9} -!dx.resources = !{!10} -!dx.entryPoints = !{!17} - -!0 = !{ptr @CSMain, !1, i32 2} -!1 = !{!2, !3} -!2 = !{!"RootSRV", i32 0, i32 0, i32 0, i32 4} -!3 = !{!"RootUAV", i32 0, i32 0, i32 0, i32 2} -!4 = !{i32 1, !"wchar_size", i32 4} -!5 = !{i32 7, !"frame-pointer", i32 2} -!6 = !{i32 1, i32 8} -!7 = !{!"clang version 21.0.0git (https://github.com/joaosaffran/llvm-project.git c16f15b4cd469a3f6efc2e4b0e098190d7fd0787)"} -!8 = !{!"cs", i32 6, i32 5} -!9 = !{i32 1, i32 5} -!10 = !{!11, !14, null, null} -!11 = !{!12} -!12 = !{i32 0, ptr @B, !"B", i32 0, i32 0, i32 1, i32 10, i32 0, !13} -!13 = !{i32 0, i32 9} -!14 = !{!15} -!15 = !{i32 0, ptr @Out, !"Out", i32 0, i32 0, i32 1, i32 12, i1 false, i1 false, i1 false, !16} -!16 = !{i32 1, i32 4} -!17 = !{ptr @CSMain, !"CSMain", null, !10, !18} -!18 = !{i32 0, i64 16, i32 4, !19} -!19 = !{i32 8, i32 8, i32 1} >From 848501da71dd90e1d7dfe25f4ba25890ba487dad Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Mon, 21 Jul 2025 23:24:21 +0000 Subject: [PATCH 07/10] address comments --- .../DXILPostOptimizationValidation.cpp | 68 +++++++++++++++++-- .../rootsignature-validation-textures-fail.ll | 15 +--- .../rootsignature-validation-textures.ll | 23 +++++++ ...otsignature-validation-typedbuffer-fail.ll | 12 +--- .../rootsignature-validation-typedbuffer.ll | 23 +++++++ 5 files changed, 113 insertions(+), 28 deletions(-) create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-textures.ll create mode 100644 llvm/test/CodeGen/DirectX/rootsignature-validation-typedbuffer.ll diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp index a62c2b7e2b2c4..211e639c44a55 100644 --- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp +++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp @@ -10,6 +10,7 @@ #include "DXILRootSignature.h" #include "DXILShaderFlags.h" #include "DirectX.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLForwardCompat.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" @@ -248,6 +249,44 @@ initRSBindingValidation(const mcdxbc::RootSignatureDesc &RSD, return Validation; } +static SmallVector<ResourceInfo::ResourceBinding> +getRootDescriptorsBindingInfo(const mcdxbc::RootSignatureDesc &RSD, + dxbc::ShaderVisibility Visibility) { + + SmallVector<ResourceInfo::ResourceBinding> RDs; + + for (size_t I = 0; I < RSD.ParametersContainer.size(); I++) { + const auto &[Type, Loc] = + RSD.ParametersContainer.getTypeAndLocForParameter(I); + + const auto &Header = RSD.ParametersContainer.getHeader(I); + if (Header.ShaderVisibility != + llvm::to_underlying(dxbc::ShaderVisibility::All) && + Header.ShaderVisibility != llvm::to_underlying(Visibility)) + continue; + + switch (Type) { + + case llvm::to_underlying(dxbc::RootParameterType::SRV): + case llvm::to_underlying(dxbc::RootParameterType::UAV): + case llvm::to_underlying(dxbc::RootParameterType::CBV): { + dxbc::RTS0::v2::RootDescriptor Desc = + RSD.ParametersContainer.getRootDescriptor(Loc); + + ResourceInfo::ResourceBinding Binding; + Binding.LowerBound = Desc.ShaderRegister; + Binding.Space = Desc.RegisterSpace; + Binding.Size = 1; + + RDs.push_back(Binding); + break; + } + } + } + + return RDs; +} + std::optional<mcdxbc::RootSignatureDesc> getRootSignature(RootSignatureBindingInfo &RSBI, dxil::ModuleMetadataInfo &MMI) { @@ -261,10 +300,22 @@ getRootSignature(RootSignatureBindingInfo &RSBI, } static void reportInvalidHandleTy( - Module &M, + Module &M, const llvm::ArrayRef<dxil::ResourceInfo::ResourceBinding> &RDs, const iterator_range<SmallVectorImpl<dxil::ResourceInfo>::iterator> &Resources) { for (auto Res = Resources.begin(), End = Resources.end(); Res != End; Res++) { + llvm::dxil::ResourceInfo::ResourceBinding Binding = Res->getBinding(); + bool IsBound = false; + for (const auto &RD : RDs) { + if (Binding.overlapsWith(RD)) { + IsBound = true; + break; + } + } + + if (!IsBound) + continue; + TargetExtType *Handle = Res->getHandleTy(); auto *TypedBuffer = dyn_cast_or_null<TypedBufferExtType>(Handle); auto *Texture = dyn_cast_or_null<TextureExtType>(Handle); @@ -312,9 +363,9 @@ static void reportErrors(Module &M, DXILResourceMap &DRM, "DXILResourceImplicitBinding pass"); if (auto RSD = getRootSignature(RSBI, MMI)) { - + dxbc::ShaderVisibility Visibility = tripleToVisibility(MMI.ShaderProfile); llvm::hlsl::rootsig::RootSignatureBindingValidation Validation = - initRSBindingValidation(*RSD, tripleToVisibility(MMI.ShaderProfile)); + initRSBindingValidation(*RSD, Visibility); reportUnboundRegisters(M, Validation, ResourceClass::CBuffer, DRM.cbuffers()); @@ -323,10 +374,13 @@ static void reportErrors(Module &M, DXILResourceMap &DRM, DRM.samplers()); reportUnboundRegisters(M, Validation, ResourceClass::SRV, DRM.srvs()); - reportInvalidHandleTy(M, DRM.cbuffers()); - reportInvalidHandleTy(M, DRM.srvs()); - reportInvalidHandleTy(M, DRM.uavs()); - reportInvalidHandleTy(M, DRM.samplers()); + SmallVector<ResourceInfo::ResourceBinding> RDs = + getRootDescriptorsBindingInfo(*RSD, Visibility); + + reportInvalidHandleTy(M, RDs, DRM.cbuffers()); + reportInvalidHandleTy(M, RDs, DRM.srvs()); + reportInvalidHandleTy(M, RDs, DRM.uavs()); + reportInvalidHandleTy(M, RDs, DRM.samplers()); } } } // namespace diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-textures-fail.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-textures-fail.ll index 81d1a1a0ab0c5..a534b6c956e84 100644 --- a/llvm/test/CodeGen/DirectX/rootsignature-validation-textures-fail.ll +++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-textures-fail.ll @@ -3,10 +3,7 @@ ; Root Signature( -; CBV(b3, space=1, visibility=SHADER_VISIBILITY_ALL) -; DescriptorTable(SRV(t0, space=0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL) -; DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_VERTEX) -; DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility=SHADER_VISIBILITY_ALL) +; UAV(b0, space=0, visibility=SHADER_VISIBILITY_ALL) @TB.str = private unnamed_addr constant [3 x i8] c"TB\00", align 1 @@ -21,11 +18,5 @@ entry: !dx.rootsignatures = !{!0} !0 = !{ptr @CSMain, !1, i32 2} -!1 = !{!2, !3, !5, !7} -!2 = !{!"RootCBV", i32 0, i32 3, i32 1, i32 4} -!3 = !{!"DescriptorTable", i32 0, !4} -!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 0} -!5 = !{!"DescriptorTable", i32 0, !6} -!6 = !{!"Sampler", i32 5, i32 3, i32 2, i32 -1, i32 0} -!7 = !{!"DescriptorTable", i32 0, !8} -!8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2} +!1 = !{!2} +!2 = !{!"RootUAV", i32 0, i32 0, i32 0, i32 4} diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-textures.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-textures.ll new file mode 100644 index 0000000000000..fc66ef6ae309f --- /dev/null +++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-textures.ll @@ -0,0 +1,23 @@ +; RUN: opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 + + + +; Root Signature( +; DescriptorTable(UAV(b0, space=0, visibility=SHADER_VISIBILITY_ALL)) + +@TB.str = private unnamed_addr constant [3 x i8] c"TB\00", align 1 + +define void @CSMain() "hlsl.shader"="compute" { +entry: + + %TB = tail call target("dx.Texture", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @TB.str) + + ret void +} + +!dx.rootsignatures = !{!0} + +!0 = !{ptr @CSMain, !1, i32 2} +!1 = !{!3} +!3 = !{!"DescriptorTable", i32 0, !4} +!4 = !{!"UAV", i32 1, i32 0, i32 0, i32 -1, i32 0} diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-typedbuffer-fail.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-typedbuffer-fail.ll index 81d1a1a0ab0c5..46ee29258dbdc 100644 --- a/llvm/test/CodeGen/DirectX/rootsignature-validation-typedbuffer-fail.ll +++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-typedbuffer-fail.ll @@ -13,7 +13,7 @@ define void @CSMain() "hlsl.shader"="compute" { entry: - %TB = tail call target("dx.Texture", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @TB.str) + %TB = tail call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @TB.str) ret void } @@ -21,11 +21,5 @@ entry: !dx.rootsignatures = !{!0} !0 = !{ptr @CSMain, !1, i32 2} -!1 = !{!2, !3, !5, !7} -!2 = !{!"RootCBV", i32 0, i32 3, i32 1, i32 4} -!3 = !{!"DescriptorTable", i32 0, !4} -!4 = !{!"SRV", i32 1, i32 0, i32 0, i32 -1, i32 0} -!5 = !{!"DescriptorTable", i32 0, !6} -!6 = !{!"Sampler", i32 5, i32 3, i32 2, i32 -1, i32 0} -!7 = !{!"DescriptorTable", i32 0, !8} -!8 = !{!"UAV", i32 -1, i32 0, i32 0, i32 -1, i32 2} +!1 = !{!2} +!2 = !{!"RootUAV", i32 0, i32 0, i32 0, i32 4} diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-typedbuffer.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-typedbuffer.ll new file mode 100644 index 0000000000000..0260e0cc9121d --- /dev/null +++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-typedbuffer.ll @@ -0,0 +1,23 @@ +; RUN: opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 + + + +; Root Signature( +; DescriptorTable(UAV(b0, space=0, visibility=SHADER_VISIBILITY_ALL)) + +@TB.str = private unnamed_addr constant [3 x i8] c"TB\00", align 1 + +define void @CSMain() "hlsl.shader"="compute" { +entry: + + %TB = tail call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @TB.str) + + ret void +} + +!dx.rootsignatures = !{!0} + +!0 = !{ptr @CSMain, !1, i32 2} +!1 = !{!3} +!3 = !{!"DescriptorTable", i32 0, !4} +!4 = !{!"UAV", i32 1, i32 0, i32 0, i32 -1, i32 0} >From 8d97116dc7bf9a052f69d4ee30b9c31c13852065 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Mon, 21 Jul 2025 23:25:03 +0000 Subject: [PATCH 08/10] format test --- .../test/CodeGen/DirectX/rootsignature-validation-textures.ll | 4 +--- .../CodeGen/DirectX/rootsignature-validation-typedbuffer.ll | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-textures.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-textures.ll index fc66ef6ae309f..f20ccd04c49c6 100644 --- a/llvm/test/CodeGen/DirectX/rootsignature-validation-textures.ll +++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-textures.ll @@ -1,7 +1,5 @@ ; RUN: opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 - - - +; expected-no-diagnostics ; Root Signature( ; DescriptorTable(UAV(b0, space=0, visibility=SHADER_VISIBILITY_ALL)) diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-typedbuffer.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-typedbuffer.ll index 0260e0cc9121d..a880cbdc8f442 100644 --- a/llvm/test/CodeGen/DirectX/rootsignature-validation-typedbuffer.ll +++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-typedbuffer.ll @@ -1,7 +1,5 @@ ; RUN: opt -S -passes='dxil-post-optimization-validation' -mtriple=dxil-pc-shadermodel6.6-compute %s 2>&1 - - - +; expected-no-diagnostics ; Root Signature( ; DescriptorTable(UAV(b0, space=0, visibility=SHADER_VISIBILITY_ALL)) >From 9c34f3fdf76c43495780666da4d22568dc914689 Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Mon, 21 Jul 2025 23:33:54 +0000 Subject: [PATCH 09/10] fix test --- llvm/test/CodeGen/DirectX/rootsignature-validation.ll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation.ll index 6a279ea123911..ca46168ed1fa3 100644 --- a/llvm/test/CodeGen/DirectX/rootsignature-validation.ll +++ b/llvm/test/CodeGen/DirectX/rootsignature-validation.ll @@ -21,7 +21,7 @@ entry: %CB = tail call target("dx.CBuffer", target("dx.Layout", %__cblayout_CB, 4, 0)) @llvm.dx.resource.handlefrombinding(i32 1, i32 3, i32 1, i32 0, i1 false, ptr nonnull @CB.str) %Sampler = call target("dx.Sampler", 0) @llvm.dx.resource.handlefrombinding(i32 2, i32 3, i32 1, i32 0, i1 false, ptr nonnull @Smp.str) %SB = tail call target("dx.RawBuffer", i32, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i32_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @SB.str) - %RWB = tail call target("dx.RawBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @RWB.str) + %RWB = tail call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_1_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false, ptr nonnull @RWB.str) ret void } >From 2c30cd907db474fc636b6e06e868dcb8046b652e Mon Sep 17 00:00:00 2001 From: joaosaffran <joao.saff...@microsoft.com> Date: Tue, 22 Jul 2025 17:01:38 +0000 Subject: [PATCH 10/10] addressing comments --- .../DXILPostOptimizationValidation.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp index a564f8f150ef9..cf4dd47ad83ef 100644 --- a/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp +++ b/llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp @@ -301,23 +301,16 @@ static void reportInvalidHandleTy( &Resources) { for (auto Res = Resources.begin(), End = Resources.end(); Res != End; Res++) { llvm::dxil::ResourceInfo::ResourceBinding Binding = Res->getBinding(); - bool IsBound = false; for (const auto &RD : RDs) { if (Binding.overlapsWith(RD)) { - IsBound = true; - break; + TargetExtType *Handle = Res->getHandleTy(); + auto *TypedBuffer = dyn_cast_or_null<TypedBufferExtType>(Handle); + auto *Texture = dyn_cast_or_null<TextureExtType>(Handle); + + if (TypedBuffer != nullptr || Texture != nullptr) + reportInvalidHandleTyBoundInRs(M, Res->getName(), Res->getBinding()); } } - - if (!IsBound) - continue; - - TargetExtType *Handle = Res->getHandleTy(); - auto *TypedBuffer = dyn_cast_or_null<TypedBufferExtType>(Handle); - auto *Texture = dyn_cast_or_null<TextureExtType>(Handle); - - if (TypedBuffer != nullptr || Texture != nullptr) - reportInvalidHandleTyBoundInRs(M, Res->getName(), Res->getBinding()); } } _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits