Skip to content

Commit acdba28

Browse files
authored
[DirectX] Set whole-module flags prior to evaluating per-function flags (#139967)
Fixes #139024 and #139954 - Refactor DXILShaderFlags to compute the flags that apply to a whole module before computing flags that apply individually to each function - Make DXILResourceMap const, since it is not modified in DXILShaderFlags - Per-function shader flag analysis now initially starts with the set of flags that apply to the whole module instead of starting from no flags. This change fixes the above linked issues - Fix shader flag tests affected by the above change
1 parent 6c40569 commit acdba28

11 files changed

+80
-67
lines changed

llvm/lib/Target/DirectX/DXILShaderFlags.cpp

+60-50
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
using namespace llvm;
3333
using namespace llvm::dxil;
3434

35-
static bool hasUAVsAtEveryStage(DXILResourceMap &DRM,
35+
static bool hasUAVsAtEveryStage(const DXILResourceMap &DRM,
3636
const ModuleMetadataInfo &MMDI) {
3737
if (DRM.uavs().empty())
3838
return false;
@@ -143,7 +143,7 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF,
143143
}
144144

145145
if (CSF.LowPrecisionPresent) {
146-
if (CanSetNativeLowPrecisionMode)
146+
if (CSF.NativeLowPrecisionMode)
147147
CSF.NativeLowPrecision = true;
148148
else
149149
CSF.MinimumPrecision = true;
@@ -207,26 +207,73 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF,
207207
}
208208
}
209209

210+
/// Set shader flags that apply to all functions within the module
211+
ComputedShaderFlags
212+
ModuleShaderFlags::gatherGlobalModuleFlags(const Module &M,
213+
const DXILResourceMap &DRM,
214+
const ModuleMetadataInfo &MMDI) {
215+
216+
ComputedShaderFlags CSF;
217+
218+
// Set DisableOptimizations flag based on the presence of OptimizeNone
219+
// attribute of entry functions.
220+
if (MMDI.EntryPropertyVec.size() > 0) {
221+
CSF.DisableOptimizations = MMDI.EntryPropertyVec[0].Entry->hasFnAttribute(
222+
llvm::Attribute::OptimizeNone);
223+
// Ensure all entry functions have the same optimization attribute
224+
for (const auto &EntryFunProps : MMDI.EntryPropertyVec)
225+
if (CSF.DisableOptimizations !=
226+
EntryFunProps.Entry->hasFnAttribute(llvm::Attribute::OptimizeNone))
227+
EntryFunProps.Entry->getContext().diagnose(DiagnosticInfoUnsupported(
228+
*(EntryFunProps.Entry), "Inconsistent optnone attribute "));
229+
}
230+
231+
CSF.UAVsAtEveryStage = hasUAVsAtEveryStage(DRM, MMDI);
232+
233+
// Set the Max64UAVs flag if the number of UAVs is > 8
234+
uint32_t NumUAVs = 0;
235+
for (auto &UAV : DRM.uavs())
236+
if (MMDI.ValidatorVersion < VersionTuple(1, 6))
237+
NumUAVs++;
238+
else // MMDI.ValidatorVersion >= VersionTuple(1, 6)
239+
NumUAVs += UAV.getBinding().Size;
240+
if (NumUAVs > 8)
241+
CSF.Max64UAVs = true;
242+
243+
// Set the module flag that enables native low-precision execution mode.
244+
// NativeLowPrecisionMode can only be set when the command line option
245+
// -enable-16bit-types is provided. This is indicated by the dx.nativelowprec
246+
// module flag being set
247+
// This flag is needed even if the module does not use 16-bit types because a
248+
// corresponding debug module may include 16-bit types, and tools that use the
249+
// debug module may expect it to have the same flags as the original
250+
if (auto *NativeLowPrec = mdconst::extract_or_null<ConstantInt>(
251+
M.getModuleFlag("dx.nativelowprec")))
252+
if (MMDI.ShaderModelVersion >= VersionTuple(6, 2))
253+
CSF.NativeLowPrecisionMode = NativeLowPrec->getValue().getBoolValue();
254+
255+
// Set ResMayNotAlias to true if DXIL validator version < 1.8 and there
256+
// are UAVs present globally.
257+
if (CanSetResMayNotAlias && MMDI.ValidatorVersion < VersionTuple(1, 8))
258+
CSF.ResMayNotAlias = !DRM.uavs().empty();
259+
260+
return CSF;
261+
}
262+
210263
/// Construct ModuleShaderFlags for module Module M
211264
void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM,
212-
DXILResourceMap &DRM,
265+
const DXILResourceMap &DRM,
213266
const ModuleMetadataInfo &MMDI) {
214267

215268
CanSetResMayNotAlias = MMDI.DXILVersion >= VersionTuple(1, 7);
216269
// The command line option -res-may-alias will set the dx.resmayalias module
217270
// flag to 1, thereby disabling the ability to set the ResMayNotAlias flag
218271
if (auto *ResMayAlias = mdconst::extract_or_null<ConstantInt>(
219272
M.getModuleFlag("dx.resmayalias")))
220-
CanSetResMayNotAlias = !ResMayAlias->getValue().getBoolValue();
273+
if (ResMayAlias->getValue().getBoolValue())
274+
CanSetResMayNotAlias = false;
221275

222-
// NativeLowPrecisionMode can only be set when the command line option
223-
// -enable-16bit-types is provided. This is indicated by the dx.nativelowprec
224-
// module flag being set
225-
CanSetNativeLowPrecisionMode = false;
226-
if (auto *NativeLowPrec = mdconst::extract_or_null<ConstantInt>(
227-
M.getModuleFlag("dx.nativelowprec")))
228-
if (MMDI.ShaderModelVersion >= VersionTuple(6, 2))
229-
CanSetNativeLowPrecisionMode = NativeLowPrec->getValue().getBoolValue();
276+
ComputedShaderFlags GlobalSFMask = gatherGlobalModuleFlags(M, DRM, MMDI);
230277

231278
CallGraph CG(M);
232279

@@ -252,7 +299,7 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM,
252299
continue;
253300
}
254301

255-
ComputedShaderFlags CSF;
302+
ComputedShaderFlags CSF = GlobalSFMask;
256303
for (const auto &BB : *F)
257304
for (const auto &I : BB)
258305
updateFunctionFlags(CSF, I, DRTM, MMDI);
@@ -273,43 +320,6 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM,
273320
// Merge SCCSF with that of F
274321
FunctionFlags[F].merge(SCCSF);
275322
}
276-
277-
// Set DisableOptimizations flag based on the presence of OptimizeNone
278-
// attribute of entry functions.
279-
if (MMDI.EntryPropertyVec.size() > 0) {
280-
CombinedSFMask.DisableOptimizations =
281-
MMDI.EntryPropertyVec[0].Entry->hasFnAttribute(
282-
llvm::Attribute::OptimizeNone);
283-
// Ensure all entry functions have the same optimization attribute
284-
for (const auto &EntryFunProps : MMDI.EntryPropertyVec)
285-
if (CombinedSFMask.DisableOptimizations !=
286-
EntryFunProps.Entry->hasFnAttribute(llvm::Attribute::OptimizeNone))
287-
EntryFunProps.Entry->getContext().diagnose(DiagnosticInfoUnsupported(
288-
*(EntryFunProps.Entry), "Inconsistent optnone attribute "));
289-
}
290-
291-
// Set ResMayNotAlias to true if DXIL validator version < 1.8 and there
292-
// are UAVs present globally.
293-
if (CanSetResMayNotAlias && MMDI.ValidatorVersion < VersionTuple(1, 8))
294-
CombinedSFMask.ResMayNotAlias = !DRM.uavs().empty();
295-
296-
// Set the module flag that enables native low-precision execution mode. This
297-
// is needed even if the module does not use 16-bit types because a
298-
// corresponding debug module may include 16-bit types, and tools that use the
299-
// debug module may expect it to have the same flags as the original
300-
CombinedSFMask.NativeLowPrecisionMode = CanSetNativeLowPrecisionMode;
301-
302-
// Set the Max64UAVs flag if the number of UAVs is > 8
303-
uint32_t NumUAVs = 0;
304-
for (auto &UAV : DRM.uavs())
305-
if (MMDI.ValidatorVersion < VersionTuple(1, 6))
306-
NumUAVs++;
307-
else // MMDI.ValidatorVersion >= VersionTuple(1, 6)
308-
NumUAVs += UAV.getBinding().Size;
309-
if (NumUAVs > 8)
310-
CombinedSFMask.Max64UAVs = true;
311-
312-
CombinedSFMask.UAVsAtEveryStage = hasUAVsAtEveryStage(DRM, MMDI);
313323
}
314324

315325
void ComputedShaderFlags::print(raw_ostream &OS) const {

llvm/lib/Target/DirectX/DXILShaderFlags.h

+8-5
Original file line numberDiff line numberDiff line change
@@ -85,22 +85,25 @@ struct ComputedShaderFlags {
8585
};
8686

8787
struct ModuleShaderFlags {
88-
void initialize(Module &, DXILResourceTypeMap &DRTM, DXILResourceMap &DRM,
89-
const ModuleMetadataInfo &MMDI);
88+
void initialize(Module &, DXILResourceTypeMap &DRTM,
89+
const DXILResourceMap &DRM, const ModuleMetadataInfo &MMDI);
9090
const ComputedShaderFlags &getFunctionFlags(const Function *) const;
9191
const ComputedShaderFlags &getCombinedFlags() const { return CombinedSFMask; }
9292

9393
private:
94-
// Booleans set by module flags
95-
bool CanSetResMayNotAlias; // dx.resmayalias
96-
bool CanSetNativeLowPrecisionMode; // dx.nativelowprec
94+
// This boolean is inversely set by the LLVM module flag dx.resmayalias to
95+
// determine whether or not the ResMayNotAlias DXIL module flag can be set
96+
bool CanSetResMayNotAlias;
9797

9898
/// Map of Function-Shader Flag Mask pairs representing properties of each of
9999
/// the functions in the module. Shader Flags of each function represent both
100100
/// module-level and function-level flags
101101
DenseMap<const Function *, ComputedShaderFlags> FunctionFlags;
102102
/// Combined Shader Flag Mask of all functions of the module
103103
ComputedShaderFlags CombinedSFMask{};
104+
ComputedShaderFlags gatherGlobalModuleFlags(const Module &M,
105+
const DXILResourceMap &,
106+
const ModuleMetadataInfo &);
104107
void updateFunctionFlags(ComputedShaderFlags &, const Instruction &,
105108
DXILResourceTypeMap &, const ModuleMetadataInfo &);
106109
};

llvm/test/CodeGen/DirectX/ShaderFlags/disable-opt-cs.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
; CHECK-NEXT: ; Disable shader optimizations
99

1010
; CHECK: ; Shader Flags for Module Functions
11-
; CHECK: ; Function main : 0x00000000
11+
; CHECK: ; Function main : 0x00000001
1212
; The test source in this file generated from the following command:
1313
; clang -cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -emit-llvm -O0 -o - <<EOF
1414
; [numthreads(1,1,1)]

llvm/test/CodeGen/DirectX/ShaderFlags/disable-opt-lib.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
; CHECK-NEXT: ; Disable shader optimizations
99

1010
; CHECK: ; Shader Flags for Module Functions
11-
; CHECK: ; Function main : 0x00000000
11+
; CHECK: ; Function main : 0x00000001
1212
; The test source in this file generated from the following command:
1313
; clang -cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -O0 -o - <<EOF
1414

llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.5.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ target triple = "dxil-pc-shadermodel6.7-library"
1313
; CHECK: UAVs at every shader stage
1414
; CHECK-NOT: 64 UAV slots
1515

16-
; CHECK: Function test : 0x00000000
16+
; CHECK: Function test : 0x00010000
1717
define void @test() "hlsl.export" {
1818
; RWBuffer<float> Buf : register(u0, space0)
1919
%buf0 = call target("dx.TypedBuffer", float, 1, 0, 1)

llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs-array-valver1.6.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ target triple = "dxil-pc-shadermodel6.7-library"
1414
; CHECK: UAVs at every shader stage
1515
; CHECK: 64 UAV slots
1616

17-
; CHECK: Function test : 0x00000000
17+
; CHECK: Function test : 0x00018000
1818
define void @test() "hlsl.export" {
1919
; RWBuffer<float> Buf : register(u0, space0)
2020
%buf0 = call target("dx.TypedBuffer", float, 1, 0, 1)

llvm/test/CodeGen/DirectX/ShaderFlags/max-64-uavs.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ target triple = "dxil-pc-shadermodel6.7-library"
1313
; CHECK: 64 UAV slots
1414

1515
; Note: 64 UAV slots does not get set per-function
16-
; CHECK: Function test : 0x00000000
16+
; CHECK: Function test : 0x00008000
1717
define void @test() "hlsl.export" {
1818
; RWBuffer<float> Buf : register(u0, space0)
1919
%buf0 = call target("dx.TypedBuffer", float, 1, 0, 1)

llvm/test/CodeGen/DirectX/ShaderFlags/res-may-not-alias-sm6.7.ll

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ target triple = "dxil-pc-shadermodel6.7-library"
1919
; CHECK: Any UAV may not alias any other UAV
2020
;
2121

22-
; CHECK: Function loadUAV : 0x00000000
22+
; CHECK: Function loadUAV : 0x200010000
2323
define float @loadUAV() #0 {
2424
%res = call target("dx.TypedBuffer", float, 1, 0, 0)
2525
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false)
@@ -29,7 +29,7 @@ define float @loadUAV() #0 {
2929
ret float %val
3030
}
3131

32-
; CHECK: Function loadSRV : 0x00000010
32+
; CHECK: Function loadSRV : 0x200010010
3333
define float @loadSRV() #0 {
3434
%res = tail call target("dx.RawBuffer", float, 0, 0)
3535
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false)

llvm/test/CodeGen/DirectX/ShaderFlags/uavs-at-every-stage-lib-valver1.7.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ target triple = "dxil-pc-shadermodel6.5-library"
1212
; CHECK: Note: shader requires additional functionality:
1313
; CHECK: UAVs at every shader stage
1414

15-
; CHECK: Function test : 0x00000000
15+
; CHECK: Function test : 0x00010000
1616
define void @test() "hlsl.export" {
1717
; RWBuffer<float> Buf : register(u0, space0)
1818
%buf0 = call target("dx.TypedBuffer", float, 1, 0, 1)

llvm/test/CodeGen/DirectX/ShaderFlags/uavs-at-every-stage-vs.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ target triple = "dxil-pc-shadermodel6.5-vertex"
1313
; CHECK: Note: shader requires additional functionality:
1414
; CHECK: UAVs at every shader stage
1515

16-
; CHECK: Function VSMain : 0x00000000
16+
; CHECK: Function VSMain : 0x00010000
1717
define void @VSMain() {
1818
; RWBuffer<float> Buf : register(u0, space0)
1919
%buf0 = call target("dx.TypedBuffer", float, 1, 0, 1)

llvm/test/CodeGen/DirectX/ShaderFlags/use-native-low-precision-1.ll

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,19 @@ target triple = "dxil-pc-shadermodel6.7-library"
1818
;CHECK-NEXT: ;
1919
;CHECK-NEXT: ; Shader Flags for Module Functions
2020

21-
;CHECK-LABEL: ; Function add_i16 : 0x00000020
21+
;CHECK-LABEL: ; Function add_i16 : 0x00800020
2222
define i16 @add_i16(i16 %a, i16 %b) "hlsl.export" {
2323
%sum = add i16 %a, %b
2424
ret i16 %sum
2525
}
2626

27-
;CHECK-LABEL: ; Function add_i32 : 0x00000000
27+
;CHECK-LABEL: ; Function add_i32 : 0x00800000
2828
define i32 @add_i32(i32 %a, i32 %b) "hlsl.export" {
2929
%sum = add i32 %a, %b
3030
ret i32 %sum
3131
}
3232

33-
;CHECK-LABEL: ; Function add_half : 0x00000020
33+
;CHECK-LABEL: ; Function add_half : 0x00800020
3434
define half @add_half(half %a, half %b) "hlsl.export" {
3535
%sum = fadd half %a, %b
3636
ret half %sum

0 commit comments

Comments
 (0)