[llvm] [DirectX][ShaderFlags] Add analysis for `WaveOps` flag (PR #118140)

Finn Plummer via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 14 10:39:04 PST 2025


https://github.com/inbelic updated https://github.com/llvm/llvm-project/pull/118140

>From b741f2b07a6b1513da7707114421bcba3e3e7acd Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
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 <canadienfinn at gmail.com>
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 <canadienfinn at gmail.com>
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 <canadienfinn at gmail.com>
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 <canadienfinn at gmail.com>
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;
   }
 }



More information about the llvm-commits mailing list