Skip to content

Commit 5742dc4

Browse files
authored
[DirectX][ShaderFlags] Add analysis for WaveOps flag (#118140)
- Check each call instruction for a `WaveOp` intrinsic and set the `WaveOps` flag if this is true for any intrinsic, Done in DXILShaderFlags.cpp Resolves #114565
1 parent 8730fd7 commit 5742dc4

File tree

2 files changed

+123
-0
lines changed

2 files changed

+123
-0
lines changed

llvm/lib/Target/DirectX/DXILShaderFlags.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,43 @@
3232
using namespace llvm;
3333
using namespace llvm::dxil;
3434

35+
static bool checkWaveOps(Intrinsic::ID IID) {
36+
// Currently unsupported intrinsics
37+
// case Intrinsic::dx_wave_getlanecount:
38+
// case Intrinsic::dx_wave_allequal:
39+
// case Intrinsic::dx_wave_ballot:
40+
// case Intrinsic::dx_wave_readfirst:
41+
// case Intrinsic::dx_wave_reduce.and:
42+
// case Intrinsic::dx_wave_reduce.or:
43+
// case Intrinsic::dx_wave_reduce.xor:
44+
// case Intrinsic::dx_wave_prefixop:
45+
// case Intrinsic::dx_quad.readat:
46+
// case Intrinsic::dx_quad.readacrossx:
47+
// case Intrinsic::dx_quad.readacrossy:
48+
// case Intrinsic::dx_quad.readacrossdiagonal:
49+
// case Intrinsic::dx_wave_prefixballot:
50+
// case Intrinsic::dx_wave_match:
51+
// case Intrinsic::dx_wavemulti.*:
52+
// case Intrinsic::dx_wavemulti.ballot:
53+
// case Intrinsic::dx_quad.vote:
54+
switch (IID) {
55+
default:
56+
return false;
57+
case Intrinsic::dx_wave_is_first_lane:
58+
case Intrinsic::dx_wave_getlaneindex:
59+
case Intrinsic::dx_wave_any:
60+
case Intrinsic::dx_wave_all:
61+
case Intrinsic::dx_wave_readlane:
62+
case Intrinsic::dx_wave_active_countbits:
63+
// Wave Active Op Variants
64+
case Intrinsic::dx_wave_reduce_sum:
65+
case Intrinsic::dx_wave_reduce_usum:
66+
case Intrinsic::dx_wave_reduce_max:
67+
case Intrinsic::dx_wave_reduce_umax:
68+
return true;
69+
}
70+
}
71+
3572
/// Update the shader flags mask based on the given instruction.
3673
/// \param CSF Shader flags mask to update.
3774
/// \param I Instruction to check.
@@ -94,6 +131,8 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF,
94131

95132
// TODO: Set DX11_1_DoubleExtensions if I is a call to DXIL intrinsic
96133
// DXIL::Opcode::Fma https://github.com/llvm/llvm-project/issues/114554
134+
135+
CSF.WaveOps |= checkWaveOps(CI->getIntrinsicID());
97136
}
98137
}
99138

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
2+
;
3+
; Test that we have the correct shader flags to indicate that there are wave
4+
; ops set at the module level
5+
;
6+
; CHECK: ; Shader Flags Value: [[WAVE_FLAG:0x00080000]]
7+
; CHECK: ; Note: shader requires additional functionality:
8+
; CHECK-NEXT: ; Wave level operations
9+
; CHECK-NEXT: ; Note: extra DXIL module flags:
10+
11+
target triple = "dxil-pc-shadermodel6.7-library"
12+
13+
; Test the indiviual ops that they have the same Shader Wave flag at the
14+
; function level to ensure that each op is setting it accordingly
15+
16+
define noundef i1 @wave_is_first_lane() {
17+
entry:
18+
; CHECK: Function wave_is_first_lane : [[WAVE_FLAG]]
19+
%ret = call i1 @llvm.dx.wave.is.first.lane()
20+
ret i1 %ret
21+
}
22+
23+
define noundef i32 @wave_getlaneindex() {
24+
entry:
25+
; CHECK: Function wave_getlaneindex : [[WAVE_FLAG]]
26+
%ret = call i32 @llvm.dx.wave.getlaneindex()
27+
ret i32 %ret
28+
}
29+
30+
define noundef i1 @wave_any(i1 %x) {
31+
entry:
32+
; CHECK: Function wave_any : [[WAVE_FLAG]]
33+
%ret = call i1 @llvm.dx.wave.any(i1 %x)
34+
ret i1 %ret
35+
}
36+
37+
define noundef i1 @wave_all(i1 %x) {
38+
entry:
39+
; CHECK: Function wave_all : [[WAVE_FLAG]]
40+
%ret = call i1 @llvm.dx.wave.all(i1 %x)
41+
ret i1 %ret
42+
}
43+
44+
define noundef i1 @wave_readlane(i1 %x, i32 %idx) {
45+
entry:
46+
; CHECK: Function wave_readlane : [[WAVE_FLAG]]
47+
%ret = call i1 @llvm.dx.wave.readlane.i1(i1 %x, i32 %idx)
48+
ret i1 %ret
49+
}
50+
51+
define noundef i32 @wave_reduce_sum(i32 noundef %x) {
52+
entry:
53+
; CHECK: Function wave_reduce_sum : [[WAVE_FLAG]]
54+
%ret = call i32 @llvm.dx.wave.reduce.sum.i32(i32 %x)
55+
ret i32 %ret
56+
}
57+
58+
define noundef i32 @wave_reduce_usum(i32 noundef %x) {
59+
entry:
60+
; CHECK: Function wave_reduce_usum : [[WAVE_FLAG]]
61+
%ret = call i32 @llvm.dx.wave.reduce.usum.i32(i32 %x)
62+
ret i32 %ret
63+
}
64+
65+
define noundef i32 @wave_reduce_max(i32 noundef %x) {
66+
entry:
67+
; CHECK: Function wave_reduce_max : [[WAVE_FLAG]]
68+
%ret = call i32 @llvm.dx.wave.reduce.max.i32(i32 %x)
69+
ret i32 %ret
70+
}
71+
72+
define noundef i32 @wave_reduce_umax(i32 noundef %x) {
73+
entry:
74+
; CHECK: Function wave_reduce_umax : [[WAVE_FLAG]]
75+
%ret = call i32 @llvm.dx.wave.reduce.umax.i32(i32 %x)
76+
ret i32 %ret
77+
}
78+
79+
define void @wave_active_countbits(i1 %expr) {
80+
entry:
81+
; CHECK: Function wave_active_countbits : [[WAVE_FLAG]]
82+
%0 = call i32 @llvm.dx.wave.active.countbits(i1 %expr)
83+
ret void
84+
}

0 commit comments

Comments
 (0)