|
44 | 44 | #include "llvm/Support/DXILABI.h"
|
45 | 45 | #include "llvm/Support/ErrorHandling.h"
|
46 | 46 | #include "llvm/TargetParser/Triple.h"
|
| 47 | +#include <cmath> |
47 | 48 | #include <cstddef>
|
48 | 49 | #include <iterator>
|
49 | 50 | #include <utility>
|
@@ -1083,6 +1084,63 @@ void SemaHLSL::ActOnFinishRootSignatureDecl(
|
1083 | 1084 |
|
1084 | 1085 | bool SemaHLSL::handleRootSignatureElements(
|
1085 | 1086 | ArrayRef<hlsl::RootSignatureElement> Elements) {
|
| 1087 | + // Define some common error handling functions |
| 1088 | + bool HadError = false; |
| 1089 | + auto ReportError = [this, &HadError](SourceLocation Loc, uint32_t LowerBound, |
| 1090 | + uint32_t UpperBound) { |
| 1091 | + HadError = true; |
| 1092 | + this->Diag(Loc, diag::err_hlsl_invalid_rootsig_value) |
| 1093 | + << LowerBound << UpperBound; |
| 1094 | + }; |
| 1095 | + |
| 1096 | + auto VerifyRegister = [ReportError](SourceLocation Loc, uint32_t Register) { |
| 1097 | + if (!llvm::hlsl::rootsig::verifyRegisterValue(Register)) |
| 1098 | + ReportError(Loc, 0, 0xfffffffe); |
| 1099 | + }; |
| 1100 | + |
| 1101 | + auto VerifySpace = [ReportError](SourceLocation Loc, uint32_t Space) { |
| 1102 | + if (!llvm::hlsl::rootsig::verifyRegisterSpace(Space)) |
| 1103 | + ReportError(Loc, 0, 0xffffffef); |
| 1104 | + }; |
| 1105 | + |
| 1106 | + // Iterate through the elements and do basic validations |
| 1107 | + for (const hlsl::RootSignatureElement &RootSigElem : Elements) { |
| 1108 | + SourceLocation Loc = RootSigElem.getLocation(); |
| 1109 | + const llvm::hlsl::rootsig::RootElement &Elem = RootSigElem.getElement(); |
| 1110 | + if (const auto *Descriptor = |
| 1111 | + std::get_if<llvm::hlsl::rootsig::RootDescriptor>(&Elem)) { |
| 1112 | + VerifyRegister(Loc, Descriptor->Reg.Number); |
| 1113 | + VerifySpace(Loc, Descriptor->Space); |
| 1114 | + } else if (const auto *Constants = |
| 1115 | + std::get_if<llvm::hlsl::rootsig::RootConstants>(&Elem)) { |
| 1116 | + VerifyRegister(Loc, Constants->Reg.Number); |
| 1117 | + VerifySpace(Loc, Constants->Space); |
| 1118 | + } else if (const auto *Sampler = |
| 1119 | + std::get_if<llvm::hlsl::rootsig::StaticSampler>(&Elem)) { |
| 1120 | + VerifyRegister(Loc, Sampler->Reg.Number); |
| 1121 | + VerifySpace(Loc, Sampler->Space); |
| 1122 | + |
| 1123 | + assert(!std::isnan(Sampler->MaxLOD) && !std::isnan(Sampler->MinLOD) && |
| 1124 | + "By construction, parseFloatParam can't produce a NaN from a " |
| 1125 | + "float_literal token"); |
| 1126 | + |
| 1127 | + if (16 < Sampler->MaxAnisotropy) |
| 1128 | + ReportError(Loc, 0, 16); |
| 1129 | + } else if (const auto *Clause = |
| 1130 | + std::get_if<llvm::hlsl::rootsig::DescriptorTableClause>( |
| 1131 | + &Elem)) { |
| 1132 | + VerifyRegister(Loc, Clause->Reg.Number); |
| 1133 | + VerifySpace(Loc, Clause->Space); |
| 1134 | + |
| 1135 | + if (!llvm::hlsl::rootsig::verifyNumDescriptors(Clause->NumDescriptors)) { |
| 1136 | + // NumDescriptor could techincally be ~0u but that is reserved for |
| 1137 | + // unbounded, so the diagnostic will not report that as a valid int |
| 1138 | + // value |
| 1139 | + ReportError(Loc, 1, 0xfffffffe); |
| 1140 | + } |
| 1141 | + } |
| 1142 | + } |
| 1143 | + |
1086 | 1144 | using RangeInfo = llvm::hlsl::rootsig::RangeInfo;
|
1087 | 1145 | using OverlappingRanges = llvm::hlsl::rootsig::OverlappingRanges;
|
1088 | 1146 |
|
@@ -1136,7 +1194,10 @@ bool SemaHLSL::handleRootSignatureElements(
|
1136 | 1194 | &Elem)) {
|
1137 | 1195 | RangeInfo Info;
|
1138 | 1196 | Info.LowerBound = Clause->Reg.Number;
|
1139 |
| - assert(0 < Clause->NumDescriptors && "Verified as part of TODO(#129940)"); |
| 1197 | + // Relevant error will have already been reported above and needs to be |
| 1198 | + // fixed before we can conduct range analysis, so shortcut error return |
| 1199 | + if (Clause->NumDescriptors == 0) |
| 1200 | + return true; |
1140 | 1201 | Info.UpperBound = Clause->NumDescriptors == RangeInfo::Unbounded
|
1141 | 1202 | ? RangeInfo::Unbounded
|
1142 | 1203 | : Info.LowerBound + Clause->NumDescriptors -
|
|
0 commit comments