Skip to content
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
29 changes: 13 additions & 16 deletions clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1360,7 +1360,8 @@ bool SemaHLSL::handleRootSignatureElements(
"Number of unbound elements must match the number of clauses");
bool HasAnySampler = false;
bool HasAnyNonSampler = false;
uint32_t Offset = 0;
uint64_t Offset = 0;
bool IsPrevUnbound = false;
for (const auto &[Clause, ClauseElem] : UnboundClauses) {
SourceLocation Loc = ClauseElem->getLocation();
if (Clause->Type == llvm::dxil::ResourceClass::Sampler)
Expand All @@ -1377,32 +1378,28 @@ bool SemaHLSL::handleRootSignatureElements(
if (Clause->NumDescriptors == 0)
return true;

if (Clause->Offset !=
llvm::hlsl::rootsig::DescriptorTableOffsetAppend) {
// Manually specified the offset
bool IsAppending =
Clause->Offset == llvm::hlsl::rootsig::DescriptorTableOffsetAppend;
if (!IsAppending)
Offset = Clause->Offset;
}

uint64_t RangeBound = llvm::hlsl::rootsig::computeRangeBound(
Offset, Clause->NumDescriptors);

if (!llvm::hlsl::rootsig::verifyBoundOffset(Offset)) {
// Trying to append onto unbound offset
if (IsPrevUnbound && IsAppending)
Diag(Loc, diag::err_hlsl_appending_onto_unbound);
} else if (!llvm::hlsl::rootsig::verifyNoOverflowedOffset(RangeBound)) {
// Upper bound overflows maximum offset
else if (!llvm::hlsl::rootsig::verifyNoOverflowedOffset(RangeBound))
Diag(Loc, diag::err_hlsl_offset_overflow) << Offset << RangeBound;
}

Offset = RangeBound == llvm::hlsl::rootsig::NumDescriptorsUnbounded
? uint32_t(RangeBound)
: uint32_t(RangeBound + 1);
// Update offset to be 1 past this range's bound
Offset = RangeBound + 1;
IsPrevUnbound = Clause->NumDescriptors ==
llvm::hlsl::rootsig::NumDescriptorsUnbounded;

// Compute the register bounds and track resource binding
uint32_t LowerBound(Clause->Reg.Number);
uint32_t UpperBound = Clause->NumDescriptors == ~0u
? ~0u
: LowerBound + Clause->NumDescriptors - 1;
uint32_t UpperBound = llvm::hlsl::rootsig::computeRangeBound(
LowerBound, Clause->NumDescriptors);

BindingChecker.trackBinding(
Table->Visibility,
Expand Down
10 changes: 9 additions & 1 deletion clang/test/SemaHLSL/RootSignature-resource-ranges-err.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,12 @@ 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() {}

// expected-error@+1 {{descriptor range offset overflows [4294967296, 4294967296]}}
[RootSignature("DescriptorTable(CBV(b0, offset = 4294967294), CBV(b1), CBV(b2))")]
void multiple_appended_offset_overflow() {}
3 changes: 3 additions & 0 deletions clang/test/SemaHLSL/RootSignature-resource-ranges.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
3 changes: 1 addition & 2 deletions llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ 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);
LLVM_ABI uint64_t computeRangeBound(uint64_t Offset, uint32_t Size);

} // namespace rootsig
} // namespace hlsl
Expand Down
8 changes: 2 additions & 6 deletions llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,20 +125,16 @@ 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();
}

uint64_t computeRangeBound(uint32_t Offset, uint32_t Size) {
uint64_t computeRangeBound(uint64_t Offset, uint32_t Size) {
assert(0 < Size && "Must be a non-empty range");
if (Size == NumDescriptorsUnbounded)
return NumDescriptorsUnbounded;

return uint64_t(Offset) + uint64_t(Size) - 1;
return Offset + uint64_t(Size) - 1;
}

} // namespace rootsig
Expand Down