[HLSL][SPIRV] Use 0 to represent unbounded arrays on shader flags#187174
Conversation
|
@llvm/pr-subscribers-backend-directx Author: None (joaosaffran) Changesthis patch updates the shader flags to account for 0 being used to represent unbounded arrays. This was a missed updated from the previous pr #186022 Full diff: https://github.com/llvm/llvm-project/pull/187174.diff 1 Files Affected:
diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
index 50d08b3a66dc1..49cfcdf615c55 100644
--- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
+++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
@@ -269,10 +269,12 @@ ModuleShaderFlags::gatherGlobalModuleFlags(const Module &M,
// Set the Max64UAVs flag if the number of UAVs is > 8
uint32_t NumUAVs = 0;
for (auto &UAV : DRM.uavs())
- if (MMDI.ValidatorVersion < VersionTuple(1, 6))
+ if (MMDI.ValidatorVersion < VersionTuple(1, 6)) {
NumUAVs++;
- else // MMDI.ValidatorVersion >= VersionTuple(1, 6)
- NumUAVs += UAV.getBinding().Size;
+ } else { // MMDI.ValidatorVersion >= VersionTuple(1, 6)
+ const uint32_t Size = UAV.getBinding().Size;
+ NumUAVs += Size == 0 ? ~0u : Size;
+ }
if (NumUAVs > 8)
CSF.Max64UAVs = true;
|
| NumUAVs += UAV.getBinding().Size; | ||
| } else { // MMDI.ValidatorVersion >= VersionTuple(1, 6) | ||
| const uint32_t Size = UAV.getBinding().Size; | ||
| NumUAVs += Size == 0 ? ~0u : Size; |
There was a problem hiding this comment.
Uh, this will overflow if NumUAVs is anything but zero coming into this. What happens if we have multiple unbounded UAVs (that is, in different spaces)? What happens if we have a bound UAV followed by an unbounded one?
I guess this is a pre-existing problem, since UAV.getBinding().Size would have been ~0U in that case anyway, but I think that this change is probably pointing out that we have a bug here.
There was a problem hiding this comment.
@tex3d, do you know what DXV expects in the scenario bogner is describing?
I've updated the PR comment to make it explicit, but this issue was found in the offload test suite, some tests were not passing dxv validation. Changing the flag value to account for unbounded fixed the issue. However, I am not sure if any tests account for such scenario.
There was a problem hiding this comment.
DXC/DXV adds a maximum of 9 to the count for each UAV range in an attempt to avoid overflow. It's not fool-proof, as nearly 500 million separate resource array decls of size 9 or greater could overflow it, but realistically, it would be virtually impossible to compile a shader that used that many decls.
See where this NumUAVs is gathered for DXC/DXV:
https://github.com/microsoft/DirectXShaderCompiler/blob/05de2c9fa9a4fec8e4a14b1ed605b81322680bd8/lib/DXIL/DxilModule.cpp#L319-L320
And where it's used to set the flag:
https://github.com/microsoft/DirectXShaderCompiler/blob/05de2c9fa9a4fec8e4a14b1ed605b81322680bd8/lib/DXIL/DxilModule.cpp#L333-L337
If that number is > 8 (kSmallUAVCount), it sets the flag.
You could add 9 or (kSmallUAVCount+1) when size is unbounded or > 8 like DXC does, and you could just set the flag and stop counting after NumUAVs > 8, for an easy overflow avoidance.
There was a problem hiding this comment.
Saturating NumUAVs to UINT32_MAX should also do the trick
bogner
left a comment
There was a problem hiding this comment.
Please add two tests here. One that demonstrates the case that regressed (a single unbounded array of resources), and one that demonstrates the pre-existing bug this fixes (a resource followed by an unbounded array of resources).
bogner
left a comment
There was a problem hiding this comment.
Looks good. A few mostly aesthetic comments about the tests (they all apply to both).
| @@ -0,0 +1,41 @@ | |||
| ; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s | |||
| ; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC | |||
There was a problem hiding this comment.
I guess this is just being consistent with the other files in this directory, but I don't understand the "DXC" check prefix... these checks have nothing to do with dxc. Can we use something more sensible, like CHECK-OBJ or CHECK-LLC or something?
| !llvm.module.flags = !{!0} | ||
| !0 = !{i32 1, !"dx.resmayalias", i32 1} |
There was a problem hiding this comment.
I don't think resmayalias is relevant to the test here, we should drop this.
There was a problem hiding this comment.
I suspect this is because the shader flag is ResMayNotAlias, so excluding this module flag will result in this shader flag being set, which adds noise to the output being checked.
| ; DXC: - Name: SFI0 | ||
| ; DXC-NEXT: Size: 8 | ||
| ; DXC-NEXT: Flags: | ||
| ; DXC: Max64UAVs: true |
There was a problem hiding this comment.
Can we align these a bit more consistently? If we indent everything to the length of the -NEXT checks the YAML is easier to read.
| ; DXC: - Name: SFI0 | |
| ; DXC-NEXT: Size: 8 | |
| ; DXC-NEXT: Flags: | |
| ; DXC: Max64UAVs: true | |
| ; DXC: - Name: SFI0 | |
| ; DXC-NEXT: Size: 8 | |
| ; DXC-NEXT: Flags: | |
| ; DXC: Max64UAVs: false |
There was a problem hiding this comment.
Did you mean to invert the Max64UAVs flag in your suggestion?
| ; DXC: NextUnusedBit: false | ||
| ; DXC: ... |
There was a problem hiding this comment.
I don't think these last two checks really do anything useful
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/3/builds/30288 Here is the relevant piece of the build log for the reference |
this patch updates the shader flags to account for 0 being used to represent unbounded arrays. This was a missed updated from the previous pr #186022. This change is required to make sure the following offload test pass dxv validation: