From b741f2b07a6b1513da7707114421bcba3e3e7acd Mon Sep 17 00:00:00 2001 From: Finn Plummer Date: Fri, 7 Feb 2025 19:11:17 +0000 Subject: [PATCH 1/5] [DirectX][ShaderFlags] Add analysis for `WaveOps` flag - add Shader Flag analysis for the `WaveOps` flag in DXILShaderFlags.cpp - add testing of all currenlty supported wave ops in wave-ops.ll --- llvm/lib/Target/DirectX/DXILShaderFlags.cpp | 35 ++++++++ .../CodeGen/DirectX/ShaderFlags/wave-ops.ll | 79 +++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 llvm/test/CodeGen/DirectX/ShaderFlags/wave-ops.ll diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp index 6a15bac153d85..65c323c134fe7 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp @@ -30,6 +30,39 @@ using namespace llvm; using namespace llvm::dxil; +static bool checkWaveOps(Intrinsic::ID IID) { + switch (IID) { + default: return false; + case Intrinsic::dx_wave_is_first_lane: + case Intrinsic::dx_wave_getlaneindex: + case Intrinsic::dx_wave_any: + case Intrinsic::dx_wave_all: + case Intrinsic::dx_wave_readlane: + case Intrinsic::dx_wave_active_countbits: + // Wave Active Op Variants + case Intrinsic::dx_wave_reduce_sum: + case Intrinsic::dx_wave_reduce_usum: + case Intrinsic::dx_wave_reduce_max: + case Intrinsic::dx_wave_reduce_umax: + + // Currently unsupported intrinsics + // case Intrinsic::dx_WaveGetLaneCount: + // case Intrinsic::dx_WaveActiveAllEqual: + // case Intrinsic::dx_WaveActiveBallot: + // case Intrinsic::dx_WaveReadLaneFirst: + // case Intrinsic::dx_WaveActiveBit: + // case Intrinsic::dx_WavePrefixOp: + // case Intrinsic::dx_QuadReadLaneAt: + // case Intrinsic::dx_QuadOp: + // case Intrinsic::dx_WavePrefixBitCount: + // case Intrinsic::dx_WaveMatch: + // case Intrinsic::dx_WaveMultiPrefixOp: + // case Intrinsic::dx_WaveMultiPrefixBitCount: + // case Intrinsic::dx_QuadVote: + return true; + } +} + /// Update the shader flags mask based on the given instruction. /// \param CSF Shader flags mask to update. /// \param I Instruction to check. @@ -92,6 +125,8 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF, // TODO: Set DX11_1_DoubleExtensions if I is a call to DXIL intrinsic // DXIL::Opcode::Fma https://github.com/llvm/llvm-project/issues/114554 + + CSF.WaveOps |= checkWaveOps(CI->getIntrinsicID()); } } diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/wave-ops.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/wave-ops.ll new file mode 100644 index 0000000000000..0f71a648eb735 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/wave-ops.ll @@ -0,0 +1,79 @@ +; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s +; +; CHECK: ; Shader Flags Value: [[WAVE_FLAG:0x00080000]] +; CHECK: ; Note: shader requires additional functionality: +; CHECK-NEXT: ; Wave level operations +; CHECK-NEXT: ; Note: extra DXIL module flags: +; CHECK-NEXT: {{^;$}} + +target triple = "dxil-pc-shadermodel6.7-library" + +define noundef i1 @wave_is_first_lane() { +entry: + ; CHECK: Function wave_is_first_lane : [[WAVE_FLAG]] + %ret = call i1 @llvm.dx.wave.is.first.lane() + ret i1 %ret +} + +define noundef i32 @wave_getlaneindex() { +entry: + ; CHECK: Function wave_getlaneindex : [[WAVE_FLAG]] + %ret = call i32 @llvm.dx.wave.getlaneindex() + ret i32 %ret +} + +define noundef i1 @wave_any(i1 %x) { +entry: + ; CHECK: Function wave_any : [[WAVE_FLAG]] + %ret = call i1 @llvm.dx.wave.any(i1 %x) + ret i1 %ret +} + +define noundef i1 @wave_all(i1 %x) { +entry: + ; CHECK: Function wave_all : [[WAVE_FLAG]] + %ret = call i1 @llvm.dx.wave.all(i1 %x) + ret i1 %ret +} + +define noundef i1 @wave_readlane(i1 %x, i32 %idx) { +entry: + ; CHECK: Function wave_readlane : [[WAVE_FLAG]] + %ret = call i1 @llvm.dx.wave.readlane.i1(i1 %x, i32 %idx) + ret i1 %ret +} + +define noundef i32 @wave_reduce_sum(i32 noundef %x) { +entry: + ; CHECK: Function wave_reduce_sum : [[WAVE_FLAG]] + %ret = call i32 @llvm.dx.wave.reduce.sum.i32(i32 %x) + ret i32 %ret +} + +define noundef i32 @wave_reduce_usum(i32 noundef %x) { +entry: + ; CHECK: Function wave_reduce_usum : [[WAVE_FLAG]] + %ret = call i32 @llvm.dx.wave.reduce.usum.i32(i32 %x) + ret i32 %ret +} + +define noundef i32 @wave_reduce_max(i32 noundef %x) { +entry: + ; CHECK: Function wave_reduce_max : [[WAVE_FLAG]] + %ret = call i32 @llvm.dx.wave.reduce.max.i32(i32 %x) + ret i32 %ret +} + +define noundef i32 @wave_reduce_umax(i32 noundef %x) { +entry: + ; CHECK: Function wave_reduce_umax : [[WAVE_FLAG]] + %ret = call i32 @llvm.dx.wave.reduce.umax.i32(i32 %x) + ret i32 %ret +} + +define void @wave_active_countbits(i1 %expr) { +entry: + ; CHECK: Function wave_active_countbits : [[WAVE_FLAG]] + %0 = call i32 @llvm.dx.wave.active.countbits(i1 %expr) + ret void +} From 580aa86aabf23406bbc08d0fad429d93c17e6cd4 Mon Sep 17 00:00:00 2001 From: Finn Plummer Date: Fri, 7 Feb 2025 20:01:08 +0000 Subject: [PATCH 2/5] clang formatting --- llvm/lib/Target/DirectX/DXILShaderFlags.cpp | 31 +++++++++++---------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp index 65c323c134fe7..ea9ad31f67fc0 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp @@ -32,7 +32,8 @@ using namespace llvm::dxil; static bool checkWaveOps(Intrinsic::ID IID) { switch (IID) { - default: return false; + default: + return false; case Intrinsic::dx_wave_is_first_lane: case Intrinsic::dx_wave_getlaneindex: case Intrinsic::dx_wave_any: @@ -45,20 +46,20 @@ static bool checkWaveOps(Intrinsic::ID IID) { case Intrinsic::dx_wave_reduce_max: case Intrinsic::dx_wave_reduce_umax: - // Currently unsupported intrinsics - // case Intrinsic::dx_WaveGetLaneCount: - // case Intrinsic::dx_WaveActiveAllEqual: - // case Intrinsic::dx_WaveActiveBallot: - // case Intrinsic::dx_WaveReadLaneFirst: - // case Intrinsic::dx_WaveActiveBit: - // case Intrinsic::dx_WavePrefixOp: - // case Intrinsic::dx_QuadReadLaneAt: - // case Intrinsic::dx_QuadOp: - // case Intrinsic::dx_WavePrefixBitCount: - // case Intrinsic::dx_WaveMatch: - // case Intrinsic::dx_WaveMultiPrefixOp: - // case Intrinsic::dx_WaveMultiPrefixBitCount: - // case Intrinsic::dx_QuadVote: + // Currently unsupported intrinsics + // case Intrinsic::dx_WaveGetLaneCount: + // case Intrinsic::dx_WaveActiveAllEqual: + // case Intrinsic::dx_WaveActiveBallot: + // case Intrinsic::dx_WaveReadLaneFirst: + // case Intrinsic::dx_WaveActiveBit: + // case Intrinsic::dx_WavePrefixOp: + // case Intrinsic::dx_QuadReadLaneAt: + // case Intrinsic::dx_QuadOp: + // case Intrinsic::dx_WavePrefixBitCount: + // case Intrinsic::dx_WaveMatch: + // case Intrinsic::dx_WaveMultiPrefixOp: + // case Intrinsic::dx_WaveMultiPrefixBitCount: + // case Intrinsic::dx_QuadVote: return true; } } From 8ff1d0fc233bd84231c0921b9d18f27a8e2143d7 Mon Sep 17 00:00:00 2001 From: Finn Plummer Date: Fri, 7 Feb 2025 21:10:32 +0000 Subject: [PATCH 3/5] review: add test description --- llvm/test/CodeGen/DirectX/ShaderFlags/wave-ops.ll | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/wave-ops.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/wave-ops.ll index 0f71a648eb735..0ab9b8abe80b0 100644 --- a/llvm/test/CodeGen/DirectX/ShaderFlags/wave-ops.ll +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/wave-ops.ll @@ -1,5 +1,8 @@ ; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s ; +; Test that we have the correct shader flags to indicate that there are wave +; ops set at the module level +; ; CHECK: ; Shader Flags Value: [[WAVE_FLAG:0x00080000]] ; CHECK: ; Note: shader requires additional functionality: ; CHECK-NEXT: ; Wave level operations @@ -8,6 +11,9 @@ target triple = "dxil-pc-shadermodel6.7-library" +; Test the indiviual ops that they have the same Shader Wave flag at the +; function level to ensure that each op is setting it accordingly + define noundef i1 @wave_is_first_lane() { entry: ; CHECK: Function wave_is_first_lane : [[WAVE_FLAG]] From 43c60afca360b50e8a3abb97fec497d8cacd5cdb Mon Sep 17 00:00:00 2001 From: Finn Plummer Date: Fri, 7 Feb 2025 21:14:45 +0000 Subject: [PATCH 4/5] review: remove unneeded check --- llvm/test/CodeGen/DirectX/ShaderFlags/wave-ops.ll | 1 - 1 file changed, 1 deletion(-) diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/wave-ops.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/wave-ops.ll index 0ab9b8abe80b0..7a876f67615cd 100644 --- a/llvm/test/CodeGen/DirectX/ShaderFlags/wave-ops.ll +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/wave-ops.ll @@ -7,7 +7,6 @@ ; CHECK: ; Note: shader requires additional functionality: ; CHECK-NEXT: ; Wave level operations ; CHECK-NEXT: ; Note: extra DXIL module flags: -; CHECK-NEXT: {{^;$}} target triple = "dxil-pc-shadermodel6.7-library" From 95d2cbf98d8bef7946a6c5207634a940a70da29e Mon Sep 17 00:00:00 2001 From: Finn Plummer Date: Fri, 14 Feb 2025 18:37:53 +0000 Subject: [PATCH 5/5] [NFC] review: provide naming convention spellings and fix format --- llvm/lib/Target/DirectX/DXILShaderFlags.cpp | 33 +++++++++++---------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp index ea9ad31f67fc0..0fb2dfd696ace 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp @@ -31,6 +31,24 @@ using namespace llvm; using namespace llvm::dxil; static bool checkWaveOps(Intrinsic::ID IID) { + // Currently unsupported intrinsics + // case Intrinsic::dx_wave_getlanecount: + // case Intrinsic::dx_wave_allequal: + // case Intrinsic::dx_wave_ballot: + // case Intrinsic::dx_wave_readfirst: + // case Intrinsic::dx_wave_reduce.and: + // case Intrinsic::dx_wave_reduce.or: + // case Intrinsic::dx_wave_reduce.xor: + // case Intrinsic::dx_wave_prefixop: + // case Intrinsic::dx_quad.readat: + // case Intrinsic::dx_quad.readacrossx: + // case Intrinsic::dx_quad.readacrossy: + // case Intrinsic::dx_quad.readacrossdiagonal: + // case Intrinsic::dx_wave_prefixballot: + // case Intrinsic::dx_wave_match: + // case Intrinsic::dx_wavemulti.*: + // case Intrinsic::dx_wavemulti.ballot: + // case Intrinsic::dx_quad.vote: switch (IID) { default: return false; @@ -45,21 +63,6 @@ static bool checkWaveOps(Intrinsic::ID IID) { case Intrinsic::dx_wave_reduce_usum: case Intrinsic::dx_wave_reduce_max: case Intrinsic::dx_wave_reduce_umax: - - // Currently unsupported intrinsics - // case Intrinsic::dx_WaveGetLaneCount: - // case Intrinsic::dx_WaveActiveAllEqual: - // case Intrinsic::dx_WaveActiveBallot: - // case Intrinsic::dx_WaveReadLaneFirst: - // case Intrinsic::dx_WaveActiveBit: - // case Intrinsic::dx_WavePrefixOp: - // case Intrinsic::dx_QuadReadLaneAt: - // case Intrinsic::dx_QuadOp: - // case Intrinsic::dx_WavePrefixBitCount: - // case Intrinsic::dx_WaveMatch: - // case Intrinsic::dx_WaveMultiPrefixOp: - // case Intrinsic::dx_WaveMultiPrefixBitCount: - // case Intrinsic::dx_QuadVote: return true; } }