1 ; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
2 ; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
4 ; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV
5 ; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
7 ; CHECK-SPIRV-DAG: %[[#int:]] = OpTypeInt 32 0
8 ; CHECK-SPIRV-DAG: %[[#float:]] = OpTypeFloat 32
9 ; CHECK-SPIRV-DAG: %[[#ScopeCrossWorkgroup:]] = OpConstant %[[#int]] 0
10 ; CHECK-SPIRV-DAG: %[[#ScopeWorkgroup:]] = OpConstant %[[#int]] 2
11 ; CHECK-SPIRV-DAG: %[[#ScopeSubgroup:]] = OpConstant %[[#int]] 3
13 ; CHECK-SPIRV: OpFunction
14 ; CHECK-SPIRV: %[[#]] = OpGroupFMax %[[#float]] %[[#ScopeWorkgroup]] Reduce
15 ; CHECK-SPIRV: OpFunctionEnd
17 ;; kernel void testWorkGroupFMax(float a, global float *res) {
18 ;; res[0] = work_group_reduce_max(a);
21 define dso_local spir_kernel void @testWorkGroupFMax(float noundef %a, float addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {
23 %call = call spir_func float @_Z21work_group_reduce_maxf(float noundef %a)
24 store float %call, float addrspace(1)* %res, align 4
28 declare spir_func float @_Z21work_group_reduce_maxf(float noundef) local_unnamed_addr
30 ; CHECK-SPIRV: OpFunction
31 ; CHECK-SPIRV: %[[#]] = OpGroupFMin %[[#float]] %[[#ScopeWorkgroup]] Reduce
32 ; CHECK-SPIRV: OpFunctionEnd
34 ;; kernel void testWorkGroupFMin(float a, global float *res) {
35 ;; res[0] = work_group_reduce_min(a);
38 define dso_local spir_kernel void @testWorkGroupFMin(float noundef %a, float addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {
40 %call = call spir_func float @_Z21work_group_reduce_minf(float noundef %a)
41 store float %call, float addrspace(1)* %res, align 4
45 declare spir_func float @_Z21work_group_reduce_minf(float noundef) local_unnamed_addr
47 ; CHECK-SPIRV: OpFunction
48 ; CHECK-SPIRV: %[[#]] = OpGroupFAdd %[[#float]] %[[#ScopeWorkgroup]] Reduce
49 ; CHECK-SPIRV: OpFunctionEnd
51 ;; kernel void testWorkGroupFAdd(float a, global float *res) {
52 ;; res[0] = work_group_reduce_add(a);
55 define dso_local spir_kernel void @testWorkGroupFAdd(float noundef %a, float addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {
57 %call = call spir_func float @_Z21work_group_reduce_addf(float noundef %a)
58 store float %call, float addrspace(1)* %res, align 4
62 declare spir_func float @_Z21work_group_reduce_addf(float noundef) local_unnamed_addr
64 ; CHECK-SPIRV: OpFunction
65 ; CHECK-SPIRV: %[[#]] = OpGroupFMax %[[#float]] %[[#ScopeWorkgroup]] InclusiveScan
66 ; CHECK-SPIRV: OpFunctionEnd
68 ;; kernel void testWorkGroupScanInclusiveFMax(float a, global float *res) {
69 ;; res[0] = work_group_scan_inclusive_max(a);
72 define dso_local spir_kernel void @testWorkGroupScanInclusiveFMax(float noundef %a, float addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {
74 %call = call spir_func float @_Z29work_group_scan_inclusive_maxf(float noundef %a)
75 store float %call, float addrspace(1)* %res, align 4
79 declare spir_func float @_Z29work_group_scan_inclusive_maxf(float noundef) local_unnamed_addr
81 ; CHECK-SPIRV: OpFunction
82 ; CHECK-SPIRV: %[[#]] = OpGroupFMax %[[#float]] %[[#ScopeWorkgroup]] ExclusiveScan
83 ; CHECK-SPIRV: OpFunctionEnd
85 ;; kernel void testWorkGroupScanExclusiveFMax(float a, global float *res) {
86 ;; res[0] = work_group_scan_exclusive_max(a);
89 define dso_local spir_kernel void @testWorkGroupScanExclusiveFMax(float noundef %a, float addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {
91 %call = call spir_func float @_Z29work_group_scan_exclusive_maxf(float noundef %a)
92 store float %call, float addrspace(1)* %res, align 4
96 declare spir_func float @_Z29work_group_scan_exclusive_maxf(float noundef) local_unnamed_addr
98 ; CHECK-SPIRV: OpFunction
99 ; CHECK-SPIRV: %[[#]] = OpGroupSMax %[[#int]] %[[#ScopeWorkgroup]] Reduce
100 ; CHECK-SPIRV: OpFunctionEnd
102 ;; kernel void testWorkGroupSMax(int a, global int *res) {
103 ;; res[0] = work_group_reduce_max(a);
106 define dso_local spir_kernel void @testWorkGroupSMax(i32 noundef %a, i32 addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {
108 %call = call spir_func i32 @_Z21work_group_reduce_maxi(i32 noundef %a)
109 store i32 %call, i32 addrspace(1)* %res, align 4
113 declare spir_func i32 @_Z21work_group_reduce_maxi(i32 noundef) local_unnamed_addr
115 ; CHECK-SPIRV: OpFunction
116 ; CHECK-SPIRV: %[[#]] = OpGroupSMin %[[#int]] %[[#ScopeWorkgroup]] Reduce
117 ; CHECK-SPIRV: OpFunctionEnd
119 ;; kernel void testWorkGroupSMin(int a, global int *res) {
120 ;; res[0] = work_group_reduce_min(a);
123 define dso_local spir_kernel void @testWorkGroupSMin(i32 noundef %a, i32 addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {
125 %call = call spir_func i32 @_Z21work_group_reduce_mini(i32 noundef %a)
126 store i32 %call, i32 addrspace(1)* %res, align 4
130 declare spir_func i32 @_Z21work_group_reduce_mini(i32 noundef) local_unnamed_addr
132 ; CHECK-SPIRV: OpFunction
133 ; CHECK-SPIRV: %[[#]] = OpGroupIAdd %[[#int]] %[[#ScopeWorkgroup]] Reduce
134 ; CHECK-SPIRV: OpFunctionEnd
136 ;; kernel void testWorkGroupIAddSigned(int a, global int *res) {
137 ;; res[0] = work_group_reduce_add(a);
140 define dso_local spir_kernel void @testWorkGroupIAddSigned(i32 noundef %a, i32 addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {
142 %call = call spir_func i32 @_Z21work_group_reduce_addi(i32 noundef %a)
143 store i32 %call, i32 addrspace(1)* %res, align 4
147 declare spir_func i32 @_Z21work_group_reduce_addi(i32 noundef) local_unnamed_addr
149 ; CHECK-SPIRV: OpFunction
150 ; CHECK-SPIRV: %[[#]] = OpGroupIAdd %[[#int]] %[[#ScopeWorkgroup]] Reduce
151 ; CHECK-SPIRV: OpFunctionEnd
153 ;; kernel void testWorkGroupIAddUnsigned(uint a, global uint *res) {
154 ;; res[0] = work_group_reduce_add(a);
157 define dso_local spir_kernel void @testWorkGroupIAddUnsigned(i32 noundef %a, i32 addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {
159 %call = call spir_func i32 @_Z21work_group_reduce_addj(i32 noundef %a)
160 store i32 %call, i32 addrspace(1)* %res, align 4
164 declare spir_func i32 @_Z21work_group_reduce_addj(i32 noundef) local_unnamed_addr
166 ; CHECK-SPIRV: OpFunction
167 ; CHECK-SPIRV: %[[#]] = OpGroupUMax %[[#int]] %[[#ScopeWorkgroup]] Reduce
168 ; CHECK-SPIRV: OpFunctionEnd
170 ;; kernel void testWorkGroupUMax(uint a, global uint *res) {
171 ;; res[0] = work_group_reduce_max(a);
174 define dso_local spir_kernel void @testWorkGroupUMax(i32 noundef %a, i32 addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {
176 %call = call spir_func i32 @_Z21work_group_reduce_maxj(i32 noundef %a)
177 store i32 %call, i32 addrspace(1)* %res, align 4
181 declare spir_func i32 @_Z21work_group_reduce_maxj(i32 noundef) local_unnamed_addr
183 ; CHECK-SPIRV: OpFunction
184 ; CHECK-SPIRV: %[[#]] = OpGroupUMax %[[#int]] %[[#ScopeSubgroup]] Reduce
185 ; CHECK-SPIRV: OpFunctionEnd
187 ;; #pragma OPENCL EXTENSION cl_khr_subgroups: enable
188 ;; kernel void testSubGroupUMax(uint a, global uint *res) {
189 ;; res[0] = sub_group_reduce_max(a);
191 ;; #pragma OPENCL EXTENSION cl_khr_subgroups: disable
193 define dso_local spir_kernel void @testSubGroupUMax(i32 noundef %a, i32 addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {
195 %call = call spir_func i32 @_Z20sub_group_reduce_maxj(i32 noundef %a)
196 store i32 %call, i32 addrspace(1)* %res, align 4
200 declare spir_func i32 @_Z20sub_group_reduce_maxj(i32 noundef) local_unnamed_addr
202 ; CHECK-SPIRV: OpFunction
203 ; CHECK-SPIRV: %[[#]] = OpGroupUMax %[[#int]] %[[#ScopeWorkgroup]] InclusiveScan
204 ; CHECK-SPIRV: OpFunctionEnd
206 ;; kernel void testWorkGroupScanInclusiveUMax(uint a, global uint *res) {
207 ;; res[0] = work_group_scan_inclusive_max(a);
210 define dso_local spir_kernel void @testWorkGroupScanInclusiveUMax(i32 noundef %a, i32 addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {
212 %call = call spir_func i32 @_Z29work_group_scan_inclusive_maxj(i32 noundef %a)
213 store i32 %call, i32 addrspace(1)* %res, align 4
217 declare spir_func i32 @_Z29work_group_scan_inclusive_maxj(i32 noundef) local_unnamed_addr
219 ; CHECK-SPIRV: OpFunction
220 ; CHECK-SPIRV: %[[#]] = OpGroupUMax %[[#int]] %[[#ScopeWorkgroup]] ExclusiveScan
221 ; CHECK-SPIRV: OpFunctionEnd
223 ;; kernel void testWorkGroupScanExclusiveUMax(uint a, global uint *res) {
224 ;; res[0] = work_group_scan_exclusive_max(a);
227 define dso_local spir_kernel void @testWorkGroupScanExclusiveUMax(i32 noundef %a, i32 addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {
229 %call = call spir_func i32 @_Z29work_group_scan_exclusive_maxj(i32 noundef %a)
230 store i32 %call, i32 addrspace(1)* %res, align 4
234 declare spir_func i32 @_Z29work_group_scan_exclusive_maxj(i32 noundef) local_unnamed_addr
236 ; CHECK-SPIRV: OpFunction
237 ; CHECK-SPIRV: %[[#]] = OpGroupUMin %[[#int]] %[[#ScopeWorkgroup]] Reduce
238 ; CHECK-SPIRV: OpFunctionEnd
240 ;; kernel void testWorkGroupUMin(uint a, global uint *res) {
241 ;; res[0] = work_group_reduce_min(a);
244 define dso_local spir_kernel void @testWorkGroupUMin(i32 noundef %a, i32 addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {
246 %call = call spir_func i32 @_Z21work_group_reduce_minj(i32 noundef %a)
247 store i32 %call, i32 addrspace(1)* %res, align 4
251 declare spir_func i32 @_Z21work_group_reduce_minj(i32 noundef) local_unnamed_addr
253 ; CHECK-SPIRV: OpFunction
254 ; CHECK-SPIRV: %[[#]] = OpGroupBroadcast %[[#int]] %[[#ScopeWorkgroup]] %[[#BroadcastValue:]] %[[#BroadcastLocalId:]]
255 ; CHECK-SPIRV: %[[#]] = OpGroupBroadcast %[[#int]] %[[#ScopeCrossWorkgroup]] %[[#BroadcastValue]] %[[#BroadcastLocalId]]
256 ; CHECK-SPIRV: OpFunctionEnd
258 ;; kernel void testWorkGroupBroadcast(uint a, global size_t *id, global int *res) {
259 ;; res[0] = work_group_broadcast(a, *id);
262 define dso_local spir_kernel void @testWorkGroupBroadcast(i32 noundef %a, i32 addrspace(1)* nocapture noundef readonly %id, i32 addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {
264 %0 = load i32, i32 addrspace(1)* %id, align 4
265 %call = call spir_func i32 @_Z20work_group_broadcastjj(i32 noundef %a, i32 noundef %0)
266 store i32 %call, i32 addrspace(1)* %res, align 4
267 %call1 = call spir_func i32 @__spirv_GroupBroadcast(i32 0, i32 noundef %a, i32 noundef %0)
271 declare spir_func i32 @_Z20work_group_broadcastjj(i32 noundef, i32 noundef) local_unnamed_addr
272 declare spir_func i32 @__spirv_GroupBroadcast(i32 noundef, i32 noundef, i32 noundef) local_unnamed_addr
274 ; CHECK-SPIRV: OpFunction
275 ; CHECK-SPIRV: %[[#]] = OpGroupFAdd %[[#float]] %[[#ScopeCrossWorkgroup]] Reduce %[[#FValue:]]
276 ; CHECK-SPIRV: %[[#]] = OpGroupFMin %[[#float]] %[[#ScopeWorkgroup]] InclusiveScan %[[#FValue]]
277 ; CHECK-SPIRV: %[[#]] = OpGroupFMax %[[#float]] %[[#ScopeSubgroup]] ExclusiveScan %[[#FValue]]
278 ; CHECK-SPIRV: %[[#]] = OpGroupIAdd %[[#int]] %[[#ScopeCrossWorkgroup]] Reduce %[[#IValue:]]
279 ; CHECK-SPIRV: %[[#]] = OpGroupUMin %[[#int]] %[[#ScopeWorkgroup]] InclusiveScan %[[#IValue]]
280 ; CHECK-SPIRV: %[[#]] = OpGroupSMin %[[#int]] %[[#ScopeSubgroup]] ExclusiveScan %[[#IValue]]
281 ; CHECK-SPIRV: %[[#]] = OpGroupUMax %[[#int]] %[[#ScopeCrossWorkgroup]] Reduce %[[#IValue]]
282 ; CHECK-SPIRV: %[[#]] = OpGroupSMax %[[#int]] %[[#ScopeWorkgroup]] InclusiveScan %[[#IValue]]
283 ; CHECK-SPIRV: OpFunctionEnd
285 define spir_kernel void @foo(float %a, i32 %b) {
287 %f1 = call spir_func float @__spirv_GroupFAdd(i32 0, i32 0, float %a)
288 %f2 = call spir_func float @__spirv_GroupFMin(i32 2, i32 1, float %a)
289 %f3 = call spir_func float @__spirv_GroupFMax(i32 3, i32 2, float %a)
290 %i1 = call spir_func i32 @__spirv_GroupIAdd(i32 0, i32 0, i32 %b)
291 %i2 = call spir_func i32 @__spirv_GroupUMin(i32 2, i32 1, i32 %b)
292 %i3 = call spir_func i32 @__spirv_GroupSMin(i32 3, i32 2, i32 %b)
293 %i4 = call spir_func i32 @__spirv_GroupUMax(i32 0, i32 0, i32 %b)
294 %i5 = call spir_func i32 @__spirv_GroupSMax(i32 2, i32 1, i32 %b)
298 declare spir_func float @__spirv_GroupFAdd(i32, i32, float)
299 declare spir_func float @__spirv_GroupFMin(i32, i32, float)
300 declare spir_func float @__spirv_GroupFMax(i32, i32, float)
301 declare spir_func i32 @__spirv_GroupIAdd(i32, i32, i32)
302 declare spir_func i32 @__spirv_GroupUMin(i32, i32, i32)
303 declare spir_func i32 @__spirv_GroupSMin(i32, i32, i32)
304 declare spir_func i32 @__spirv_GroupUMax(i32, i32, i32)
305 declare spir_func i32 @__spirv_GroupSMax(i32, i32, i32)