Skip to content

Commit 47662f0

Browse files
Joao SaffranJoao Saffran
authored andcommitted
Merge branch 'validation/overlapping-ranges' into validation/check-descriptors-are-bound
2 parents 21675e6 + 41f32bd commit 47662f0

File tree

10 files changed

+118
-116
lines changed

10 files changed

+118
-116
lines changed

llvm/include/llvm/Analysis/DXILResource.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,6 @@ class DXILResourceTypeMap;
3333

3434
namespace dxil {
3535

36-
inline StringRef getResourceClassName(ResourceClass RC) {
37-
switch (RC) {
38-
case ResourceClass::SRV:
39-
return "SRV";
40-
case ResourceClass::UAV:
41-
return "UAV";
42-
case ResourceClass::CBuffer:
43-
return "CBuffer";
44-
case ResourceClass::Sampler:
45-
return "Sampler";
46-
}
47-
llvm_unreachable("Unhandled ResourceClass");
48-
}
49-
5036
// Returns the resource name from dx_resource_handlefrombinding or
5137
// dx_resource_handlefromimplicitbinding call
5238
LLVM_ABI StringRef getResourceNameFromBindingCall(CallInst *CI);

llvm/include/llvm/Support/DXILABI.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#ifndef LLVM_SUPPORT_DXILABI_H
1818
#define LLVM_SUPPORT_DXILABI_H
1919

20+
#include "llvm/ADT/StringRef.h"
2021
#include <cstdint>
2122

2223
namespace llvm {
@@ -99,6 +100,8 @@ enum class SamplerFeedbackType : uint32_t {
99100
const unsigned MinWaveSize = 4;
100101
const unsigned MaxWaveSize = 128;
101102

103+
StringRef getResourceClassName(ResourceClass RC);
104+
102105
} // namespace dxil
103106
} // namespace llvm
104107

llvm/lib/Analysis/DXILResource.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/IR/Metadata.h"
2121
#include "llvm/IR/Module.h"
2222
#include "llvm/InitializePasses.h"
23+
#include "llvm/Support/DXILABI.h"
2324
#include "llvm/Support/FormatVariadic.h"
2425
#include <cstdint>
2526
#include <optional>

llvm/lib/Support/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ add_llvm_component_library(LLVMSupport
182182
DivisionByConstantInfo.cpp
183183
DAGDeltaAlgorithm.cpp
184184
DJB.cpp
185+
DXILABI.cpp
185186
DynamicAPInt.cpp
186187
ELFAttributes.cpp
187188
ELFAttrParserCompact.cpp

llvm/lib/Support/DXILABI.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
#include "llvm/Support/DXILABI.h"
3+
#include "llvm/Support/ErrorHandling.h"
4+
5+
using namespace llvm;
6+
namespace llvm {
7+
namespace dxil {
8+
StringRef getResourceClassName(dxil::ResourceClass RC) {
9+
switch (RC) {
10+
case dxil::ResourceClass::SRV:
11+
return "SRV";
12+
case dxil::ResourceClass::UAV:
13+
return "UAV";
14+
case dxil::ResourceClass::CBuffer:
15+
return "CBuffer";
16+
case dxil::ResourceClass::Sampler:
17+
return "Sampler";
18+
}
19+
llvm_unreachable("Unhandled ResourceClass");
20+
}
21+
} // namespace dxil
22+
} // namespace llvm

llvm/lib/Target/DirectX/DXContainerGlobals.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,7 @@ void DXContainerGlobals::addRootSignature(Module &M,
162162

163163
auto &RSA = getAnalysis<RootSignatureAnalysisWrapper>().getRSInfo();
164164
const Function *EntryFunction = MMI.EntryPropertyVec[0].Entry;
165-
const std::optional<mcdxbc::RootSignatureDesc> &RS =
166-
RSA.getDescForFunction(EntryFunction);
165+
const mcdxbc::RootSignatureDesc *RS = RSA.getDescForFunction(EntryFunction);
167166

168167
if (!RS)
169168
return;

llvm/lib/Target/DirectX/DXILOpLowering.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,7 @@ PreservedAnalyses DXILOpLowering::run(Module &M, ModuleAnalysisManager &MAM) {
919919
PA.preserve<DXILResourceAnalysis>();
920920
PA.preserve<DXILMetadataAnalysis>();
921921
PA.preserve<ShaderFlagsAnalysis>();
922+
PA.preserve<RootSignatureAnalysis>();
922923
return PA;
923924
}
924925

llvm/lib/Target/DirectX/DXILPostOptimizationValidation.cpp

Lines changed: 85 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@
1818
#include "llvm/IR/IntrinsicsDirectX.h"
1919
#include "llvm/IR/Module.h"
2020
#include "llvm/InitializePasses.h"
21+
#include "llvm/Support/DXILABI.h"
2122

2223
#define DEBUG_TYPE "dxil-post-optimization-validation"
2324

2425
using namespace llvm;
2526
using namespace llvm::dxil;
2627

27-
namespace {
28-
static ResourceClass RangeToResourceClass(uint32_t RangeType) {
28+
static ResourceClass toResourceClass(dxbc::DescriptorRangeType RangeType) {
2929
using namespace dxbc;
30-
switch (static_cast<DescriptorRangeType>(RangeType)) {
30+
switch (RangeType) {
3131
case DescriptorRangeType::SRV:
3232
return ResourceClass::SRV;
3333
case DescriptorRangeType::UAV:
@@ -39,20 +39,21 @@ static ResourceClass RangeToResourceClass(uint32_t RangeType) {
3939
}
4040
}
4141

42-
ResourceClass ParameterToResourceClass(uint32_t Type) {
42+
static ResourceClass toResourceClass(dxbc::RootParameterType Type) {
4343
using namespace dxbc;
4444
switch (Type) {
45-
case llvm::to_underlying(RootParameterType::Constants32Bit):
45+
case RootParameterType::Constants32Bit:
4646
return ResourceClass::CBuffer;
47-
case llvm::to_underlying(RootParameterType::SRV):
47+
case RootParameterType::SRV:
4848
return ResourceClass::SRV;
49-
case llvm::to_underlying(RootParameterType::UAV):
49+
case RootParameterType::UAV:
5050
return ResourceClass::UAV;
51-
case llvm::to_underlying(RootParameterType::CBV):
51+
case RootParameterType::CBV:
5252
return ResourceClass::CBuffer;
53-
default:
54-
llvm_unreachable("Unknown RootParameterType");
53+
case dxbc::RootParameterType::DescriptorTable:
54+
break;
5555
}
56+
llvm_unreachable("Unconvertible RootParameterType");
5657
}
5758

5859
static void reportInvalidDirection(Module &M, DXILResourceMap &DRM) {
@@ -143,12 +144,6 @@ reportRegNotBound(Module &M, ResourceClass Class,
143144

144145
static dxbc::ShaderVisibility
145146
tripleToVisibility(llvm::Triple::EnvironmentType ET) {
146-
assert((ET == Triple::Pixel || ET == Triple::Vertex ||
147-
ET == Triple::Geometry || ET == Triple::Hull ||
148-
ET == Triple::Domain || ET == Triple::Mesh ||
149-
ET == Triple::Compute) &&
150-
"Invalid Triple to shader stage conversion");
151-
152147
switch (ET) {
153148
case Triple::Pixel:
154149
return dxbc::ShaderVisibility::Pixel;
@@ -169,73 +164,103 @@ tripleToVisibility(llvm::Triple::EnvironmentType ET) {
169164
}
170165
}
171166

172-
static void trackRootSigDescBinding(hlsl::BindingInfoBuilder &Builder,
173-
const mcdxbc::RootSignatureDesc &RSD,
174-
dxbc::ShaderVisibility Visibility) {
175-
for (size_t I = 0; I < RSD.ParametersContainer.size(); I++) {
176-
const auto &[Type, Loc] =
177-
RSD.ParametersContainer.getTypeAndLocForParameter(I);
178-
179-
const auto &Header = RSD.ParametersContainer.getHeader(I);
180-
if (Header.ShaderVisibility !=
181-
llvm::to_underlying(dxbc::ShaderVisibility::All) &&
182-
Header.ShaderVisibility != llvm::to_underlying(Visibility))
167+
static void validateRootSignature(Module &M,
168+
const mcdxbc::RootSignatureDesc &RSD,
169+
dxil::ModuleMetadataInfo &MMI,
170+
DXILResourceMap &DRM) {
171+
172+
hlsl::BindingInfoBuilder Builder;
173+
dxbc::ShaderVisibility Visibility = tripleToVisibility(MMI.ShaderProfile);
174+
SmallVector<char> IDs;
175+
for (const mcdxbc::RootParameterInfo &ParamInfo : RSD.ParametersContainer) {
176+
dxbc::ShaderVisibility ParamVisibility =
177+
static_cast<dxbc::ShaderVisibility>(ParamInfo.Header.ShaderVisibility);
178+
if (ParamVisibility != dxbc::ShaderVisibility::All &&
179+
ParamVisibility != Visibility)
183180
continue;
184-
185-
switch (Type) {
186-
case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit): {
181+
dxbc::RootParameterType ParamType =
182+
static_cast<dxbc::RootParameterType>(ParamInfo.Header.ParameterType);
183+
switch (ParamType) {
184+
case dxbc::RootParameterType::Constants32Bit: {
187185
dxbc::RTS0::v1::RootConstants Const =
188-
RSD.ParametersContainer.getConstant(Loc);
186+
RSD.ParametersContainer.getConstant(ParamInfo.Location);
189187
Builder.trackBinding(dxil::ResourceClass::CBuffer, Const.RegisterSpace,
190-
Const.ShaderRegister,
191-
Const.ShaderRegister + Const.Num32BitValues, &Const);
188+
Const.ShaderRegister, Const.ShaderRegister,
189+
&IDs.emplace_back());
192190
break;
193191
}
194192

195-
case llvm::to_underlying(dxbc::RootParameterType::SRV):
196-
case llvm::to_underlying(dxbc::RootParameterType::UAV):
197-
case llvm::to_underlying(dxbc::RootParameterType::CBV): {
193+
case dxbc::RootParameterType::SRV:
194+
case dxbc::RootParameterType::UAV:
195+
case dxbc::RootParameterType::CBV: {
198196
dxbc::RTS0::v2::RootDescriptor Desc =
199-
RSD.ParametersContainer.getRootDescriptor(Loc);
200-
Builder.trackBinding(ParameterToResourceClass(Type), Desc.RegisterSpace,
201-
Desc.ShaderRegister, Desc.ShaderRegister, &Desc);
197+
RSD.ParametersContainer.getRootDescriptor(ParamInfo.Location);
198+
Builder.trackBinding(toResourceClass(static_cast<dxbc::RootParameterType>(
199+
ParamInfo.Header.ParameterType)),
200+
Desc.RegisterSpace, Desc.ShaderRegister,
201+
Desc.ShaderRegister, &IDs.emplace_back());
202202

203203
break;
204204
}
205-
case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {
205+
case dxbc::RootParameterType::DescriptorTable: {
206206
const mcdxbc::DescriptorTable &Table =
207-
RSD.ParametersContainer.getDescriptorTable(Loc);
207+
RSD.ParametersContainer.getDescriptorTable(ParamInfo.Location);
208208

209209
for (const dxbc::RTS0::v2::DescriptorRange &Range : Table.Ranges) {
210-
Builder.trackBinding(RangeToResourceClass(Range.RangeType),
211-
Range.RegisterSpace, Range.BaseShaderRegister,
212-
Range.NumDescriptors == ~0U
213-
? Range.NumDescriptors
214-
: Range.BaseShaderRegister +
215-
Range.NumDescriptors,
216-
&Range);
210+
uint32_t UpperBound =
211+
Range.NumDescriptors == ~0U
212+
? Range.BaseShaderRegister
213+
: Range.BaseShaderRegister + Range.NumDescriptors - 1;
214+
Builder.trackBinding(
215+
toResourceClass(
216+
static_cast<dxbc::DescriptorRangeType>(Range.RangeType)),
217+
Range.RegisterSpace, Range.BaseShaderRegister, UpperBound,
218+
&IDs.emplace_back());
217219
}
218220
break;
219221
}
220222
}
221223
}
222224

223-
for (auto &S : RSD.StaticSamplers) {
225+
for (const dxbc::RTS0::v1::StaticSampler &S : RSD.StaticSamplers)
224226
Builder.trackBinding(dxil::ResourceClass::Sampler, S.RegisterSpace,
225-
S.ShaderRegister, S.ShaderRegister, &S);
226-
}
227+
S.ShaderRegister, S.ShaderRegister,
228+
&IDs.emplace_back());
229+
bool HasOverlap = false;
230+
hlsl::BindingInfo Info = Builder.calculateBindingInfo(
231+
[&M, &HasOverlap](const llvm::hlsl::BindingInfoBuilder &Builder,
232+
const llvm::hlsl::BindingInfoBuilder::Binding &ReportedBinding) {
233+
HasOverlap = true;
234+
const llvm::hlsl::BindingInfoBuilder::Binding &Overlaping =
235+
Builder.findOverlapping(ReportedBinding);
236+
reportOverlappingRegisters(M, ReportedBinding, Overlaping);
237+
});
238+
// Next checks require that the root signature definition is valid.
239+
if (!HasOverlap) {
240+
for (const auto &ResList :
241+
{std::make_pair(ResourceClass::SRV, DRM.srvs()),
242+
std::make_pair(ResourceClass::UAV, DRM.uavs()),
243+
std::make_pair(ResourceClass::CBuffer, DRM.cbuffers()),
244+
std::make_pair(ResourceClass::Sampler, DRM.samplers())}) {
245+
for (auto Res : ResList.second) {
246+
llvm::dxil::ResourceInfo::ResourceBinding ResBinding =
247+
Res.getBinding();
248+
llvm::hlsl::BindingInfo::BindingRange ResRange(
249+
ResBinding.LowerBound, ResBinding.LowerBound + ResBinding.Size);
250+
251+
if (!Info.isBound(ResList.first, ResBinding.Space, ResRange))
252+
reportRegNotBound(M, ResList.first, ResBinding);
253+
}
254+
}
255+
}
227256
}
228257

229-
std::optional<mcdxbc::RootSignatureDesc>
258+
static mcdxbc::RootSignatureDesc *
230259
getRootSignature(RootSignatureBindingInfo &RSBI,
231260
dxil::ModuleMetadataInfo &MMI) {
232261
if (MMI.EntryPropertyVec.size() == 0)
233-
return std::nullopt;
234-
std::optional<mcdxbc::RootSignatureDesc> RootSigDesc =
235-
RSBI.getDescForFunction(MMI.EntryPropertyVec[0].Entry);
236-
if (!RootSigDesc)
237-
return std::nullopt;
238-
return RootSigDesc;
262+
return nullptr;
263+
return RSBI.getDescForFunction(MMI.EntryPropertyVec[0].Entry);
239264
}
240265

241266
static void reportErrors(Module &M, DXILResourceMap &DRM,
@@ -251,42 +276,9 @@ static void reportErrors(Module &M, DXILResourceMap &DRM,
251276
assert(!DRBI.hasImplicitBinding() && "implicit bindings should be handled in "
252277
"DXILResourceImplicitBinding pass");
253278

254-
if (auto RSD = getRootSignature(RSBI, MMI)) {
255-
256-
hlsl::BindingInfoBuilder Builder;
257-
dxbc::ShaderVisibility Visibility = tripleToVisibility(MMI.ShaderProfile);
258-
trackRootSigDescBinding(Builder, *RSD, Visibility);
259-
bool HasOverlap = false;
260-
hlsl::BindingInfo Info = Builder.calculateBindingInfo(
261-
[&M, &HasOverlap](
262-
const llvm::hlsl::BindingInfoBuilder &Builder,
263-
const llvm::hlsl::BindingInfoBuilder::Binding &ReportedBinding) {
264-
HasOverlap = true;
265-
const llvm::hlsl::BindingInfoBuilder::Binding &Overlaping =
266-
Builder.findOverlapping(ReportedBinding);
267-
reportOverlappingRegisters(M, ReportedBinding, Overlaping);
268-
});
269-
// Next checks require that the root signature definition is valid.
270-
if (!HasOverlap) {
271-
for (const auto &ResList :
272-
{std::make_pair(ResourceClass::SRV, DRM.srvs()),
273-
std::make_pair(ResourceClass::UAV, DRM.uavs()),
274-
std::make_pair(ResourceClass::CBuffer, DRM.cbuffers()),
275-
std::make_pair(ResourceClass::Sampler, DRM.samplers())}) {
276-
for (auto Res : ResList.second) {
277-
llvm::dxil::ResourceInfo::ResourceBinding ResBinding =
278-
Res.getBinding();
279-
llvm::hlsl::BindingInfo::BindingRange ResRange(
280-
ResBinding.LowerBound, ResBinding.LowerBound + ResBinding.Size);
281-
282-
if (!Info.isBound(ResList.first, ResBinding.Space, ResRange))
283-
reportRegNotBound(M, ResList.first, ResBinding);
284-
}
285-
}
286-
}
287-
}
279+
if (mcdxbc::RootSignatureDesc *RSD = getRootSignature(RSBI, MMI))
280+
validateRootSignature(M, *RSD, MMI, DRM);
288281
}
289-
} // namespace
290282

291283
PreservedAnalyses
292284
DXILPostOptimizationValidation::run(Module &M, ModuleAnalysisManager &MAM) {

llvm/lib/Target/DirectX/DXILRootSignature.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,11 @@ class RootSignatureBindingInfo {
4343

4444
iterator end() { return FuncToRsMap.end(); }
4545

46-
std::optional<mcdxbc::RootSignatureDesc>
47-
getDescForFunction(const Function *F) {
46+
mcdxbc::RootSignatureDesc *getDescForFunction(const Function *F) {
4847
const auto FuncRs = find(F);
4948
if (FuncRs == end())
50-
return std::nullopt;
51-
52-
return FuncRs->second;
49+
return nullptr;
50+
return &FuncRs->second;
5351
}
5452
};
5553

llvm/test/CodeGen/DirectX/rootsignature-validation-fail-root-descriptor-range.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@ entry:
66
ret void
77
}
88

9-
; DescriptorTable(UAV(u0, numDescriptors=unbounded), visibility = SHADER_VISIBILITY_HULL), UAV(u3, space=1)
109
!dx.rootsignatures = !{!0}
1110
!0 = !{ptr @CSMain, !1, i32 2}
1211
!1 = !{!2, !4}
1312
!2 = !{!"RootUAV", i32 0, i32 3, i32 1, i32 4}
1413
!4 = !{!"DescriptorTable", i32 0, !5}
15-
!5 = !{!"UAV", i32 3, i32 0, i32 1, i32 -1, i32 2}
14+
!5 = !{!"UAV", i32 4, i32 0, i32 1, i32 -1, i32 2}

0 commit comments

Comments
 (0)