diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp index 50d08b3a66dc1..e446a92bf2781 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp @@ -269,10 +269,15 @@ 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) + uint32_t Size = UAV.getBinding().Size; + uint32_t NewNum = NumUAVs + (Size == 0 ? ~0U : Size); + if (NewNum < NumUAVs) + NewNum = ~0U; + NumUAVs = NewNum; + } if (NumUAVs > 8) CSF.Max64UAVs = true; diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/overflow-uavs-array.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/overflow-uavs-array.ll new file mode 100644 index 0000000000000..6b08f62ff73ed --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/overflow-uavs-array.ll @@ -0,0 +1,36 @@ +; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s +; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=OBJ + +; This test makes sure that no overflow is happening when a resource is followed +; by an unbounded array of UAVs. + +target triple = "dxil-pc-shadermodel6.7-library" + +; CHECK: Combined Shader Flags for Module +; CHECK-NEXT: Shader Flags Value: 0x200018000 + +; CHECK: Note: shader requires additional functionality: +; CHECK: UAVs at every shader stage +; CHECK: 64 UAV slots + +; CHECK: Function test : 0x200018000 +define void @test() "hlsl.export" { + ; RWBuffer Buf : register(u0, space0) + %buf0 = call target("dx.TypedBuffer", float, 1, 0, 1) + @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0t( + i32 0, i32 0, i32 1, i32 0, ptr null) + + ; RWBuffer Buf[] : register(u1, space0) + %buf1 = call target("dx.TypedBuffer", float, 1, 0, 1) + @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0t( + i32 0, i32 1, i32 0, i32 0, ptr null) + ret void +} + +!dx.valver = !{!1} +!1 = !{i32 1, i32 6} + +; OBJ: - Name: SFI0 +; OBJ-NEXT: Size: 8 +; OBJ-NEXT: Flags: +; OBJ: Max64UAVs: true diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/unbounded-uavs-array.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/unbounded-uavs-array.ll new file mode 100644 index 0000000000000..ba323d60fb530 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/unbounded-uavs-array.ll @@ -0,0 +1,31 @@ +; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s +; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=OBJ + +; This test makes sure that Max64UAVs is correctly set when using an +; unbounded array of UAVs; + +target triple = "dxil-pc-shadermodel6.7-library" + +; CHECK: Combined Shader Flags for Module +; CHECK-NEXT: Shader Flags Value: 0x200018000 + +; CHECK: Note: shader requires additional functionality: +; CHECK: UAVs at every shader stage +; CHECK: 64 UAV slots + +; CHECK: Function test : 0x200018000 +define void @test() "hlsl.export" { + ; RWBuffer Buf[] : register(u1, space0) + %buf1 = call target("dx.TypedBuffer", float, 1, 0, 1) + @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0t( + i32 0, i32 1, i32 0, i32 0, ptr null) + ret void +} + +!dx.valver = !{!1} +!1 = !{i32 1, i32 6} + +; OBJ: - Name: SFI0 +; OBJ-NEXT: Size: 8 +; OBJ-NEXT: Flags: +; OBJ: Max64UAVs: true