diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp index 9fa137b4c025e..3cea08b7ae18e 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp @@ -13,8 +13,11 @@ #include "DXILShaderFlags.h" #include "DirectX.h" +#include "llvm/Analysis/DXILMetadataAnalysis.h" +#include "llvm/Analysis/DXILResource.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Module.h" +#include "llvm/Support/DXILABI.h" #include "llvm/Support/FormatVariadic.h" using namespace llvm; @@ -36,8 +39,43 @@ static void updateFlags(ComputedShaderFlags &Flags, const Instruction &I) { } } -ComputedShaderFlags ComputedShaderFlags::computeFlags(Module &M) { +static void updateResourceFlags(ComputedShaderFlags &Flags, Module &M, + ModuleAnalysisManager *AM) { + if (!AM) + return; + + const DXILResourceMap &DRM = AM->getResult(M); + if (DRM.empty()) + return; + + for (const ResourceInfo &RI : DRM.uavs()) { + switch (RI.getResourceKind()) { + case ResourceKind::RawBuffer: + case ResourceKind::StructuredBuffer: + Flags.EnableRawAndStructuredBuffers = true; + break; + default: + break; + } + } + + for (const ResourceInfo &RI : DRM.srvs()) { + switch (RI.getResourceKind()) { + case ResourceKind::RawBuffer: + case ResourceKind::StructuredBuffer: + Flags.EnableRawAndStructuredBuffers = true; + break; + default: + break; + } + } +} + +ComputedShaderFlags +ComputedShaderFlags::computeFlags(Module &M, ModuleAnalysisManager *AM) { ComputedShaderFlags Flags; + updateResourceFlags(Flags, M, AM); + for (const auto &F : M) for (const auto &BB : F) for (const auto &I : BB) @@ -67,7 +105,7 @@ AnalysisKey ShaderFlagsAnalysis::Key; ComputedShaderFlags ShaderFlagsAnalysis::run(Module &M, ModuleAnalysisManager &AM) { - return ComputedShaderFlags::computeFlags(M); + return ComputedShaderFlags::computeFlags(M, &AM); } PreservedAnalyses ShaderFlagsAnalysisPrinter::run(Module &M, diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.h b/llvm/lib/Target/DirectX/DXILShaderFlags.h index 1df7d27de13d3..86d0a70dcbee1 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.h +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.h @@ -60,7 +60,7 @@ struct ComputedShaderFlags { return FeatureFlags; } - static ComputedShaderFlags computeFlags(Module &M); + static ComputedShaderFlags computeFlags(Module &M, ModuleAnalysisManager *AM); void print(raw_ostream &OS = dbgs()) const; LLVM_DUMP_METHOD void dump() const { print(); } }; @@ -102,7 +102,7 @@ class ShaderFlagsAnalysisWrapper : public ModulePass { const ComputedShaderFlags &getShaderFlags() { return Flags; } bool runOnModule(Module &M) override { - Flags = ComputedShaderFlags::computeFlags(M); + Flags = ComputedShaderFlags::computeFlags(M, nullptr); return false; } diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/buffer.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/buffer.ll new file mode 100644 index 0000000000000..c31ecbf4385d9 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/buffer.ll @@ -0,0 +1,23 @@ +; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s + +target triple = "dxil-pc-shadermodel6.3-compute" + +@G = external constant <4 x float>, align 4 + +define void @test_bufferflags() { + + ; ByteAddressBuffer Buf : register(t8, space1) + %srv0 = call target("dx.RawBuffer", i8, 0, 0) + @llvm.dx.handle.fromBinding.tdx.RawBuffer_i8_0_0t( + i32 1, i32 8, i32 1, i32 0, i1 false) + + ret void +} + +attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) } + +; CHECK: ; Shader Flags Value: 0x00000010 +; CHECK: ; Note: shader requires additional functionality: +; CHECK-NEXT: ; Note: extra DXIL module flags: +; CHECK-NEXT: ; D3D11_SB_GLOBAL_FLAG_ENABLE_RAW_AND_STRUCTURED_BUFFERS +; CHECK-NEXT: {{^;$}} diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/rwbuffer.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/rwbuffer.ll new file mode 100644 index 0000000000000..5cbe79305329f --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/rwbuffer.ll @@ -0,0 +1,23 @@ +; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s + +target triple = "dxil-pc-shadermodel6.3-compute" + +@G = external constant <4 x float>, align 4 + +define void @test_bufferflags() { + + ; RWByteAddressBuffer Buf : register(u8, space1) + %uav0 = call target("dx.RawBuffer", i8, 1, 0) + @llvm.dx.handle.fromBinding.tdx.RawBuffer_i8_0_0t( + i32 1, i32 8, i32 1, i32 0, i1 false) + + ret void +} + +attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) } + +; CHECK: ; Shader Flags Value: 0x00000010 +; CHECK: ; Note: shader requires additional functionality: +; CHECK-NEXT: ; Note: extra DXIL module flags: +; CHECK-NEXT: ; D3D11_SB_GLOBAL_FLAG_ENABLE_RAW_AND_STRUCTURED_BUFFERS +; CHECK-NEXT: {{^;$}} diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/rwstructuredbuffer.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/rwstructuredbuffer.ll new file mode 100644 index 0000000000000..e442c01c62886 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/rwstructuredbuffer.ll @@ -0,0 +1,24 @@ +; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s + +target triple = "dxil-pc-shadermodel6.7-library" + +@G = external constant <4 x float>, align 4 + +define void @test_bufferflags() { + + ; struct S { float4 a; uint4 b; }; + ; RWStructuredBuffer Buf : register(u2, space4) + %struct0 = call target("dx.RawBuffer", {<4 x float>, <4 x i32>}, 1, 0) + @llvm.dx.handle.fromBinding.tdx.RawBuffer_sl_v4f32v4i32s_0_0t( + i32 4, i32 2, i32 1, i32 10, i1 true) + + ret void +} + +attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) } + +; CHECK: ; Shader Flags Value: 0x00000010 +; CHECK: ; Note: shader requires additional functionality: +; CHECK-NEXT: ; Note: extra DXIL module flags: +; CHECK-NEXT: ; D3D11_SB_GLOBAL_FLAG_ENABLE_RAW_AND_STRUCTURED_BUFFERS +; CHECK-NEXT: {{^;$}} diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/structuredbuffer.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/structuredbuffer.ll new file mode 100644 index 0000000000000..e45eaaec652a6 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/structuredbuffer.ll @@ -0,0 +1,24 @@ +; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s + +target triple = "dxil-pc-shadermodel6.7-library" + +@G = external constant <4 x float>, align 4 + +define void @test_bufferflags() { + + ; struct S { float4 a; uint4 b; }; + ; StructuredBuffer Buf : register(t2, space4) + %struct0 = call target("dx.RawBuffer", {<4 x float>, <4 x i32>}, 0, 0) + @llvm.dx.handle.fromBinding.tdx.RawBuffer_sl_v4f32v4i32s_0_0t( + i32 4, i32 2, i32 1, i32 10, i1 true) + + ret void +} + +attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) } + +; CHECK: ; Shader Flags Value: 0x00000010 +; CHECK: ; Note: shader requires additional functionality: +; CHECK-NEXT: ; Note: extra DXIL module flags: +; CHECK-NEXT: ; D3D11_SB_GLOBAL_FLAG_ENABLE_RAW_AND_STRUCTURED_BUFFERS +; CHECK-NEXT: {{^;$}}