Skip to content

[DirectX] Add missing verifications during validate of DXILRootSignature #147111

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 6 commits into from
Jul 9, 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
3 changes: 2 additions & 1 deletion llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ bool verifyRootFlag(uint32_t Flags);
bool verifyVersion(uint32_t Version);
bool verifyRegisterValue(uint32_t RegisterValue);
bool verifyRegisterSpace(uint32_t RegisterSpace);
bool verifyDescriptorFlag(uint32_t Flags);
bool verifyRootDescriptorFlag(uint32_t Version, uint32_t FlagsVal);
bool verifyRangeType(uint32_t Type);
bool verifyDescriptorRangeFlag(uint32_t Version, uint32_t Type,
uint32_t FlagsVal);
bool verifyNumDescriptors(uint32_t NumDescriptors);
bool verifySamplerFilter(uint32_t Value);
bool verifyAddress(uint32_t Address);
bool verifyMipLODBias(float MipLODBias);
Expand Down
23 changes: 22 additions & 1 deletion llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,24 @@ bool verifyRegisterSpace(uint32_t RegisterSpace) {
return !(RegisterSpace >= 0xFFFFFFF0 && RegisterSpace <= 0xFFFFFFFF);
}

bool verifyDescriptorFlag(uint32_t Flags) { return (Flags & ~0xE) == 0; }
bool verifyRootDescriptorFlag(uint32_t Version, uint32_t FlagsVal) {
using FlagT = dxbc::RootDescriptorFlags;
FlagT Flags = FlagT(FlagsVal);
if (Version == 1)
return Flags == FlagT::DataVolatile;

assert(Version == 2 && "Provided invalid root signature version");

// The data-specific flags are mutually exclusive.
FlagT DataFlags = FlagT::DataVolatile | FlagT::DataStatic |
FlagT::DataStaticWhileSetAtExecute;

if (popcount(llvm::to_underlying(Flags & DataFlags)) > 1)
return false;

// Only a data flag or no flags is valid
return (Flags | DataFlags) == DataFlags;
}

bool verifyRangeType(uint32_t Type) {
switch (Type) {
Expand Down Expand Up @@ -108,6 +125,10 @@ bool verifyDescriptorRangeFlag(uint32_t Version, uint32_t Type,
return (Flags & ~Mask) == FlagT::None;
}

bool verifyNumDescriptors(uint32_t NumDescriptors) {
return NumDescriptors > 0;
}

bool verifySamplerFilter(uint32_t Value) {
switch (Value) {
#define FILTER(Num, Val) case llvm::to_underlying(dxbc::SamplerFilter::Val):
Expand Down
8 changes: 6 additions & 2 deletions llvm/lib/Target/DirectX/DXILRootSignature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,9 @@ static bool validate(LLVMContext *Ctx, const mcdxbc::RootSignatureDesc &RSD) {
return reportValueError(Ctx, "RegisterSpace", Descriptor.RegisterSpace);

if (RSD.Version > 1) {
if (!llvm::hlsl::rootsig::verifyDescriptorFlag(Descriptor.Flags))
return reportValueError(Ctx, "DescriptorRangeFlag", Descriptor.Flags);
if (!llvm::hlsl::rootsig::verifyRootDescriptorFlag(RSD.Version,
Descriptor.Flags))
return reportValueError(Ctx, "RootDescriptorFlag", Descriptor.Flags);
}
break;
}
Expand All @@ -447,6 +448,9 @@ static bool validate(LLVMContext *Ctx, const mcdxbc::RootSignatureDesc &RSD) {
if (!llvm::hlsl::rootsig::verifyRegisterSpace(Range.RegisterSpace))
return reportValueError(Ctx, "RegisterSpace", Range.RegisterSpace);

if (!llvm::hlsl::rootsig::verifyNumDescriptors(Range.NumDescriptors))
return reportValueError(Ctx, "NumDescriptors", Range.NumDescriptors);

if (!llvm::hlsl::rootsig::verifyDescriptorRangeFlag(
RSD.Version, Range.RangeType, Range.Flags))
return reportValueError(Ctx, "DescriptorFlag", Range.Flags);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
!2 = !{ ptr @main, !3, i32 1 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
!5 = !{ !"DescriptorTable", i32 0, !6, !7 }
!6 = !{ !"Sampler", i32 0, i32 1, i32 0, i32 -1, i32 1 }
!6 = !{ !"Sampler", i32 1, i32 1, i32 0, i32 -1, i32 1 }
!7 = !{ !"UAV", i32 5, i32 1, i32 10, i32 5, i32 3 }


Expand All @@ -33,7 +33,7 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
; DXC-NEXT: RangesOffset: 44
; DXC-NEXT: Ranges:
; DXC-NEXT: - RangeType: 3
; DXC-NEXT: NumDescriptors: 0
; DXC-NEXT: NumDescriptors: 1
; DXC-NEXT: BaseShaderRegister: 1
; DXC-NEXT: RegisterSpace: 0
; DXC-NEXT: OffsetInDescriptorsFromTableStart: 4294967295
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
!2 = !{ ptr @main, !3, i32 2 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
!5 = !{ !"DescriptorTable", i32 0, !6, !7 }
!6 = !{ !"SRV", i32 0, i32 1, i32 0, i32 -1, i32 22 }
!6 = !{ !"SRV", i32 1, i32 1, i32 0, i32 -1, i32 22 }
!7 = !{ !"UAV", i32 5, i32 1, i32 10, i32 5, i32 2 }
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
; RUN: not opt -passes='print<dxil-root-signature>' %s -S -o - 2>&1 | FileCheck %s

target triple = "dxil-unknown-shadermodel6.0-compute"

; CHECK: error: Invalid value for NumDescriptors: 0
; CHECK-NOT: Root Signature Definitions

define void @main() #0 {
entry:
ret void
}
attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }


!dx.rootsignatures = !{!2} ; list of function/root signature pairs
!2 = !{ ptr @main, !3, i32 2 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
!5 = !{ !"DescriptorTable", i32 0, !6}
!6 = !{ !"SRV", i32 0, i32 0, i32 10, i32 -1, i32 4 }
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
!2 = !{ ptr @main, !3, i32 2 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
!5 = !{ !"DescriptorTable", i32 0, !6, !7 }
!6 = !{ !"Invalid", i32 0, i32 0, i32 -1, i32 -1, i32 4 }
!6 = !{ !"Invalid", i32 1, i32 0, i32 -1, i32 -1, i32 4 }
!7 = !{ !"UAV", i32 5, i32 1, i32 10, i32 5, i32 2 }
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
!2 = !{ ptr @main, !3, i32 2 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
!5 = !{ !"DescriptorTable", i32 0, !6, !7 }
!6 = !{ !"SRV", i32 0, i32 0, i32 10, i32 -1, i32 4 }
!6 = !{ !"SRV", i32 1, i32 0, i32 10, i32 -1, i32 4 }
!7 = !{ !"UAV", i32 5, i32 1, i32 4294967280, i32 5, i32 2 }
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
!2 = !{ ptr @main, !3, i32 2 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
!5 = !{ !"DescriptorTable", i32 0, !6, !7 }
!6 = !{ !"SRV", i32 0, i32 1, i32 0, i32 -1, i32 4 }
!6 = !{ !"SRV", i32 1, i32 1, i32 0, i32 -1, i32 4 }
!7 = !{ !"UAV", i32 5, i32 1, i32 10, i32 5, i32 2 }

; DXC: - Name: RTS0
Expand All @@ -35,7 +35,7 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
; DXC-NEXT: RangesOffset: 44
; DXC-NEXT: Ranges:
; DXC-NEXT: - RangeType: 0
; DXC-NEXT: NumDescriptors: 0
; DXC-NEXT: NumDescriptors: 1
; DXC-NEXT: BaseShaderRegister: 1
; DXC-NEXT: RegisterSpace: 0
; DXC-NEXT: OffsetInDescriptorsFromTableStart: 4294967295
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
!3 = !{ !4, !5, !6, !7 } ; list of root signature elements
!4 = !{ !"RootFlags", i32 1 } ; 1 = allow_input_assembler_input_layout
!5 = !{ !"RootConstants", i32 0, i32 1, i32 2, i32 3 }
!6 = !{ !"RootSRV", i32 1, i32 4, i32 5, i32 6 }
!6 = !{ !"RootSRV", i32 1, i32 4, i32 5, i32 4 }
!7 = !{ !"DescriptorTable", i32 0, !8, !9 }
!8 = !{ !"SRV", i32 0, i32 1, i32 0, i32 -1, i32 4 }
!8 = !{ !"SRV", i32 1, i32 1, i32 0, i32 -1, i32 4 }
!9 = !{ !"UAV", i32 5, i32 1, i32 10, i32 5, i32 2 }

;CHECK-LABEL: Definition for 'main':
Expand All @@ -34,14 +34,14 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
;CHECK-NEXT: Shader Visibility: 1
;CHECK-NEXT: Register Space: 5
;CHECK-NEXT: Shader Register: 4
;CHECK-NEXT: Flags: 6
;CHECK-NEXT: Flags: 4
;CHECK-NEXT: - Parameter Type: 0
;CHECK-NEXT: Shader Visibility: 0
;CHECK-NEXT: NumRanges: 2
;CHECK-NEXT: - Range Type: 0
;CHECK-NEXT: Register Space: 0
;CHECK-NEXT: Base Shader Register: 1
;CHECK-NEXT: Num Descriptors: 0
;CHECK-NEXT: Num Descriptors: 1
;CHECK-NEXT: Offset In Descriptors From Table Start: 4294967295
;CHECK-NEXT: Flags: 4
;CHECK-NEXT: - Range Type: 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
target triple = "dxil-unknown-shadermodel6.0-compute"


; CHECK: error: Invalid value for DescriptorRangeFlag: 3
; CHECK: error: Invalid value for RootDescriptorFlag: 3
; CHECK-NOT: Root Signature Definitions
define void @main() #0 {
entry:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
; RUN: not opt -passes='print<dxil-root-signature>' %s -S -o - 2>&1 | FileCheck %s

target triple = "dxil-unknown-shadermodel6.0-compute"

; Check that 10 = DataVolatile | Datastatic is invalid due to mutually exclusive

; CHECK: error: Invalid value for RootDescriptorFlag: 10
; CHECK-NOT: Root Signature Definitions
define void @main() #0 {
entry:
ret void
}
attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }


!dx.rootsignatures = !{!2} ; list of function/root signature pairs
!2 = !{ ptr @main, !3, i32 2 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
!5 = !{ !"RootCBV", i32 0, i32 1, i32 2, i32 10 }
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
!dx.rootsignatures = !{!2} ; list of function/root signature pairs
!2 = !{ ptr @main, !3, i32 1 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
!5 = !{ !"RootCBV", i32 0, i32 1, i32 2, i32 8 }
!5 = !{ !"RootCBV", i32 0, i32 1, i32 2, i32 2 }

; DXC: - Name: RTS0
; DXC-NEXT: Size: 44
Expand All @@ -31,4 +31,4 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
; DXC-NEXT: Descriptor:
; DXC-NEXT: RegisterSpace: 2
; DXC-NEXT: ShaderRegister: 1
; DXC-NOT: DATA_STATIC: true
; DXC-NOT: DATA_VOLATILE: true