Skip to content

Commit a49de2a

Browse files
committed
Add SPV_KHR_subgroup_rotate support
Add support for mapping the SPV_KHR_subgroup_rotate extension operations to and from SPIR-V friendly IR, as well as to and from the cl_khr_subgroup_rotate OpenCL extension. Specifications: - https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extensions/KHR/SPV_KHR_subgroup_rotate.html - https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_Ext.html#cl_khr_subgroup_rotate
1 parent 2a8f524 commit a49de2a

File tree

9 files changed

+299
-2
lines changed

9 files changed

+299
-2
lines changed

include/LLVMSPIRVExtensions.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ EXT(SPV_KHR_expect_assume)
1111
EXT(SPV_KHR_integer_dot_product)
1212
EXT(SPV_KHR_bit_instructions)
1313
EXT(SPV_KHR_uniform_group_instructions)
14+
EXT(SPV_KHR_subgroup_rotate)
1415
EXT(SPV_INTEL_subgroups)
1516
EXT(SPV_INTEL_media_block_io)
1617
EXT(SPV_INTEL_device_side_avc_motion_estimation)

lib/SPIRV/OCLUtil.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,9 @@ template <> void SPIRVMap<std::string, Op, SPIRVInstruction>::init() {
424424
// cl_khr_subgroup_shuffle_relative
425425
_SPIRV_OP(group_shuffle_up, GroupNonUniformShuffleUp)
426426
_SPIRV_OP(group_shuffle_down, GroupNonUniformShuffleDown)
427+
// cl_khr_subgroup_rotate
428+
_SPIRV_OP(group_rotate, GroupNonUniformRotateKHR)
429+
_SPIRV_OP(group_clustered_rotate, GroupNonUniformRotateKHR)
427430
// cl_khr_extended_bit_ops
428431
_SPIRV_OP(bitfield_insert, BitFieldInsert)
429432
_SPIRV_OP(bitfield_extract_signed, BitFieldSExtract)
@@ -1287,6 +1290,8 @@ class OCLBuiltinFuncMangleInfo : public SPIRV::BuiltinFuncMangleInfo {
12871290
else if (NameRef.contains("bit_extract")) {
12881291
addUnsignedArgs(0, 1);
12891292
}
1293+
} else if (NameRef.startswith("sub_group_clustered_rotate")) {
1294+
addUnsignedArg(2);
12901295
} else if (NameRef.contains("shuffle") || NameRef.contains("clustered"))
12911296
addUnsignedArg(1);
12921297
} else if (NameRef.startswith("bitfield_insert")) {

lib/SPIRV/SPIRVToOCL.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,23 @@ std::string SPIRVToOCLBase::getBallotBuiltinName(CallInst *CI, Op OC) {
481481
return Prefix + kSPIRVName::GroupPrefix + "ballot_" + GroupOp;
482482
}
483483

484+
std::string SPIRVToOCLBase::getRotateBuiltinName(CallInst *CI, Op OC) {
485+
assert((OC == OpGroupNonUniformRotateKHR) &&
486+
"Not intended to handle other opcodes");
487+
std::string Prefix = getGroupBuiltinPrefix(CI);
488+
assert((Prefix == kOCLBuiltinName::SubPrefix) &&
489+
"Workgroup scope is not supported for OpGroupNonUniformRotateKHR");
490+
491+
std::string OptionalClustered;
492+
if (CI->arg_size() == 4)
493+
OptionalClustered = "clustered_";
494+
return Prefix + kSPIRVName::GroupPrefix + OptionalClustered + "rotate";
495+
}
496+
484497
std::string SPIRVToOCLBase::groupOCToOCLBuiltinName(CallInst *CI, Op OC) {
498+
if (OC == OpGroupNonUniformRotateKHR)
499+
return getRotateBuiltinName(CI, OC);
500+
485501
auto FuncName = OCLSPIRVBuiltinMap::rmap(OC);
486502
assert(FuncName.find(kSPIRVName::GroupPrefix) == 0);
487503

lib/SPIRV/SPIRVToOCL.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,9 @@ class SPIRVToOCLBase : public InstVisitor<SPIRVToOCLBase> {
253253
/// example: GroupNonUniformBallotBitCount(Reduce) =>
254254
/// group_ballot_bit_count_iadd => sub_group_ballot_bit_count
255255
std::string getBallotBuiltinName(CallInst *CI, Op OC);
256+
/// Transform OpGroupNonUniformRotateKHR to corresponding OpenCL function
257+
/// name.
258+
std::string getRotateBuiltinName(CallInst *CI, Op OC);
256259
/// Transform group opcode to corresponding OpenCL function name
257260
std::string groupOCToOCLBuiltinName(CallInst *CI, Op OC);
258261
/// Transform SPV-IR image opaque type into OpenCL representation,

lib/SPIRV/SPIRVUtil.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2170,6 +2170,10 @@ class SPIRVFriendlyIRMangleInfo : public BuiltinFuncMangleInfo {
21702170
case OpGroupNonUniformShuffleDown:
21712171
addUnsignedArg(2);
21722172
break;
2173+
case OpGroupNonUniformRotateKHR:
2174+
if (ArgTys.size() == 4)
2175+
addUnsignedArg(3);
2176+
break;
21732177
case OpGroupNonUniformInverseBallot:
21742178
case OpGroupNonUniformBallotFindLSB:
21752179
case OpGroupNonUniformBallotFindMSB:

lib/SPIRV/libSPIRV/SPIRVInstruction.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2533,6 +2533,24 @@ _SPIRV_OP(GroupNonUniformShuffleUp, true, 6)
25332533
_SPIRV_OP(GroupNonUniformShuffleDown, true, 6)
25342534
#undef _SPIRV_OP
25352535

2536+
class SPIRVGroupNonUniformRotateKHRInst : public SPIRVInstTemplateBase {
2537+
public:
2538+
SPIRVCapVec getRequiredCapability() const override {
2539+
return getVec(CapabilityGroupNonUniformRotateKHR);
2540+
}
2541+
2542+
llvm::Optional<ExtensionID> getRequiredExtension() const override {
2543+
return ExtensionID::SPV_KHR_subgroup_rotate;
2544+
}
2545+
};
2546+
2547+
#define _SPIRV_OP(x, ...) \
2548+
typedef SPIRVInstTemplate<SPIRVGroupNonUniformRotateKHRInst, Op##x, \
2549+
__VA_ARGS__> \
2550+
SPIRV##x;
2551+
_SPIRV_OP(GroupNonUniformRotateKHR, true, 6, true)
2552+
#undef _SPIRV_OP
2553+
25362554
class SPIRVBlockingPipesIntelInst : public SPIRVInstTemplateBase {
25372555
protected:
25382556
SPIRVCapVec getRequiredCapability() const override {

lib/SPIRV/libSPIRV/SPIRVOpCode.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,9 @@ inline bool isAccessChainOpCode(Op OpCode) {
141141
inline bool hasExecScope(Op OpCode) {
142142
unsigned OC = OpCode;
143143
return (OpGroupWaitEvents <= OC && OC <= OpGroupSMax) ||
144-
(OpGroupReserveReadPipePackets <= OC && OC <= OpGroupCommitWritePipe);
144+
(OpGroupReserveReadPipePackets <= OC &&
145+
OC <= OpGroupCommitWritePipe) ||
146+
(OC == OpGroupNonUniformRotateKHR);
145147
}
146148

147149
inline bool hasGroupOperation(Op OpCode) {
@@ -179,7 +181,8 @@ inline bool isGroupOpCode(Op OpCode) {
179181

180182
inline bool isGroupNonUniformOpcode(Op OpCode) {
181183
unsigned OC = OpCode;
182-
return OpGroupNonUniformElect <= OC && OC <= OpGroupNonUniformQuadSwap;
184+
return (OpGroupNonUniformElect <= OC && OC <= OpGroupNonUniformQuadSwap) ||
185+
(OC == OpGroupNonUniformRotateKHR);
183186
}
184187

185188
inline bool isMediaBlockINTELOpcode(Op OpCode) {

lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ _SPIRV_OP(GroupNonUniformBitwiseXor, 361)
328328
_SPIRV_OP(GroupNonUniformLogicalAnd, 362)
329329
_SPIRV_OP(GroupNonUniformLogicalOr, 363)
330330
_SPIRV_OP(GroupNonUniformLogicalXor, 364)
331+
_SPIRV_OP(GroupNonUniformRotateKHR, 4431)
331332
_SPIRV_OP(SDotKHR, 4450)
332333
_SPIRV_OP(UDotKHR, 4451)
333334
_SPIRV_OP(SUDotKHR, 4452)
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
// RUN: %clang_cc1 -triple spir-unknown-unknown -O1 -cl-std=CL2.0 -fdeclare-opencl-builtins -finclude-default-header -emit-llvm-bc %s -o %t.bc -no-opaque-pointers
2+
// RUN: llvm-spirv --spirv-ext=+SPV_KHR_subgroup_rotate %t.bc -o %t.spv
3+
// RUN: llvm-spirv --spirv-ext=+SPV_KHR_subgroup_rotate %t.spv -to-text -o %t.spt
4+
// RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
5+
6+
// RUN: llvm-spirv -r %t.spv -o %t.rev.bc
7+
// RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefixes=CHECK-COMMON,CHECK-LLVM
8+
// RUN: llvm-spirv -r %t.spv --spirv-target-env=SPV-IR -o %t.rev.bc
9+
// RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefixes=CHECK-COMMON,CHECK-SPV-IR
10+
11+
// From SPIR-V friendly IR:
12+
// RUN: llvm-spirv %t.rev.bc --spirv-ext=+SPV_KHR_subgroup_rotate -spirv-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
13+
14+
// CHECK-SPIRV-DAG: {{[0-9]*}} Capability GroupNonUniformRotateKHR
15+
// CHECK-SPIRV-DAG: Extension "SPV_KHR_subgroup_rotate"
16+
17+
// CHECK-SPIRV-DAG: TypeInt [[char:[0-9]+]] 8 0
18+
// CHECK-SPIRV-DAG: TypeInt [[short:[0-9]+]] 16 0
19+
// CHECK-SPIRV-DAG: TypeInt [[int:[0-9]+]] 32 0
20+
// CHECK-SPIRV-DAG: TypeInt [[long:[0-9]+]] 64 0
21+
// CHECK-SPIRV-DAG: TypeFloat [[half:[0-9]+]] 16
22+
// CHECK-SPIRV-DAG: TypeFloat [[float:[0-9]+]] 32
23+
// CHECK-SPIRV-DAG: TypeFloat [[double:[0-9]+]] 64
24+
25+
// CHECK-SPIRV-DAG: Constant [[int]] [[ScopeSubgroup:[0-9]+]] 3
26+
// CHECK-SPIRV-DAG: Constant [[char]] [[char_0:[0-9]+]] 0
27+
// CHECK-SPIRV-DAG: Constant [[short]] [[short_0:[0-9]+]] 0
28+
// CHECK-SPIRV-DAG: Constant [[int]] [[int_0:[0-9]+]] 0
29+
// CHECK-SPIRV-DAG: Constant [[int]] [[int_2:[0-9]+]] 2
30+
// CHECK-SPIRV-DAG: Constant [[int]] [[int_4:[0-9]+]] 4
31+
// CHECK-SPIRV-DAG: Constant [[long]] [[long_0:[0-9]+]] 0
32+
// CHECK-SPIRV-DAG: Constant [[half]] [[half_0:[0-9]+]] 0
33+
// CHECK-SPIRV-DAG: Constant [[float]] [[float_0:[0-9]+]] 0
34+
// CHECK-SPIRV-DAG: Constant [[double]] [[double_0:[0-9]+]] 0
35+
36+
#pragma OPENCL EXTENSION cl_khr_fp16 : enable
37+
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
38+
39+
// CHECK-SPIRV-LABEL: 5 Function
40+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[char]] {{[0-9]+}} [[ScopeSubgroup]] [[char_0]] [[int_2]]
41+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[char]] {{[0-9]+}} [[ScopeSubgroup]] [[char_0]] [[int_2]] [[int_4]]
42+
// CHECK-SPIRV: FunctionEnd
43+
44+
// CHECK-COMMON-LABEL: @testRotateChar
45+
46+
// CHECK-LLVM: call spir_func i8 @_Z16sub_group_rotateci(i8 0, i32 2)
47+
// CHECK-LLVM: call spir_func i8 @_Z26sub_group_clustered_rotatecij(i8 0, i32 2, i32 4)
48+
49+
// CHECK-SPV-IR: call spir_func i8 @_Z32__spirv_GroupNonUniformRotateKHRici(i32 3, i8 0, i32 2)
50+
// CHECK-SPV-IR: call spir_func i8 @_Z32__spirv_GroupNonUniformRotateKHRicij(i32 3, i8 0, i32 2, i32 4)
51+
kernel void testRotateChar(global char* dst)
52+
{
53+
char v = 0;
54+
dst[0] = sub_group_rotate(v, 2);
55+
dst[1] = sub_group_clustered_rotate(v, 2, 4);
56+
}
57+
58+
// CHECK-SPIRV-LABEL: 5 Function
59+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[char]] {{[0-9]+}} [[ScopeSubgroup]] [[char_0]] [[int_2]]
60+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[char]] {{[0-9]+}} [[ScopeSubgroup]] [[char_0]] [[int_2]] [[int_4]]
61+
// CHECK-SPIRV: FunctionEnd
62+
63+
// CHECK-COMMON-LABEL: @testRotateUChar
64+
65+
// CHECK-LLVM: call spir_func i8 @_Z16sub_group_rotateci(i8 0, i32 2)
66+
// CHECK-LLVM: call spir_func i8 @_Z26sub_group_clustered_rotatecij(i8 0, i32 2, i32 4)
67+
68+
// CHECK-SPV-IR: call spir_func i8 @_Z32__spirv_GroupNonUniformRotateKHRici(i32 3, i8 0, i32 2)
69+
// CHECK-SPV-IR: call spir_func i8 @_Z32__spirv_GroupNonUniformRotateKHRicij(i32 3, i8 0, i32 2, i32 4)
70+
kernel void testRotateUChar(global uchar* dst)
71+
{
72+
uchar v = 0;
73+
dst[0] = sub_group_rotate(v, 2);
74+
dst[1] = sub_group_clustered_rotate(v, 2, 4);
75+
}
76+
77+
// CHECK-SPIRV-LABEL: 5 Function
78+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[short]] {{[0-9]+}} [[ScopeSubgroup]] [[short_0]] [[int_2]]
79+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[short]] {{[0-9]+}} [[ScopeSubgroup]] [[short_0]] [[int_2]] [[int_4]]
80+
// CHECK-SPIRV: FunctionEnd
81+
82+
// CHECK-COMMON-LABEL: @testRotateShort
83+
84+
// CHECK-LLVM: call spir_func i16 @_Z16sub_group_rotatesi(i16 0, i32 2)
85+
// CHECK-LLVM: call spir_func i16 @_Z26sub_group_clustered_rotatesij(i16 0, i32 2, i32 4)
86+
87+
// CHECK-SPV-IR: call spir_func i16 @_Z32__spirv_GroupNonUniformRotateKHRisi(i32 3, i16 0, i32 2)
88+
// CHECK-SPV-IR: call spir_func i16 @_Z32__spirv_GroupNonUniformRotateKHRisij(i32 3, i16 0, i32 2, i32 4)
89+
kernel void testRotateShort(global short* dst)
90+
{
91+
short v = 0;
92+
dst[0] = sub_group_rotate(v, 2);
93+
dst[1] = sub_group_clustered_rotate(v, 2, 4);
94+
}
95+
96+
// CHECK-SPIRV-LABEL: 5 Function
97+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[short]] {{[0-9]+}} [[ScopeSubgroup]] [[short_0]] [[int_2]]
98+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[short]] {{[0-9]+}} [[ScopeSubgroup]] [[short_0]] [[int_2]] [[int_4]]
99+
// CHECK-SPIRV: FunctionEnd
100+
101+
// CHECK-COMMON-LABEL: @testRotateUShort
102+
103+
// CHECK-LLVM: call spir_func i16 @_Z16sub_group_rotatesi(i16 0, i32 2)
104+
// CHECK-LLVM: call spir_func i16 @_Z26sub_group_clustered_rotatesij(i16 0, i32 2, i32 4)
105+
106+
// CHECK-SPV-IR: call spir_func i16 @_Z32__spirv_GroupNonUniformRotateKHRisi(i32 3, i16 0, i32 2)
107+
// CHECK-SPV-IR: call spir_func i16 @_Z32__spirv_GroupNonUniformRotateKHRisij(i32 3, i16 0, i32 2, i32 4)
108+
kernel void testRotateUShort(global ushort* dst)
109+
{
110+
ushort v = 0;
111+
dst[0] = sub_group_rotate(v, 2);
112+
dst[1] = sub_group_clustered_rotate(v, 2, 4);
113+
}
114+
115+
// CHECK-SPIRV-LABEL: 5 Function
116+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[int]] {{[0-9]+}} [[ScopeSubgroup]] [[int_0]] [[int_2]]
117+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[int]] {{[0-9]+}} [[ScopeSubgroup]] [[int_0]] [[int_2]] [[int_4]]
118+
// CHECK-SPIRV: FunctionEnd
119+
120+
// CHECK-COMMON-LABEL: @testRotateInt
121+
122+
// CHECK-LLVM: call spir_func i32 @_Z16sub_group_rotateii(i32 0, i32 2)
123+
// CHECK-LLVM: call spir_func i32 @_Z26sub_group_clustered_rotateiij(i32 0, i32 2, i32 4)
124+
125+
// CHECK-SPV-IR: call spir_func i32 @_Z32__spirv_GroupNonUniformRotateKHRiii(i32 3, i32 0, i32 2)
126+
// CHECK-SPV-IR: call spir_func i32 @_Z32__spirv_GroupNonUniformRotateKHRiiij(i32 3, i32 0, i32 2, i32 4)
127+
kernel void testRotateInt(global int* dst)
128+
{
129+
int v = 0;
130+
dst[0] = sub_group_rotate(v, 2);
131+
dst[1] = sub_group_clustered_rotate(v, 2, 4);
132+
}
133+
134+
// CHECK-SPIRV-LABEL: 5 Function
135+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[int]] {{[0-9]+}} [[ScopeSubgroup]] [[int_0]] [[int_2]]
136+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[int]] {{[0-9]+}} [[ScopeSubgroup]] [[int_0]] [[int_2]] [[int_4]]
137+
// CHECK-SPIRV: FunctionEnd
138+
139+
// CHECK-COMMON-LABEL: @testRotateUInt
140+
141+
// CHECK-LLVM: call spir_func i32 @_Z16sub_group_rotateii(i32 0, i32 2)
142+
// CHECK-LLVM: call spir_func i32 @_Z26sub_group_clustered_rotateiij(i32 0, i32 2, i32 4)
143+
144+
// CHECK-SPV-IR: call spir_func i32 @_Z32__spirv_GroupNonUniformRotateKHRiii(i32 3, i32 0, i32 2)
145+
// CHECK-SPV-IR: call spir_func i32 @_Z32__spirv_GroupNonUniformRotateKHRiiij(i32 3, i32 0, i32 2, i32 4)
146+
kernel void testRotateUInt(global uint* dst)
147+
{
148+
uint v = 0;
149+
dst[0] = sub_group_rotate(v, 2);
150+
dst[1] = sub_group_clustered_rotate(v, 2, 4);
151+
}
152+
153+
// CHECK-SPIRV-LABEL: 5 Function
154+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[long]] {{[0-9]+}} [[ScopeSubgroup]] [[long_0]] [[int_2]]
155+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[long]] {{[0-9]+}} [[ScopeSubgroup]] [[long_0]] [[int_2]] [[int_4]]
156+
// CHECK-SPIRV: FunctionEnd
157+
158+
// CHECK-COMMON-LABEL: @testRotateLong
159+
160+
// CHECK-LLVM: call spir_func i64 @_Z16sub_group_rotateli(i64 0, i32 2)
161+
// CHECK-LLVM: call spir_func i64 @_Z26sub_group_clustered_rotatelij(i64 0, i32 2, i32 4)
162+
163+
// CHECK-SPV-IR: call spir_func i64 @_Z32__spirv_GroupNonUniformRotateKHRili(i32 3, i64 0, i32 2)
164+
// CHECK-SPV-IR: call spir_func i64 @_Z32__spirv_GroupNonUniformRotateKHRilij(i32 3, i64 0, i32 2, i32 4)
165+
kernel void testRotateLong(global long* dst)
166+
{
167+
long v = 0;
168+
dst[0] = sub_group_rotate(v, 2);
169+
dst[1] = sub_group_clustered_rotate(v, 2, 4);
170+
}
171+
172+
// CHECK-SPIRV-LABEL: 5 Function
173+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[long]] {{[0-9]+}} [[ScopeSubgroup]] [[long_0]] [[int_2]]
174+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[long]] {{[0-9]+}} [[ScopeSubgroup]] [[long_0]] [[int_2]] [[int_4]]
175+
// CHECK-SPIRV: FunctionEnd
176+
177+
// CHECK-COMMON-LABEL: @testRotateULong
178+
179+
// CHECK-LLVM: call spir_func i64 @_Z16sub_group_rotateli(i64 0, i32 2)
180+
// CHECK-LLVM: call spir_func i64 @_Z26sub_group_clustered_rotatelij(i64 0, i32 2, i32 4)
181+
182+
// CHECK-SPV-IR: call spir_func i64 @_Z32__spirv_GroupNonUniformRotateKHRili(i32 3, i64 0, i32 2)
183+
// CHECK-SPV-IR: call spir_func i64 @_Z32__spirv_GroupNonUniformRotateKHRilij(i32 3, i64 0, i32 2, i32 4)
184+
kernel void testRotateULong(global ulong* dst)
185+
{
186+
ulong v = 0;
187+
dst[0] = sub_group_rotate(v, 2);
188+
dst[1] = sub_group_clustered_rotate(v, 2, 4);
189+
}
190+
191+
// CHECK-SPIRV-LABEL: 5 Function
192+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[float]] {{[0-9]+}} [[ScopeSubgroup]] [[float_0]] [[int_2]]
193+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[float]] {{[0-9]+}} [[ScopeSubgroup]] [[float_0]] [[int_2]] [[int_4]]
194+
// CHECK-SPIRV: FunctionEnd
195+
196+
// CHECK-COMMON-LABEL: @testRotateFloat
197+
198+
// CHECK-LLVM: call spir_func float @_Z16sub_group_rotatefi(float 0.000000e+00, i32 2)
199+
// CHECK-LLVM: call spir_func float @_Z26sub_group_clustered_rotatefij(float 0.000000e+00, i32 2, i32 4)
200+
201+
// CHECK-SPV-IR: call spir_func float @_Z32__spirv_GroupNonUniformRotateKHRifi(i32 3, float 0.000000e+00, i32 2)
202+
// CHECK-SPV-IR: call spir_func float @_Z32__spirv_GroupNonUniformRotateKHRifij(i32 3, float 0.000000e+00, i32 2, i32 4)
203+
kernel void testRotateFloat(global float* dst)
204+
{
205+
float v = 0;
206+
dst[0] = sub_group_rotate(v, 2);
207+
dst[1] = sub_group_clustered_rotate(v, 2, 4);
208+
}
209+
210+
// CHECK-SPIRV-LABEL: 5 Function
211+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[half]] {{[0-9]+}} [[ScopeSubgroup]] [[half_0]] [[int_2]]
212+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[half]] {{[0-9]+}} [[ScopeSubgroup]] [[half_0]] [[int_2]] [[int_4]]
213+
// CHECK-SPIRV: FunctionEnd
214+
215+
// CHECK-COMMON-LABEL: @testRotateHalf
216+
217+
// CHECK-LLVM: call spir_func half @_Z16sub_group_rotateDhi(half 0xH0000, i32 2)
218+
// CHECK-LLVM: call spir_func half @_Z26sub_group_clustered_rotateDhij(half 0xH0000, i32 2, i32 4)
219+
220+
// CHECK-SPV-IR: call spir_func half @_Z32__spirv_GroupNonUniformRotateKHRiDhi(i32 3, half 0xH0000, i32 2)
221+
// CHECK-SPV-IR: call spir_func half @_Z32__spirv_GroupNonUniformRotateKHRiDhij(i32 3, half 0xH0000, i32 2, i32 4)
222+
kernel void testRotateHalf(global half* dst)
223+
{
224+
half v = 0;
225+
dst[0] = sub_group_rotate(v, 2);
226+
dst[1] = sub_group_clustered_rotate(v, 2, 4);
227+
}
228+
229+
// CHECK-SPIRV-LABEL: 5 Function
230+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[double]] {{[0-9]+}} [[ScopeSubgroup]] [[double_0]] [[int_2]]
231+
// CHECK-SPIRV: GroupNonUniformRotateKHR [[double]] {{[0-9]+}} [[ScopeSubgroup]] [[double_0]] [[int_2]] [[int_4]]
232+
// CHECK-SPIRV: FunctionEnd
233+
234+
// CHECK-COMMON-LABEL: @testRotateDouble
235+
236+
// CHECK-LLVM: call spir_func double @_Z16sub_group_rotatedi(double 0.000000e+00, i32 2)
237+
// CHECK-LLVM: call spir_func double @_Z26sub_group_clustered_rotatedij(double 0.000000e+00, i32 2, i32 4)
238+
239+
// CHECK-SPV-IR: call spir_func double @_Z32__spirv_GroupNonUniformRotateKHRidi(i32 3, double 0.000000e+00, i32 2)
240+
// CHECK-SPV-IR: call spir_func double @_Z32__spirv_GroupNonUniformRotateKHRidij(i32 3, double 0.000000e+00, i32 2, i32 4)
241+
kernel void testRotateDouble(global double* dst)
242+
{
243+
double v = 0;
244+
dst[0] = sub_group_rotate(v, 2);
245+
dst[1] = sub_group_clustered_rotate(v, 2, 4);
246+
}

0 commit comments

Comments
 (0)