Skip to content

Commit ad5fbee

Browse files
committed
Initial ResMayNotAlias shader flag implementation
1 parent 9a65dc9 commit ad5fbee

File tree

9 files changed

+145
-6
lines changed

9 files changed

+145
-6
lines changed

clang/include/clang/Basic/CodeGenOptions.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,9 @@ CODEGENOPT(ImportCallOptimization, 1, 0)
476476
/// (BlocksRuntime) on Windows.
477477
CODEGENOPT(StaticClosure, 1, 0)
478478

479+
/// Assume that UAVs/SRVs may alias
480+
CODEGENOPT(ResMayAlias, 1, 0)
481+
479482
/// FIXME: Make DebugOptions its own top-level .def file.
480483
#include "DebugOptions.def"
481484

clang/include/clang/Driver/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9044,6 +9044,11 @@ def dxil_validator_version : Option<["/", "-"], "validator-version", KIND_SEPARA
90449044
HelpText<"Override validator version for module. Format: <major.minor>;"
90459045
"Default: DXIL.dll version or current internal version">,
90469046
MarshallingInfoString<TargetOpts<"DxilValidatorVersion">, "\"1.8\"">;
9047+
def res_may_alias : Option<["/", "-"], "res-may-alias", KIND_FLAG>,
9048+
Group<dxc_Group>, Flags<[HelpHidden]>,
9049+
Visibility<[DXCOption, ClangOption, CC1Option]>,
9050+
HelpText<"Assume that UAVs/SRVs may alias">,
9051+
MarshallingInfoFlag<CodeGenOpts<"ResMayAlias">>;
90479052
def target_profile : DXCJoinedOrSeparate<"T">, MetaVarName<"<profile>">,
90489053
HelpText<"Set target profile">,
90499054
Values<"ps_6_0, ps_6_1, ps_6_2, ps_6_3, ps_6_4, ps_6_5, ps_6_6, ps_6_7,"

clang/lib/CodeGen/CGHLSLRuntime.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,13 @@ void CGHLSLRuntime::addHLSLBufferLayoutType(const RecordType *StructType,
252252

253253
void CGHLSLRuntime::finishCodeGen() {
254254
auto &TargetOpts = CGM.getTarget().getTargetOpts();
255+
auto &CodeGenOpts = CGM.getCodeGenOpts();
255256
llvm::Module &M = CGM.getModule();
256257
Triple T(M.getTargetTriple());
257258
if (T.getArch() == Triple::ArchType::dxil)
258259
addDxilValVersion(TargetOpts.DxilValidatorVersion, M);
260+
if (CodeGenOpts.ResMayAlias)
261+
M.setModuleFlag(llvm::Module::ModFlagBehavior::Error, "dx.resmayalias", 1);
259262

260263
generateGlobalCtorDtorCalls();
261264
}

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3960,6 +3960,7 @@ static void RenderOpenCLOptions(const ArgList &Args, ArgStringList &CmdArgs,
39603960
static void RenderHLSLOptions(const ArgList &Args, ArgStringList &CmdArgs,
39613961
types::ID InputType) {
39623962
const unsigned ForwardedArguments[] = {options::OPT_dxil_validator_version,
3963+
options::OPT_res_may_alias,
39633964
options::OPT_D,
39643965
options::OPT_I,
39653966
options::OPT_O,

llvm/lib/Target/DirectX/DXILShaderFlags.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
//===----------------------------------------------------------------------===//
1313

1414
#include "DXILShaderFlags.h"
15+
#include "DXILResourceAnalysis.h"
1516
#include "DirectX.h"
1617
#include "llvm/ADT/SCCIterator.h"
1718
#include "llvm/ADT/SmallVector.h"
@@ -74,6 +75,7 @@ static bool checkWaveOps(Intrinsic::ID IID) {
7475
/// \param I Instruction to check.
7576
void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF,
7677
const Instruction &I,
78+
const ModuleMetadataInfo &MMDI,
7779
DXILResourceTypeMap &DRTM) {
7880
if (!CSF.Doubles)
7981
CSF.Doubles = I.getType()->isDoubleTy();
@@ -117,6 +119,11 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF,
117119
default:
118120
break;
119121
case Intrinsic::dx_resource_handlefrombinding:
122+
if (!ResMayAlias && !CSF.ResMayNotAlias &&
123+
MMDI.DXILVersion > VersionTuple(1, 7) &&
124+
DRTM[cast<TargetExtType>(II->getType())].isUAV()) {
125+
CSF.ResMayNotAlias = true;
126+
}
120127
switch (DRTM[cast<TargetExtType>(II->getType())].getResourceKind()) {
121128
case dxil::ResourceKind::StructuredBuffer:
122129
case dxil::ResourceKind::RawBuffer:
@@ -151,7 +158,14 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF,
151158

152159
/// Construct ModuleShaderFlags for module Module M
153160
void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM,
154-
const ModuleMetadataInfo &MMDI) {
161+
const ModuleMetadataInfo &MMDI,
162+
const dxil::Resources &MDR) {
163+
164+
if (mdconst::extract_or_null<ConstantInt>(
165+
M.getModuleFlag("dx.resmayalias"))) {
166+
ResMayAlias = true;
167+
}
168+
155169
CallGraph CG(M);
156170

157171
// Compute Shader Flags Mask for all functions using post-order visit of SCC
@@ -176,10 +190,15 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM,
176190
continue;
177191
}
178192

193+
if (!ResMayAlias && !SCCSF.ResMayNotAlias &&
194+
MMDI.DXILVersion <= VersionTuple(1, 7)) {
195+
SCCSF.ResMayNotAlias = MDR.hasUAVs();
196+
}
197+
179198
ComputedShaderFlags CSF;
180199
for (const auto &BB : *F)
181200
for (const auto &I : BB)
182-
updateFunctionFlags(CSF, I, DRTM);
201+
updateFunctionFlags(CSF, I, MMDI, DRTM);
183202
// Update combined shader flags mask for all functions in this SCC
184203
SCCSF.merge(CSF);
185204

@@ -250,9 +269,10 @@ ModuleShaderFlags ShaderFlagsAnalysis::run(Module &M,
250269
ModuleAnalysisManager &AM) {
251270
DXILResourceTypeMap &DRTM = AM.getResult<DXILResourceTypeAnalysis>(M);
252271
const ModuleMetadataInfo MMDI = AM.getResult<DXILMetadataAnalysis>(M);
272+
const dxil::Resources &MDR = AM.getResult<DXILResourceMDAnalysis>(M);
253273

254274
ModuleShaderFlags MSFI;
255-
MSFI.initialize(M, DRTM, MMDI);
275+
MSFI.initialize(M, DRTM, MMDI, MDR);
256276

257277
return MSFI;
258278
}
@@ -284,14 +304,16 @@ bool ShaderFlagsAnalysisWrapper::runOnModule(Module &M) {
284304
getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap();
285305
const ModuleMetadataInfo MMDI =
286306
getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata();
307+
dxil::Resources &MDR = getAnalysis<DXILResourceMDWrapper>().getDXILResource();
287308

288-
MSFI.initialize(M, DRTM, MMDI);
309+
MSFI.initialize(M, DRTM, MMDI, MDR);
289310
return false;
290311
}
291312

292313
void ShaderFlagsAnalysisWrapper::getAnalysisUsage(AnalysisUsage &AU) const {
293314
AU.setPreservesAll();
294315
AU.addRequiredTransitive<DXILResourceTypeWrapperPass>();
316+
AU.addRequired<DXILResourceMDWrapper>();
295317
AU.addRequired<DXILMetadataAnalysisWrapperPass>();
296318
}
297319

llvm/lib/Target/DirectX/DXILShaderFlags.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#ifndef LLVM_TARGET_DIRECTX_DXILSHADERFLAGS_H
1515
#define LLVM_TARGET_DIRECTX_DXILSHADERFLAGS_H
1616

17+
#include "DXILResource.h"
1718
#include "llvm/Analysis/DXILMetadataAnalysis.h"
1819
#include "llvm/IR/Function.h"
1920
#include "llvm/IR/PassManager.h"
@@ -85,7 +86,7 @@ struct ComputedShaderFlags {
8586

8687
struct ModuleShaderFlags {
8788
void initialize(Module &, DXILResourceTypeMap &DRTM,
88-
const ModuleMetadataInfo &MMDI);
89+
const ModuleMetadataInfo &MMDI, const dxil::Resources &MDR);
8990
const ComputedShaderFlags &getFunctionFlags(const Function *) const;
9091
const ComputedShaderFlags &getCombinedFlags() const { return CombinedSFMask; }
9192

@@ -97,7 +98,11 @@ struct ModuleShaderFlags {
9798
/// Combined Shader Flag Mask of all functions of the module
9899
ComputedShaderFlags CombinedSFMask{};
99100
void updateFunctionFlags(ComputedShaderFlags &, const Instruction &,
100-
DXILResourceTypeMap &);
101+
const ModuleMetadataInfo &MMDI,
102+
DXILResourceTypeMap &DRTM);
103+
104+
// Set to indicate if the -res-may-alias flag was passed to clang-dxc
105+
bool ResMayAlias = false;
101106
};
102107

103108
class ShaderFlagsAnalysis : public AnalysisInfoMixin<ShaderFlagsAnalysis> {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
; TODO: Figure out an appropriate RUN command for this test. Normally, -res-may-alias is only applicable to clang-dxc
2+
; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
3+
4+
target triple = "dxil-pc-shadermodel6.8-library"
5+
6+
; CHECK: Combined Shader Flags for Module
7+
; CHECK-NEXT: Shader Flags Value: 0x00000010
8+
9+
; CHECK: Note: extra DXIL module flags:
10+
; CHECK: Raw and Structured buffers
11+
; CHECK-NOT: Any UAV may not alias any other UAV
12+
;
13+
14+
; CHECK: Function loadUAV : 0x00000000
15+
define float @loadUAV() #0 {
16+
%res = call target("dx.TypedBuffer", float, 1, 0, 0)
17+
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false)
18+
%load = call {float, i1} @llvm.dx.resource.load.typedbuffer(
19+
target("dx.TypedBuffer", float, 1, 0, 0) %res, i32 0)
20+
%val = extractvalue {float, i1} %load, 0
21+
ret float %val
22+
}
23+
24+
; CHECK: Function loadSRV : 0x00000010
25+
define float @loadSRV() #0 {
26+
%res = tail call target("dx.RawBuffer", float, 0, 0)
27+
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false)
28+
%load = call {float, i1} @llvm.dx.resource.load.rawbuffer(
29+
target("dx.RawBuffer", float, 0, 0) %res, i32 0, i32 0)
30+
%val = extractvalue { float, i1 } %load, 0
31+
ret float %val
32+
}
33+
34+
attributes #0 = { convergent norecurse nounwind "hlsl.export"}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
2+
3+
target triple = "dxil-pc-shadermodel6.7-library"
4+
5+
; CHECK: Combined Shader Flags for Module
6+
; CHECK-NEXT: Shader Flags Value: 0x200000010
7+
8+
; CHECK: Note: extra DXIL module flags:
9+
; CHECK: Raw and Structured buffers
10+
; CHECK: Any UAV may not alias any other UAV
11+
;
12+
13+
; CHECK: Function loadUAV : 0x00000000
14+
define float @loadUAV() #0 {
15+
%res = call target("dx.TypedBuffer", float, 1, 0, 0)
16+
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false)
17+
%load = call {float, i1} @llvm.dx.resource.load.typedbuffer(
18+
target("dx.TypedBuffer", float, 1, 0, 0) %res, i32 0)
19+
%val = extractvalue {float, i1} %load, 0
20+
ret float %val
21+
}
22+
23+
; CHECK: Function loadSRV : 0x00000010
24+
define float @loadSRV() #0 {
25+
%res = tail call target("dx.RawBuffer", float, 0, 0)
26+
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false)
27+
%load = call {float, i1} @llvm.dx.resource.load.rawbuffer(
28+
target("dx.RawBuffer", float, 0, 0) %res, i32 0, i32 0)
29+
%val = extractvalue { float, i1 } %load, 0
30+
ret float %val
31+
}
32+
33+
attributes #0 = { convergent norecurse nounwind "hlsl.export"}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
2+
3+
target triple = "dxil-pc-shadermodel6.8-library"
4+
5+
; CHECK: Combined Shader Flags for Module
6+
; CHECK-NEXT: Shader Flags Value: 0x200000010
7+
8+
; CHECK: Note: extra DXIL module flags:
9+
; CHECK: Raw and Structured buffers
10+
; CHECK: Any UAV may not alias any other UAV
11+
;
12+
13+
; CHECK: Function loadUAV : 0x20000000
14+
define float @loadUAV() #0 {
15+
%res = call target("dx.TypedBuffer", float, 1, 0, 0)
16+
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false)
17+
%load = call {float, i1} @llvm.dx.resource.load.typedbuffer(
18+
target("dx.TypedBuffer", float, 1, 0, 0) %res, i32 0)
19+
%val = extractvalue {float, i1} %load, 0
20+
ret float %val
21+
}
22+
23+
; CHECK: Function loadSRV : 0x00000010
24+
define float @loadSRV() #0 {
25+
%res = tail call target("dx.RawBuffer", float, 0, 0)
26+
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false)
27+
%load = call {float, i1} @llvm.dx.resource.load.rawbuffer(
28+
target("dx.RawBuffer", float, 0, 0) %res, i32 0, i32 0)
29+
%val = extractvalue { float, i1 } %load, 0
30+
ret float %val
31+
}
32+
33+
attributes #0 = { convergent norecurse nounwind "hlsl.export"}

0 commit comments

Comments
 (0)