-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[SemaHLSL] Correct descriptor range overflow validation #159475
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
Conversation
@llvm/pr-subscribers-hlsl @llvm/pr-subscribers-clang Author: Finn Plummer (inbelic) ChangesThis pr corrects the validation behaviour to allow valid root signatures of the form: Full diff: https://github.com/llvm/llvm-project/pull/159475.diff 5 Files Affected:
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 0af38472b0fec..33edd7f9a916a 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -1361,6 +1361,7 @@ bool SemaHLSL::handleRootSignatureElements(
bool HasAnySampler = false;
bool HasAnyNonSampler = false;
uint32_t Offset = 0;
+ bool Unbound = false;
for (const auto &[Clause, ClauseElem] : UnboundClauses) {
SourceLocation Loc = ClauseElem->getLocation();
if (Clause->Type == llvm::dxil::ResourceClass::Sampler)
@@ -1381,15 +1382,16 @@ bool SemaHLSL::handleRootSignatureElements(
llvm::hlsl::rootsig::DescriptorTableOffsetAppend) {
// Manually specified the offset
Offset = Clause->Offset;
+ Unbound = false;
+ } else if (Unbound) {
+ // Trying to append onto unbound offset
+ Diag(Loc, diag::err_hlsl_appending_onto_unbound);
}
uint64_t RangeBound = llvm::hlsl::rootsig::computeRangeBound(
Offset, Clause->NumDescriptors);
- if (!llvm::hlsl::rootsig::verifyBoundOffset(Offset)) {
- // Trying to append onto unbound offset
- Diag(Loc, diag::err_hlsl_appending_onto_unbound);
- } else if (!llvm::hlsl::rootsig::verifyNoOverflowedOffset(RangeBound)) {
+ if (!llvm::hlsl::rootsig::verifyNoOverflowedOffset(RangeBound)) {
// Upper bound overflows maximum offset
Diag(Loc, diag::err_hlsl_offset_overflow) << Offset << RangeBound;
}
@@ -1397,6 +1399,8 @@ bool SemaHLSL::handleRootSignatureElements(
Offset = RangeBound == llvm::hlsl::rootsig::NumDescriptorsUnbounded
? uint32_t(RangeBound)
: uint32_t(RangeBound + 1);
+ Unbound = Clause->NumDescriptors ==
+ llvm::hlsl::rootsig::NumDescriptorsUnbounded;
// Compute the register bounds and track resource binding
uint32_t LowerBound(Clause->Reg.Number);
diff --git a/clang/test/SemaHLSL/RootSignature-resource-ranges-err.hlsl b/clang/test/SemaHLSL/RootSignature-resource-ranges-err.hlsl
index 2d025d0e6e5ce..5ce4419149592 100644
--- a/clang/test/SemaHLSL/RootSignature-resource-ranges-err.hlsl
+++ b/clang/test/SemaHLSL/RootSignature-resource-ranges-err.hlsl
@@ -141,4 +141,8 @@ void append_offset_overflow_signature() {}
// expected-error@+1 {{descriptor range offset overflows [4294967292, 4294967296]}}
[RootSignature("DescriptorTable(CBV(b0, offset = 4294967292, numDescriptors = 5))")]
-void offset_() {}
+void offset_overflow() {}
+
+// expected-error@+1 {{descriptor range offset overflows [4294967295, 4294967296]}}
+[RootSignature("DescriptorTable(CBV(b0, offset = 4294967294), CBV(b1, numDescriptors = 2))")]
+void appended_offset_overflow() {}
diff --git a/clang/test/SemaHLSL/RootSignature-resource-ranges.hlsl b/clang/test/SemaHLSL/RootSignature-resource-ranges.hlsl
index 10e7215eccf6e..37bb4f173aac4 100644
--- a/clang/test/SemaHLSL/RootSignature-resource-ranges.hlsl
+++ b/clang/test/SemaHLSL/RootSignature-resource-ranges.hlsl
@@ -25,3 +25,6 @@ void valid_root_signature_6() {}
[RootSignature("DescriptorTable(CBV(b0, offset = 4294967292), CBV(b1, numDescriptors = 3))")]
void valid_root_signature_7() {}
+
+[RootSignature("DescriptorTable(CBV(b0, offset = 4294967294), CBV(b1))")]
+void valid_root_signature_8() {}
diff --git a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
index ea96094b18300..45353142267a6 100644
--- a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
+++ b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
@@ -38,7 +38,6 @@ LLVM_ABI bool verifyMipLODBias(float MipLODBias);
LLVM_ABI bool verifyMaxAnisotropy(uint32_t MaxAnisotropy);
LLVM_ABI bool verifyLOD(float LOD);
-LLVM_ABI bool verifyBoundOffset(uint32_t Offset);
LLVM_ABI bool verifyNoOverflowedOffset(uint64_t Offset);
LLVM_ABI uint64_t computeRangeBound(uint32_t Offset, uint32_t Size);
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
index 0970977b5064f..f3ea1698f3bf8 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
@@ -125,10 +125,6 @@ bool verifyMaxAnisotropy(uint32_t MaxAnisotropy) {
bool verifyLOD(float LOD) { return !std::isnan(LOD); }
-bool verifyBoundOffset(uint32_t Offset) {
- return Offset != NumDescriptorsUnbounded;
-}
-
bool verifyNoOverflowedOffset(uint64_t Offset) {
return Offset <= std::numeric_limits<uint32_t>::max();
}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there may be a gap in this implementation allowing binding of overlapping size 1 range at UINT_MAX Offset; plus some other nits; see comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, just want Tex to triple check to make sure we didn't miss anything
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
This pr corrects the validation behaviour to allow valid root signatures of the form:
DescriptorTable(CBV(b0, offset = 4294967294), CBV(b1))
which will append a range onto the location of
UINT_MAX
, which is valid.Resolves: #159478.