316 lines · plain
1; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV2; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}3 4; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s --check-prefix=CHECK-SPIRV5; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}6 7; CHECK-SPIRV-DAG: %[[#int:]] = OpTypeInt 32 08; CHECK-SPIRV-DAG: %[[#intv2:]] = OpTypeVector %[[#int]] 29; CHECK-SPIRV-DAG: %[[#intv3:]] = OpTypeVector %[[#int]] 310; CHECK-SPIRV-DAG: %[[#float:]] = OpTypeFloat 3211; CHECK-SPIRV-DAG: %[[#ScopeCrossWorkgroup:]] = OpConstantNull %[[#int]]12; CHECK-SPIRV-DAG: %[[#ScopeWorkgroup:]] = OpConstant %[[#int]] 2{{$}}13; CHECK-SPIRV-DAG: %[[#ScopeSubgroup:]] = OpConstant %[[#int]] 3{{$}}14 15; CHECK-SPIRV: OpFunction16; CHECK-SPIRV: %[[#]] = OpGroupFMax %[[#float]] %[[#ScopeWorkgroup]] Reduce17; CHECK-SPIRV: OpFunctionEnd18 19;; kernel void testWorkGroupFMax(float a, global float *res) {20;; res[0] = work_group_reduce_max(a);21;; }22 23define dso_local spir_kernel void @testWorkGroupFMax(float noundef %a, float addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {24entry:25 %call = call spir_func float @_Z21work_group_reduce_maxf(float noundef %a)26 store float %call, float addrspace(1)* %res, align 427 ret void28}29 30declare spir_func float @_Z21work_group_reduce_maxf(float noundef) local_unnamed_addr31 32; CHECK-SPIRV: OpFunction33; CHECK-SPIRV: %[[#]] = OpGroupFMin %[[#float]] %[[#ScopeWorkgroup]] Reduce34; CHECK-SPIRV: OpFunctionEnd35 36;; kernel void testWorkGroupFMin(float a, global float *res) {37;; res[0] = work_group_reduce_min(a);38;; }39 40define dso_local spir_kernel void @testWorkGroupFMin(float noundef %a, float addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {41entry:42 %call = call spir_func float @_Z21work_group_reduce_minf(float noundef %a)43 store float %call, float addrspace(1)* %res, align 444 ret void45}46 47declare spir_func float @_Z21work_group_reduce_minf(float noundef) local_unnamed_addr48 49; CHECK-SPIRV: OpFunction50; CHECK-SPIRV: %[[#]] = OpGroupFAdd %[[#float]] %[[#ScopeWorkgroup]] Reduce51; CHECK-SPIRV: OpFunctionEnd52 53;; kernel void testWorkGroupFAdd(float a, global float *res) {54;; res[0] = work_group_reduce_add(a);55;; }56 57define dso_local spir_kernel void @testWorkGroupFAdd(float noundef %a, float addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {58entry:59 %call = call spir_func float @_Z21work_group_reduce_addf(float noundef %a)60 store float %call, float addrspace(1)* %res, align 461 ret void62}63 64declare spir_func float @_Z21work_group_reduce_addf(float noundef) local_unnamed_addr65 66; CHECK-SPIRV: OpFunction67; CHECK-SPIRV: %[[#]] = OpGroupFMax %[[#float]] %[[#ScopeWorkgroup]] InclusiveScan68; CHECK-SPIRV: OpFunctionEnd69 70;; kernel void testWorkGroupScanInclusiveFMax(float a, global float *res) {71;; res[0] = work_group_scan_inclusive_max(a);72;; }73 74define dso_local spir_kernel void @testWorkGroupScanInclusiveFMax(float noundef %a, float addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {75entry:76 %call = call spir_func float @_Z29work_group_scan_inclusive_maxf(float noundef %a)77 store float %call, float addrspace(1)* %res, align 478 ret void79}80 81declare spir_func float @_Z29work_group_scan_inclusive_maxf(float noundef) local_unnamed_addr82 83; CHECK-SPIRV: OpFunction84; CHECK-SPIRV: %[[#]] = OpGroupFMax %[[#float]] %[[#ScopeWorkgroup]] ExclusiveScan85; CHECK-SPIRV: OpFunctionEnd86 87;; kernel void testWorkGroupScanExclusiveFMax(float a, global float *res) {88;; res[0] = work_group_scan_exclusive_max(a);89;; }90 91define dso_local spir_kernel void @testWorkGroupScanExclusiveFMax(float noundef %a, float addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {92entry:93 %call = call spir_func float @_Z29work_group_scan_exclusive_maxf(float noundef %a)94 store float %call, float addrspace(1)* %res, align 495 ret void96}97 98declare spir_func float @_Z29work_group_scan_exclusive_maxf(float noundef) local_unnamed_addr99 100; CHECK-SPIRV: OpFunction101; CHECK-SPIRV: %[[#]] = OpGroupSMax %[[#int]] %[[#ScopeWorkgroup]] Reduce102; CHECK-SPIRV: OpFunctionEnd103 104;; kernel void testWorkGroupSMax(int a, global int *res) {105;; res[0] = work_group_reduce_max(a);106;; }107 108define dso_local spir_kernel void @testWorkGroupSMax(i32 noundef %a, i32 addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {109entry:110 %call = call spir_func i32 @_Z21work_group_reduce_maxi(i32 noundef %a)111 store i32 %call, i32 addrspace(1)* %res, align 4112 ret void113}114 115declare spir_func i32 @_Z21work_group_reduce_maxi(i32 noundef) local_unnamed_addr116 117; CHECK-SPIRV: OpFunction118; CHECK-SPIRV: %[[#]] = OpGroupSMin %[[#int]] %[[#ScopeWorkgroup]] Reduce119; CHECK-SPIRV: OpFunctionEnd120 121;; kernel void testWorkGroupSMin(int a, global int *res) {122;; res[0] = work_group_reduce_min(a);123;; }124 125define dso_local spir_kernel void @testWorkGroupSMin(i32 noundef %a, i32 addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {126entry:127 %call = call spir_func i32 @_Z21work_group_reduce_mini(i32 noundef %a)128 store i32 %call, i32 addrspace(1)* %res, align 4129 ret void130}131 132declare spir_func i32 @_Z21work_group_reduce_mini(i32 noundef) local_unnamed_addr133 134; CHECK-SPIRV: OpFunction135; CHECK-SPIRV: %[[#]] = OpGroupIAdd %[[#int]] %[[#ScopeWorkgroup]] Reduce136; CHECK-SPIRV: OpFunctionEnd137 138;; kernel void testWorkGroupIAddSigned(int a, global int *res) {139;; res[0] = work_group_reduce_add(a);140;; }141 142define dso_local spir_kernel void @testWorkGroupIAddSigned(i32 noundef %a, i32 addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {143entry:144 %call = call spir_func i32 @_Z21work_group_reduce_addi(i32 noundef %a)145 store i32 %call, i32 addrspace(1)* %res, align 4146 ret void147}148 149declare spir_func i32 @_Z21work_group_reduce_addi(i32 noundef) local_unnamed_addr150 151; CHECK-SPIRV: OpFunction152; CHECK-SPIRV: %[[#]] = OpGroupIAdd %[[#int]] %[[#ScopeWorkgroup]] Reduce153; CHECK-SPIRV: OpFunctionEnd154 155;; kernel void testWorkGroupIAddUnsigned(uint a, global uint *res) {156;; res[0] = work_group_reduce_add(a);157;; }158 159define dso_local spir_kernel void @testWorkGroupIAddUnsigned(i32 noundef %a, i32 addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {160entry:161 %call = call spir_func i32 @_Z21work_group_reduce_addj(i32 noundef %a)162 store i32 %call, i32 addrspace(1)* %res, align 4163 ret void164}165 166declare spir_func i32 @_Z21work_group_reduce_addj(i32 noundef) local_unnamed_addr167 168; CHECK-SPIRV: OpFunction169; CHECK-SPIRV: %[[#]] = OpGroupUMax %[[#int]] %[[#ScopeWorkgroup]] Reduce170; CHECK-SPIRV: OpFunctionEnd171 172;; kernel void testWorkGroupUMax(uint a, global uint *res) {173;; res[0] = work_group_reduce_max(a);174;; }175 176define dso_local spir_kernel void @testWorkGroupUMax(i32 noundef %a, i32 addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {177entry:178 %call = call spir_func i32 @_Z21work_group_reduce_maxj(i32 noundef %a)179 store i32 %call, i32 addrspace(1)* %res, align 4180 ret void181}182 183declare spir_func i32 @_Z21work_group_reduce_maxj(i32 noundef) local_unnamed_addr184 185; CHECK-SPIRV: OpFunction186; CHECK-SPIRV: %[[#]] = OpGroupUMax %[[#int]] %[[#ScopeSubgroup]] Reduce187; CHECK-SPIRV: OpFunctionEnd188 189;; #pragma OPENCL EXTENSION cl_khr_subgroups: enable190;; kernel void testSubGroupUMax(uint a, global uint *res) {191;; res[0] = sub_group_reduce_max(a);192;; }193;; #pragma OPENCL EXTENSION cl_khr_subgroups: disable194 195define dso_local spir_kernel void @testSubGroupUMax(i32 noundef %a, i32 addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {196entry:197 %call = call spir_func i32 @_Z20sub_group_reduce_maxj(i32 noundef %a)198 store i32 %call, i32 addrspace(1)* %res, align 4199 ret void200}201 202declare spir_func i32 @_Z20sub_group_reduce_maxj(i32 noundef) local_unnamed_addr203 204; CHECK-SPIRV: OpFunction205; CHECK-SPIRV: %[[#]] = OpGroupUMax %[[#int]] %[[#ScopeWorkgroup]] InclusiveScan206; CHECK-SPIRV: OpFunctionEnd207 208;; kernel void testWorkGroupScanInclusiveUMax(uint a, global uint *res) {209;; res[0] = work_group_scan_inclusive_max(a);210;; }211 212define dso_local spir_kernel void @testWorkGroupScanInclusiveUMax(i32 noundef %a, i32 addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {213entry:214 %call = call spir_func i32 @_Z29work_group_scan_inclusive_maxj(i32 noundef %a)215 store i32 %call, i32 addrspace(1)* %res, align 4216 ret void217}218 219declare spir_func i32 @_Z29work_group_scan_inclusive_maxj(i32 noundef) local_unnamed_addr220 221; CHECK-SPIRV: OpFunction222; CHECK-SPIRV: %[[#]] = OpGroupUMax %[[#int]] %[[#ScopeWorkgroup]] ExclusiveScan223; CHECK-SPIRV: OpFunctionEnd224 225;; kernel void testWorkGroupScanExclusiveUMax(uint a, global uint *res) {226;; res[0] = work_group_scan_exclusive_max(a);227;; }228 229define dso_local spir_kernel void @testWorkGroupScanExclusiveUMax(i32 noundef %a, i32 addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {230entry:231 %call = call spir_func i32 @_Z29work_group_scan_exclusive_maxj(i32 noundef %a)232 store i32 %call, i32 addrspace(1)* %res, align 4233 ret void234}235 236declare spir_func i32 @_Z29work_group_scan_exclusive_maxj(i32 noundef) local_unnamed_addr237 238; CHECK-SPIRV: OpFunction239; CHECK-SPIRV: %[[#]] = OpGroupUMin %[[#int]] %[[#ScopeWorkgroup]] Reduce240; CHECK-SPIRV: OpFunctionEnd241 242;; kernel void testWorkGroupUMin(uint a, global uint *res) {243;; res[0] = work_group_reduce_min(a);244;; }245 246define dso_local spir_kernel void @testWorkGroupUMin(i32 noundef %a, i32 addrspace(1)* nocapture noundef writeonly %res) local_unnamed_addr {247entry:248 %call = call spir_func i32 @_Z21work_group_reduce_minj(i32 noundef %a)249 store i32 %call, i32 addrspace(1)* %res, align 4250 ret void251}252 253declare spir_func i32 @_Z21work_group_reduce_minj(i32 noundef) local_unnamed_addr254 255; CHECK-SPIRV: OpFunction256; CHECK-SPIRV: %[[#]] = OpGroupBroadcast %[[#int]] %[[#ScopeWorkgroup]] %[[#BroadcastValue:]] %[[#BroadcastLocalId:]]257; CHECK-SPIRV: %[[#BroadcastVec2:]] = OpCompositeConstruct %[[#intv2]] %[[#BroadcastLocalId]] %[[#BroadcastLocalId]]258; CHECK-SPIRV: %[[#]] = OpGroupBroadcast %[[#int]] %[[#ScopeWorkgroup]] %[[#BroadcastValue]] %[[#BroadcastVec2]]259; CHECK-SPIRV: %[[#BroadcastVec3:]] = OpCompositeConstruct %[[#intv3]] %[[#BroadcastLocalId]] %[[#BroadcastLocalId]] %[[#BroadcastLocalId]]260; CHECK-SPIRV: %[[#]] = OpGroupBroadcast %[[#int]] %[[#ScopeWorkgroup]] %[[#BroadcastValue]] %[[#BroadcastVec3]]261; CHECK-SPIRV: %[[#]] = OpGroupBroadcast %[[#int]] %[[#ScopeCrossWorkgroup]] %[[#BroadcastValue]] %[[#BroadcastLocalId]]262; CHECK-SPIRV: OpFunctionEnd263 264;; kernel void testWorkGroupBroadcast(uint a, global size_t *id, global int *res) {265;; res[0] = work_group_broadcast(a, *id);266;; }267 268define 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 {269entry:270 %0 = load i32, i32 addrspace(1)* %id, align 4271 %call = call spir_func i32 @_Z20work_group_broadcastjj(i32 noundef %a, i32 noundef %0)272 %call_v2 = call spir_func i32 @_Z20work_group_broadcastjj(i32 noundef %a, i32 noundef %0, i32 noundef %0)273 %call_v3 = call spir_func i32 @_Z20work_group_broadcastjj(i32 noundef %a, i32 noundef %0, i32 noundef %0, i32 noundef %0)274 store i32 %call, i32 addrspace(1)* %res, align 4275 %call1 = call spir_func i32 @__spirv_GroupBroadcast(i32 0, i32 noundef %a, i32 noundef %0)276 ret void277}278 279declare spir_func i32 @_Z20work_group_broadcastjj(i32 noundef, i32 noundef) local_unnamed_addr280declare spir_func i32 @_Z20work_group_broadcastjjj(i32 noundef, i32 noundef, i32 noundef) local_unnamed_addr281declare spir_func i32 @_Z20work_group_broadcastjjjj(i32 noundef, i32 noundef, i32 noundef, i32 noundef) local_unnamed_addr282declare spir_func i32 @__spirv_GroupBroadcast(i32 noundef, i32 noundef, i32 noundef) local_unnamed_addr283 284; CHECK-SPIRV: OpFunction285; CHECK-SPIRV: %[[#]] = OpGroupFAdd %[[#float]] %[[#ScopeCrossWorkgroup]] Reduce %[[#FValue:]]286; CHECK-SPIRV: %[[#]] = OpGroupFMin %[[#float]] %[[#ScopeWorkgroup]] InclusiveScan %[[#FValue]]287; CHECK-SPIRV: %[[#]] = OpGroupFMax %[[#float]] %[[#ScopeSubgroup]] ExclusiveScan %[[#FValue]]288; CHECK-SPIRV: %[[#]] = OpGroupIAdd %[[#int]] %[[#ScopeCrossWorkgroup]] Reduce %[[#IValue:]]289; CHECK-SPIRV: %[[#]] = OpGroupUMin %[[#int]] %[[#ScopeWorkgroup]] InclusiveScan %[[#IValue]]290; CHECK-SPIRV: %[[#]] = OpGroupSMin %[[#int]] %[[#ScopeSubgroup]] ExclusiveScan %[[#IValue]]291; CHECK-SPIRV: %[[#]] = OpGroupUMax %[[#int]] %[[#ScopeCrossWorkgroup]] Reduce %[[#IValue]]292; CHECK-SPIRV: %[[#]] = OpGroupSMax %[[#int]] %[[#ScopeWorkgroup]] InclusiveScan %[[#IValue]]293; CHECK-SPIRV: OpFunctionEnd294 295define spir_kernel void @foo(float %a, i32 %b) {296entry:297 %f1 = call spir_func float @__spirv_GroupFAdd(i32 0, i32 0, float %a)298 %f2 = call spir_func float @__spirv_GroupFMin(i32 2, i32 1, float %a)299 %f3 = call spir_func float @__spirv_GroupFMax(i32 3, i32 2, float %a)300 %i1 = call spir_func i32 @__spirv_GroupIAdd(i32 0, i32 0, i32 %b)301 %i2 = call spir_func i32 @__spirv_GroupUMin(i32 2, i32 1, i32 %b)302 %i3 = call spir_func i32 @__spirv_GroupSMin(i32 3, i32 2, i32 %b)303 %i4 = call spir_func i32 @__spirv_GroupUMax(i32 0, i32 0, i32 %b)304 %i5 = call spir_func i32 @__spirv_GroupSMax(i32 2, i32 1, i32 %b)305 ret void306}307 308declare spir_func float @__spirv_GroupFAdd(i32, i32, float)309declare spir_func float @__spirv_GroupFMin(i32, i32, float)310declare spir_func float @__spirv_GroupFMax(i32, i32, float)311declare spir_func i32 @__spirv_GroupIAdd(i32, i32, i32)312declare spir_func i32 @__spirv_GroupUMin(i32, i32, i32)313declare spir_func i32 @__spirv_GroupSMin(i32, i32, i32)314declare spir_func i32 @__spirv_GroupUMax(i32, i32, i32)315declare spir_func i32 @__spirv_GroupSMax(i32, i32, i32)316