Skip to content

Commit 37cf047

Browse files
[SPIR-V] Introduce support of '__spirv_' wrapper builtins for the SPV_INTEL_subgroups extension (#94235)
This PR Introduces support of '__spirv_' wrapper builtins for the SPV_INTEL_subgroups extension.
1 parent 6d4fb3d commit 37cf047

File tree

3 files changed

+108
-1
lines changed

3 files changed

+108
-1
lines changed

llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1020,9 +1020,17 @@ static bool generateIntelSubgroupsInst(const SPIRV::IncomingCall *Call,
10201020
}
10211021
const SPIRV::IntelSubgroupsBuiltin *IntelSubgroups =
10221022
SPIRV::lookupIntelSubgroupsBuiltin(Builtin->Name);
1023-
MachineRegisterInfo *MRI = MIRBuilder.getMRI();
10241023

10251024
uint32_t OpCode = IntelSubgroups->Opcode;
1025+
if (Call->isSpirvOp()) {
1026+
bool IsSet = OpCode != SPIRV::OpSubgroupBlockWriteINTEL &&
1027+
OpCode != SPIRV::OpSubgroupImageBlockWriteINTEL;
1028+
return buildOpFromWrapper(MIRBuilder, OpCode, Call,
1029+
IsSet ? GR->getSPIRVTypeID(Call->ReturnType)
1030+
: Register(0));
1031+
}
1032+
1033+
MachineRegisterInfo *MRI = MIRBuilder.getMRI();
10261034
if (IntelSubgroups->IsBlock) {
10271035
// Minimal number or arguments set in TableGen records is 1
10281036
if (SPIRVType *Arg0Type = GR->getSPIRVTypeForVReg(Call->Arguments[0])) {

llvm/lib/Target/SPIRV/SPIRVBuiltins.td

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,21 @@ foreach i = ["", "2", "4", "8", "16"] in {
10551055
}
10561056
// OpSubgroupImageBlockReadINTEL and OpSubgroupImageBlockWriteINTEL are to be resolved later on (in code)
10571057

1058+
// Multiclass used to define builtin wrappers for the SPV_INTEL_subgroups extension.
1059+
multiclass DemangledIntelSubgroupsBuiltinWrapper<string name, bits<8> numArgs, Op operation> {
1060+
def : DemangledBuiltin<!strconcat("__spirv_", name), OpenCL_std, IntelSubgroups, numArgs, numArgs>;
1061+
def : IntelSubgroupsBuiltin<!strconcat("__spirv_", name), operation>;
1062+
}
1063+
1064+
defm : DemangledIntelSubgroupsBuiltinWrapper<"SubgroupShuffleINTEL", 2, OpSubgroupShuffleINTEL>;
1065+
defm : DemangledIntelSubgroupsBuiltinWrapper<"SubgroupShuffleDownINTEL", 3, OpSubgroupShuffleDownINTEL>;
1066+
defm : DemangledIntelSubgroupsBuiltinWrapper<"SubgroupShuffleUpINTEL", 3, OpSubgroupShuffleUpINTEL>;
1067+
defm : DemangledIntelSubgroupsBuiltinWrapper<"SubgroupShuffleXorINTEL", 2, OpSubgroupShuffleXorINTEL>;
1068+
defm : DemangledIntelSubgroupsBuiltinWrapper<"SubgroupBlockReadINTEL", 1, OpSubgroupBlockReadINTEL>;
1069+
defm : DemangledIntelSubgroupsBuiltinWrapper<"SubgroupBlockWriteINTEL", 2, OpSubgroupBlockWriteINTEL>;
1070+
defm : DemangledIntelSubgroupsBuiltinWrapper<"SubgroupImageBlockReadINTEL", 2, OpSubgroupImageBlockReadINTEL>;
1071+
defm : DemangledIntelSubgroupsBuiltinWrapper<"SubgroupImageBlockWriteINTEL", 3, OpSubgroupImageBlockWriteINTEL>;
1072+
10581073
//===----------------------------------------------------------------------===//
10591074
// Class defining a builtin for group operations within uniform control flow.
10601075
// It should be translated into a SPIR-V instruction using
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown --spirv-ext=+SPV_INTEL_subgroups %s -o - | FileCheck %s
2+
3+
; CHECK-DAG: Capability SubgroupShuffleINTEL
4+
; CHECK-DAG: Capability SubgroupBufferBlockIOINTEL
5+
; CHECK-DAG: Capability SubgroupImageBlockIOINTEL
6+
; CHECK: Extension "SPV_INTEL_subgroups"
7+
8+
; CHECK-DAG: %[[#Float:]] = OpTypeFloat 32
9+
; CHECK-DAG: %[[#FloatVec:]] = OpTypeVector %[[#Float]] 2
10+
; CHECK-DAG: %[[#Int:]] = OpTypeInt 32 0
11+
; CHECK-DAG: %[[#IntVec:]] = OpTypeVector %[[#Int]] 2
12+
13+
; CHECK: Function
14+
; CHECK: %[[#X:]] = OpFunctionParameter
15+
; CHECK: %[[#C:]] = OpFunctionParameter
16+
; CHECK: %[[#ImgIn:]] = OpFunctionParameter
17+
; CHECK: %[[#ImgOut:]] = OpFunctionParameter
18+
; CHECK: %[[#Coord:]] = OpFunctionParameter
19+
; CHECK: %[[#Ptr:]] = OpFunctionParameter
20+
21+
; CHECK: %[[#]] = OpSubgroupShuffleINTEL %[[#FloatVec]] %[[#X]] %[[#C]]
22+
; CHECK: %[[#]] = OpSubgroupShuffleDownINTEL %[[#FloatVec]] %[[#X]] %[[#X]] %[[#C]]
23+
; CHECK: %[[#]] = OpSubgroupShuffleUpINTEL %[[#FloatVec]] %[[#X]] %[[#X]] %[[#C]]
24+
; CHECK: %[[#]] = OpSubgroupShuffleXorINTEL %[[#FloatVec]] %[[#X]] %[[#C]]
25+
; CHECK: %[[#ResImg1:]] = OpSubgroupImageBlockReadINTEL %[[#IntVec]] %[[#ImgIn]] %[[#Coord]]
26+
; CHECK: OpSubgroupImageBlockWriteINTEL %[[#ImgOut]] %[[#Coord]] %[[#ResImg1]]
27+
; CHECK: %[[#Res1:]] = OpSubgroupBlockReadINTEL %[[#IntVec]] %[[#Ptr]]
28+
; CHECK: OpSubgroupBlockWriteINTEL %[[#Ptr]] %[[#Res1]]
29+
; CHECK: %[[#]] = OpSubgroupShuffleINTEL %[[#FloatVec]] %[[#X]] %[[#C]]
30+
; CHECK: %[[#]] = OpSubgroupShuffleDownINTEL %[[#FloatVec]] %[[#X]] %[[#X]] %[[#C]]
31+
; CHECK: %[[#]] = OpSubgroupShuffleUpINTEL %[[#FloatVec]] %[[#X]] %[[#X]] %[[#C]]
32+
; CHECK: %[[#]] = OpSubgroupShuffleXorINTEL %[[#FloatVec]] %[[#X]] %[[#C]]
33+
; CHECK: %[[#ResImg2:]] = OpSubgroupImageBlockReadINTEL %[[#IntVec]] %[[#ImgIn]] %[[#Coord]]
34+
; CHECK: OpSubgroupImageBlockWriteINTEL %[[#ImgOut]] %[[#Coord]] %[[#ResImg2]]
35+
; CHECK: %[[#Res2:]] = OpSubgroupBlockReadINTEL %[[#IntVec]] %[[#Ptr]]
36+
; CHECK: OpSubgroupBlockWriteINTEL %[[#Ptr]] %[[#Res2]]
37+
; CHECK: Return
38+
39+
define spir_kernel void @test(<2 x float> %x, i32 %c, ptr addrspace(1) %image_in, ptr addrspace(1) %image_out, <2 x i32> %coord, ptr addrspace(1) %p) {
40+
entry:
41+
%wrap = tail call spir_func <2 x float> @__spirv_SubgroupShuffleINTEL(<2 x float> %x, i32 %c)
42+
%wrap1 = tail call spir_func <2 x float> @__spirv_SubgroupShuffleDownINTEL(<2 x float> %x, <2 x float> %x, i32 %c)
43+
%wrap2 = tail call spir_func <2 x float> @__spirv_SubgroupShuffleUpINTEL(<2 x float> %x, <2 x float> %x, i32 %c)
44+
%wrap3 = tail call spir_func <2 x float> @__spirv_SubgroupShuffleXorINTEL(<2 x float> %x, i32 %c)
45+
46+
%wrap4 = tail call spir_func <2 x i32> @__spirv_SubgroupImageBlockReadINTEL(ptr addrspace(1) %image_in, <2 x i32> %coord)
47+
tail call spir_func void @__spirv_SubgroupImageBlockWriteINTEL(ptr addrspace(1) %image_out, <2 x i32> %coord, <2 x i32> %wrap4)
48+
%wrap5 = tail call spir_func <2 x i32> @__spirv_SubgroupBlockReadINTEL(ptr addrspace(1) %p)
49+
tail call spir_func void @__spirv_SubgroupBlockWriteINTEL(ptr addrspace(1) %p, <2 x i32> %wrap5)
50+
51+
%ocl = tail call spir_func <2 x float> @intel_sub_group_shuffle(<2 x float> %x, i32 %c)
52+
%ocl1 = tail call spir_func <2 x float> @intel_sub_group_shuffle_down(<2 x float> %x, <2 x float> %x, i32 %c)
53+
%ocl2 = tail call spir_func <2 x float> @intel_sub_group_shuffle_up(<2 x float> %x, <2 x float> %x, i32 %c)
54+
%ocl3 = tail call spir_func <2 x float> @intel_sub_group_shuffle_xor(<2 x float> %x, i32 %c)
55+
56+
%ocl4 = tail call spir_func <2 x i32> @_Z27intel_sub_group_block_read214ocl_image2d_roDv2_i(ptr addrspace(1) %image_in, <2 x i32> %coord)
57+
tail call spir_func void @_Z28intel_sub_group_block_write214ocl_image2d_woDv2_iDv2_j(ptr addrspace(1) %image_out, <2 x i32> %coord, <2 x i32> %ocl4)
58+
%ocl5 = tail call spir_func <2 x i32> @intel_sub_group_block_read(ptr addrspace(1) %p)
59+
tail call spir_func void @intel_sub_group_block_write(ptr addrspace(1) %p, <2 x i32> %ocl5)
60+
61+
ret void
62+
}
63+
64+
declare spir_func <2 x float> @__spirv_SubgroupShuffleINTEL(<2 x float>, i32)
65+
declare spir_func <2 x float> @__spirv_SubgroupShuffleDownINTEL(<2 x float>, <2 x float>, i32)
66+
declare spir_func <2 x float> @__spirv_SubgroupShuffleUpINTEL(<2 x float>, <2 x float>, i32)
67+
declare spir_func <2 x float> @__spirv_SubgroupShuffleXorINTEL(<2 x float>, i32)
68+
69+
declare spir_func <2 x i32> @__spirv_SubgroupBlockReadINTEL(ptr addrspace(1))
70+
declare spir_func void @__spirv_SubgroupBlockWriteINTEL(ptr addrspace(1), <2 x i32>)
71+
72+
declare spir_func <2 x i32> @__spirv_SubgroupImageBlockReadINTEL(ptr addrspace(1), <2 x i32>)
73+
declare spir_func void @__spirv_SubgroupImageBlockWriteINTEL(ptr addrspace(1), <2 x i32>, <2 x i32>)
74+
75+
declare spir_func <2 x float> @intel_sub_group_shuffle(<2 x float>, i32)
76+
declare spir_func <2 x float> @intel_sub_group_shuffle_down(<2 x float>, <2 x float>, i32)
77+
declare spir_func <2 x float> @intel_sub_group_shuffle_up(<2 x float>, <2 x float>, i32)
78+
declare spir_func <2 x float> @intel_sub_group_shuffle_xor(<2 x float>, i32)
79+
80+
declare spir_func <2 x i32> @intel_sub_group_block_read(ptr addrspace(1))
81+
declare spir_func void @intel_sub_group_block_write(ptr addrspace(1), <2 x i32>)
82+
83+
declare spir_func <2 x i32> @_Z27intel_sub_group_block_read214ocl_image2d_roDv2_i(ptr addrspace(1), <2 x i32>)
84+
declare spir_func void @_Z28intel_sub_group_block_write214ocl_image2d_woDv2_iDv2_j(ptr addrspace(1), <2 x i32>, <2 x i32>)

0 commit comments

Comments
 (0)