Skip to content

Conversation

joaosaffran
Copy link
Contributor

This PR makes a few changes to make sure that Root Signature Flags are always parsed validated and verified, this includes if you use a version that doesn't support flags. The logic already existed, this PR just makes sure it is always executed.

Closes: #161579

@llvmbot llvmbot added backend:DirectX HLSL HLSL Language Support labels Oct 6, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 6, 2025

@llvm/pr-subscribers-hlsl

@llvm/pr-subscribers-backend-directx

Author: None (joaosaffran)

Changes

This PR makes a few changes to make sure that Root Signature Flags are always parsed validated and verified, this includes if you use a version that doesn't support flags. The logic already existed, this PR just makes sure it is always executed.

Closes: #161579


Full diff: https://github.com/llvm/llvm-project/pull/162171.diff

4 Files Affected:

  • (modified) llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp (+10-23)
  • (modified) llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp (-3)
  • (added) llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootDescriptor-Invalid-Flags_V1.ll (+18)
  • (added) llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Flag_V1.ll (+19)
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
index 73d91a47cab25..3296dbb019f6b 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
@@ -385,12 +385,6 @@ Error MetadataParser::parseRootDescriptors(
     return createRSError(RSErrorKind::InvalidMetadataValue,
                          StringRef("RegisterSpace"));
 
-  if (RSD.Version == 1) {
-    RSD.ParametersContainer.addParameter(Type, *Visibility, Descriptor);
-    return Error::success();
-  }
-  assert(RSD.Version > 1);
-
   if (std::optional<uint32_t> Val = extractMdIntValue(RootDescriptorNode, 4))
     Descriptor.Flags = *Val;
   else
@@ -589,12 +583,6 @@ Error MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD,
     return Error(std::move(E));
   Sampler.ShaderVisibility = *Visibility;
 
-  if (RSD.Version < 3) {
-    RSD.StaticSamplers.push_back(Sampler);
-    return Error::success();
-  }
-  assert(RSD.Version >= 3);
-
   if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 14))
     Sampler.Flags = *Val;
   else
@@ -738,17 +726,16 @@ Error MetadataParser::validateRootSignature(
                                                 StringRef("RegisterSpace"),
                                                 Descriptor.RegisterSpace));
 
-      if (RSD.Version > 1) {
-        bool IsValidFlag =
-            dxbc::isValidRootDesciptorFlags(Descriptor.Flags) &&
-            hlsl::rootsig::verifyRootDescriptorFlag(
-                RSD.Version, dxbc::RootDescriptorFlags(Descriptor.Flags));
-        if (!IsValidFlag)
-          DeferredErrs = joinErrors(
-              std::move(DeferredErrs),
-              createRSError(RSErrorKind::Validation,
-                            StringRef("RootDescriptorFlag"), Descriptor.Flags));
-      }
+      bool IsValidFlag =
+          dxbc::isValidRootDesciptorFlags(Descriptor.Flags) &&
+          hlsl::rootsig::verifyRootDescriptorFlag(
+              RSD.Version, dxbc::RootDescriptorFlags(Descriptor.Flags));
+      if (!IsValidFlag)
+        DeferredErrs = joinErrors(
+            std::move(DeferredErrs),
+            createRSError(RSErrorKind::Validation,
+                          StringRef("RootDescriptorFlag"), Descriptor.Flags));
+      
       break;
     }
     case dxbc::RootParameterType::DescriptorTable: {
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
index 30408dfda940d..2b35b1e3a85ad 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
@@ -41,8 +41,6 @@ bool verifyRootDescriptorFlag(uint32_t Version,
   if (Version == 1)
     return Flags == FlagT::DataVolatile;
 
-  assert((Version <= 3) && "Provided invalid root signature version");
-
   // The data-specific flags are mutually exclusive.
   FlagT DataFlags = FlagT::DataVolatile | FlagT::DataStatic |
                     FlagT::DataStaticWhileSetAtExecute;
@@ -118,7 +116,6 @@ bool verifyStaticSamplerFlags(uint32_t Version,
   if (Version <= 2)
     return Flags == dxbc::StaticSamplerFlags::None;
 
-  assert(Version == 3 && "Provided invalid root signature version");
 
   dxbc::StaticSamplerFlags Mask =
       dxbc::StaticSamplerFlags::NonNormalizedCoordinates |
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootDescriptor-Invalid-Flags_V1.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootDescriptor-Invalid-Flags_V1.ll
new file mode 100644
index 0000000000000..610ce4f4617d0
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootDescriptor-Invalid-Flags_V1.ll
@@ -0,0 +1,18 @@
+; RUN: not opt -passes='print<dxil-root-signature>' %s -S -o - 2>&1 | FileCheck %s
+; On Version 1, the only valid flag is DataVolatile (2).
+target triple = "dxil-unknown-shadermodel6.0-compute"
+
+
+; CHECK: error: Invalid value for RootDescriptorFlag: 4
+; 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 1 } ; function, root signature
+!3 = !{ !5 } ; list of root signature elements
+!5 = !{ !"RootCBV", i32 0, i32 1, i32 2, i32 4  }
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Flag_V1.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Flag_V1.ll
new file mode 100644
index 0000000000000..76b60b82db852
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Flag_V1.ll
@@ -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 Static Sampler Flag: 1 
+; 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 1 } ; function, root signature
+!3 = !{ !5 } ; list of root signature elements
+!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0, i32 1 }

Copy link

github-actions bot commented Oct 6, 2025

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff origin/main HEAD --extensions cpp -- llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp

⚠️
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing origin/main to the base branch/commit you want to compare against.
⚠️

View the diff from clang-format here.
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
index 3296dbb01..3d1ce147c 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
@@ -731,11 +731,11 @@ Error MetadataParser::validateRootSignature(
           hlsl::rootsig::verifyRootDescriptorFlag(
               RSD.Version, dxbc::RootDescriptorFlags(Descriptor.Flags));
       if (!IsValidFlag)
-        DeferredErrs = joinErrors(
-            std::move(DeferredErrs),
-            createRSError(RSErrorKind::Validation,
-                          StringRef("RootDescriptorFlag"), Descriptor.Flags));
-      
+        DeferredErrs = joinErrors(std::move(DeferredErrs),
+                                  createRSError(RSErrorKind::Validation,
+                                                StringRef("RootDescriptorFlag"),
+                                                Descriptor.Flags));
+
       break;
     }
     case dxbc::RootParameterType::DescriptorTable: {
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
index 2b35b1e3a..1735751de 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
@@ -116,7 +116,6 @@ bool verifyStaticSamplerFlags(uint32_t Version,
   if (Version <= 2)
     return Flags == dxbc::StaticSamplerFlags::None;
 
-
   dxbc::StaticSamplerFlags Mask =
       dxbc::StaticSamplerFlags::NonNormalizedCoordinates |
       dxbc::StaticSamplerFlags::UintBorderColor |

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:DirectX HLSL HLSL Language Support
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants