Skip to content

Commit 24cee1c

Browse files
[SPIR-V] Add __spirv_ wrappers to Non-Uniform, Atomic, Convert Instructions (#96790)
This PR: * adds missing __spirv_ wrappers to Non-Uniform, Atomic, and Convert Instructions, * fixes emission of Group builtins, * adds relevant checks to test cases to cover newly added __spirv_ wrappers.
1 parent 8ce1aed commit 24cee1c

10 files changed

+269
-25
lines changed

llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,15 +1066,17 @@ static bool generateGroupInst(const SPIRV::IncomingCall *Call,
10661066
Register ScopeReg = Call->Arguments[0];
10671067
if (!MRI->getRegClassOrNull(ScopeReg))
10681068
MRI->setRegClass(ScopeReg, &SPIRV::IDRegClass);
1069-
Register ValueReg = Call->Arguments[2];
1070-
if (!MRI->getRegClassOrNull(ValueReg))
1071-
MRI->setRegClass(ValueReg, &SPIRV::IDRegClass);
1072-
MIRBuilder.buildInstr(GroupBuiltin->Opcode)
1073-
.addDef(Call->ReturnRegister)
1074-
.addUse(GR->getSPIRVTypeID(Call->ReturnType))
1075-
.addUse(ScopeReg)
1076-
.addImm(GrpOp)
1077-
.addUse(ValueReg);
1069+
auto MIB = MIRBuilder.buildInstr(GroupBuiltin->Opcode)
1070+
.addDef(Call->ReturnRegister)
1071+
.addUse(GR->getSPIRVTypeID(Call->ReturnType))
1072+
.addUse(ScopeReg)
1073+
.addImm(GrpOp);
1074+
for (unsigned i = 2; i < Call->Arguments.size(); ++i) {
1075+
Register ArgReg = Call->Arguments[i];
1076+
if (!MRI->getRegClassOrNull(ArgReg))
1077+
MRI->setRegClass(ArgReg, &SPIRV::IDRegClass);
1078+
MIB.addUse(ArgReg);
1079+
}
10781080
return true;
10791081
}
10801082

@@ -1467,6 +1469,9 @@ static bool generateAtomicInst(const SPIRV::IncomingCall *Call,
14671469
case SPIRV::OpAtomicFlagClear:
14681470
return buildAtomicFlagInst(Call, Opcode, MIRBuilder, GR);
14691471
default:
1472+
if (Call->isSpirvOp())
1473+
return buildOpFromWrapper(MIRBuilder, Opcode, Call,
1474+
GR->getSPIRVTypeID(Call->ReturnType));
14701475
return false;
14711476
}
14721477
}
@@ -1510,6 +1515,9 @@ static bool generateCastToPtrInst(const SPIRV::IncomingCall *Call,
15101515
static bool generateDotOrFMulInst(const SPIRV::IncomingCall *Call,
15111516
MachineIRBuilder &MIRBuilder,
15121517
SPIRVGlobalRegistry *GR) {
1518+
if (Call->isSpirvOp())
1519+
return buildOpFromWrapper(MIRBuilder, SPIRV::OpDot, Call,
1520+
GR->getSPIRVTypeID(Call->ReturnType));
15131521
unsigned Opcode = GR->getSPIRVTypeForVReg(Call->Arguments[0])->getOpcode();
15141522
bool IsVec = Opcode == SPIRV::OpTypeVector;
15151523
// Use OpDot only in case of vector args and OpFMul in case of scalar args.
@@ -2232,6 +2240,14 @@ static bool generateConvertInst(const StringRef DemangledCall,
22322240
const SPIRV::ConvertBuiltin *Builtin =
22332241
SPIRV::lookupConvertBuiltin(Call->Builtin->Name, Call->Builtin->Set);
22342242

2243+
if (!Builtin && Call->isSpirvOp()) {
2244+
const SPIRV::DemangledBuiltin *Builtin = Call->Builtin;
2245+
unsigned Opcode =
2246+
SPIRV::lookupNativeBuiltin(Builtin->Name, Builtin->Set)->Opcode;
2247+
return buildOpFromWrapper(MIRBuilder, Opcode, Call,
2248+
GR->getSPIRVTypeID(Call->ReturnType));
2249+
}
2250+
22352251
if (Builtin->IsSaturated)
22362252
buildOpDecorate(Call->ReturnRegister, MIRBuilder,
22372253
SPIRV::Decoration::SaturatedConversion, {});

llvm/lib/Target/SPIRV/SPIRVBuiltins.td

Lines changed: 48 additions & 1 deletion
Large diffs are not rendered by default.

llvm/test/CodeGen/SPIRV/instructions/atomic.ll

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
2+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
3+
14
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
25
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
36

@@ -12,6 +15,7 @@
1215
; CHECK-DAG: OpName [[XOR:%.*]] "test_xor"
1316

1417
; CHECK-DAG: [[I32Ty:%.*]] = OpTypeInt 32 0
18+
; CHECK-DAG: [[I64Ty:%.*]] = OpTypeInt 64 0
1519
;; Device scope is encoded with constant 1
1620
; CHECK-DAG: [[SCOPE:%.*]] = OpConstant [[I32Ty]] 1
1721
;; "monotonic" maps to the relaxed memory semantics, encoded with constant 0
@@ -133,3 +137,24 @@ define i32 @test_xor(i32* %ptr, i32 %val) {
133137
%r = atomicrmw xor i32* %ptr, i32 %val monotonic
134138
ret i32 %r
135139
}
140+
141+
; CHECK: OpFunction
142+
; CHECK: [[Arg1:%.*]] = OpFunctionParameter
143+
; CHECK: [[Arg2:%.*]] = OpFunctionParameter
144+
; CHECK: OpAtomicSMin [[I64Ty]] %[[#]] [[SCOPE]] [[RELAXED]] [[Arg2]]
145+
; CHECK: OpAtomicSMax [[I64Ty]] %[[#]] [[SCOPE]] [[RELAXED]] [[Arg2]]
146+
; CHECK: OpAtomicUMin [[I64Ty]] %[[#]] [[SCOPE]] [[RELAXED]] [[Arg2]]
147+
; CHECK: OpAtomicUMax [[I64Ty]] %[[#]] [[SCOPE]] [[RELAXED]] [[Arg2]]
148+
; CHECK: OpFunctionEnd
149+
define dso_local spir_kernel void @test_wrappers(ptr addrspace(4) %arg, i64 %val) {
150+
%r1 = call spir_func i64 @__spirv_AtomicSMin(ptr addrspace(4) %arg, i32 1, i32 0, i64 %val)
151+
%r2 = call spir_func i64 @__spirv_AtomicSMax(ptr addrspace(4) %arg, i32 1, i32 0, i64 %val)
152+
%r3 = call spir_func i64 @__spirv_AtomicUMin(ptr addrspace(4) %arg, i32 1, i32 0, i64 %val)
153+
%r4 = call spir_func i64 @__spirv_AtomicUMax(ptr addrspace(4) %arg, i32 1, i32 0, i64 %val)
154+
ret void
155+
}
156+
157+
declare dso_local spir_func i64 @__spirv_AtomicSMin(ptr addrspace(4), i32, i32, i64)
158+
declare dso_local spir_func i64 @__spirv_AtomicSMax(ptr addrspace(4), i32, i32, i64)
159+
declare dso_local spir_func i64 @__spirv_AtomicUMin(ptr addrspace(4), i32, i32, i64)
160+
declare dso_local spir_func i64 @__spirv_AtomicUMax(ptr addrspace(4), i32, i32, i64)

llvm/test/CodeGen/SPIRV/instructions/integer-casts.ll

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
2+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
3+
14
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
5+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
26

37
; CHECK-DAG: OpName [[TRUNC32_16:%.*]] "i32toi16"
48
; CHECK-DAG: OpName [[TRUNC32_8:%.*]] "i32toi8"
@@ -20,6 +24,9 @@
2024
; CHECK-DAG: OpName [[ZEXT8_16v4:%.*]] "u8tou16v4"
2125
; CHECK-DAG: OpName [[ZEXT16_32v4:%.*]] "u16tou32v4"
2226

27+
; CHECK-DAG: [[F32:%.*]] = OpTypeFloat 32
28+
; CHECK-DAG: [[F16:%.*]] = OpTypeFloat 16
29+
; CHECK-DAG: [[U64:%.*]] = OpTypeInt 64 0
2330
; CHECK-DAG: [[U32:%.*]] = OpTypeInt 32 0
2431
; CHECK-DAG: [[U16:%.*]] = OpTypeInt 16 0
2532
; CHECK-DAG: [[U8:%.*]] = OpTypeInt 8 0
@@ -227,3 +234,48 @@ define <4 x i32> @u16tou32v4(<4 x i16> %a) {
227234
%r = zext <4 x i16> %a to <4 x i32>
228235
ret <4 x i32> %r
229236
}
237+
238+
; CHECK: OpFunction
239+
; CHECK: [[Arg1:%.*]] = OpFunctionParameter
240+
; CHECK: [[Arg2:%.*]] = OpFunctionParameter
241+
; CHECK: %[[#]] = OpConvertFToU [[U32]] %[[#]]
242+
; CHECK: %[[#]] = OpConvertFToS [[U32]] %[[#]]
243+
; CHECK: %[[#]] = OpConvertSToF [[F32]] %[[#]]
244+
; CHECK: %[[#]] = OpConvertUToF [[F32]] %[[#]]
245+
; CHECK: %[[#]] = OpUConvert [[U32]] %[[#]]
246+
; CHECK: %[[#]] = OpSConvert [[U32]] %[[#]]
247+
; CHECK: %[[#]] = OpFConvert [[F16]] %[[#]]
248+
; CHECK: %[[#]] = OpQuantizeToF16 [[F32]] %[[#]]
249+
; CHECK: %[[#]] = OpSatConvertSToU [[U64]] %[[#]]
250+
; CHECK: %[[#]] = OpSatConvertUToS [[U64]] %[[#]]
251+
; CHECK: %[[#]] = OpConvertPtrToU [[U64]] [[Arg1]]
252+
; CHECK: %[[#]] = OpConvertUToPtr %[[#]] [[Arg2]]
253+
; CHECK: OpFunctionEnd
254+
define dso_local spir_kernel void @test_wrappers(ptr addrspace(4) %arg, i64 %arg_ptr) {
255+
%r1 = call spir_func i32 @__spirv_ConvertFToU(float 0.000000e+00)
256+
%r2 = call spir_func i32 @__spirv_ConvertFToS(float 0.000000e+00)
257+
%r3 = call spir_func float @__spirv_ConvertSToF(i32 1)
258+
%r4 = call spir_func float @__spirv_ConvertUToF(i32 1)
259+
%r5 = call spir_func i32 @__spirv_UConvert(i64 1)
260+
%r6 = call spir_func i32 @__spirv_SConvert(i64 1)
261+
%r7 = call spir_func half @__spirv_FConvert(float 0.000000e+00)
262+
%r8 = call spir_func float @__spirv_QuantizeToF16(float 0.000000e+00)
263+
%r9 = call spir_func i64 @__spirv_SatConvertSToU(i64 1)
264+
%r10 = call spir_func i64 @__spirv_SatConvertUToS(i64 1)
265+
%r11 = call spir_func i64 @__spirv_ConvertPtrToU(ptr addrspace(4) %arg)
266+
%r12 = call spir_func ptr addrspace(4) @__spirv_ConvertUToPtr(i64 %arg_ptr)
267+
ret void
268+
}
269+
270+
declare dso_local spir_func i32 @__spirv_ConvertFToU(float)
271+
declare dso_local spir_func i32 @__spirv_ConvertFToS(float)
272+
declare dso_local spir_func float @__spirv_ConvertSToF(i32)
273+
declare dso_local spir_func float @__spirv_ConvertUToF(i32)
274+
declare dso_local spir_func i32 @__spirv_UConvert(i64)
275+
declare dso_local spir_func i32 @__spirv_SConvert(i64)
276+
declare dso_local spir_func half @__spirv_FConvert(float)
277+
declare dso_local spir_func float @__spirv_QuantizeToF16(float)
278+
declare dso_local spir_func i64 @__spirv_SatConvertSToU(i64)
279+
declare dso_local spir_func i64 @__spirv_SatConvertUToS(i64)
280+
declare dso_local spir_func i64 @__spirv_ConvertPtrToU(ptr addrspace(4))
281+
declare dso_local spir_func ptr addrspace(4) @__spirv_ConvertUToPtr(i64)

llvm/test/CodeGen/SPIRV/transcoding/OpDot.ll

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
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 %}
3+
14
; 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 %}
6+
7+
; CHECK-SPIRV-DAG: %[[#TyFloat:]] = OpTypeFloat 32
8+
; CHECK-SPIRV-DAG: %[[#TyHalf:]] = OpTypeFloat 16
29

310
;; The OpDot operands must be vectors; check that translating dot with
411
;; scalar arguments does not result in OpDot.
@@ -16,15 +23,21 @@ entry:
1623
;; The OpDot operands must be vectors; check that translating dot with
1724
;; vector arguments results in OpDot.
1825
; CHECK-SPIRV-LABEL: %[[#]] = OpFunction %[[#]] None %[[#]]
19-
; CHECK-SPIRV: %[[#]] = OpDot %[[#]] %[[#]] %[[#]]
26+
; CHECK-SPIRV: %[[#]] = OpDot %[[#TyFloat]] %[[#]] %[[#]]
27+
; CHECK-SPIRV: %[[#]] = OpDot %[[#TyFloat]] %[[#]] %[[#]]
28+
; CHECK-SPIRV: %[[#]] = OpDot %[[#TyHalf]] %[[#]] %[[#]]
2029
; CHECK-SPIRV: OpFunctionEnd
2130

22-
define spir_kernel void @testVector(<2 x float> %f) {
31+
define spir_kernel void @testVector(<2 x float> %f, <2 x half> %h) {
2332
entry:
2433
%call = tail call spir_func float @_Z3dotDv2_fS_(<2 x float> %f, <2 x float> %f)
34+
%call2 = tail call spir_func float @__spirv_Dot(<2 x float> %f, <2 x float> %f)
35+
%call3 = tail call spir_func half @_Z11__spirv_DotDv2_DF16_S_(<2 x half> %h, <2 x half> %h)
2536
ret void
2637
}
2738

2839
declare spir_func float @_Z3dotff(float, float)
2940

3041
declare spir_func float @_Z3dotDv2_fS_(<2 x float>, <2 x float>)
42+
declare spir_func float @__spirv_Dot(<2 x float>, <2 x float>)
43+
declare spir_func half @_Z11__spirv_DotDv2_DF16_S_(<2 x half>, <2 x half>)

llvm/test/CodeGen/SPIRV/transcoding/sub_group_ballot.ll

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,55 +844,77 @@ declare dso_local spir_func double @_Z25sub_group_broadcast_firstd(double) local
844844

845845
; CHECK-SPIRV: OpFunction
846846
; CHECK-SPIRV: %[[#ballot:]] = OpGroupNonUniformBallot %[[#int4]] %[[#ScopeSubgroup]] %[[#false]]
847+
; CHECK-SPIRV: %[[#ballot2:]] = OpGroupNonUniformBallot %[[#int4]] %[[#ScopeSubgroup]] %[[#false]]
847848
; CHECK-SPIRV: %[[#]] = OpGroupNonUniformInverseBallot %[[#bool]] %[[#ScopeSubgroup]] %[[#ballot]]
849+
; CHECK-SPIRV: %[[#]] = OpGroupNonUniformInverseBallot %[[#bool]] %[[#ScopeSubgroup]] %[[#ballot2]]
848850
; CHECK-SPIRV: %[[#]] = OpGroupNonUniformBallotBitExtract %[[#bool]] %[[#ScopeSubgroup]] %[[#ballot]] %[[#int_0]]
851+
; CHECK-SPIRV: %[[#]] = OpGroupNonUniformBallotBitExtract %[[#bool]] %[[#ScopeSubgroup]] %[[#ballot2]] %[[#int_0]]
849852
; CHECK-SPIRV: %[[#]] = OpGroupNonUniformBallotBitCount %[[#int]] %[[#ScopeSubgroup]] Reduce %[[#ballot]]
853+
; CHECK-SPIRV: %[[#]] = OpGroupNonUniformBallotBitCount %[[#int]] %[[#ScopeSubgroup]] Reduce %[[#ballot2]]
850854
; CHECK-SPIRV: %[[#]] = OpGroupNonUniformBallotBitCount %[[#int]] %[[#ScopeSubgroup]] InclusiveScan %[[#ballot]]
855+
; CHECK-SPIRV: %[[#]] = OpGroupNonUniformBallotBitCount %[[#int]] %[[#ScopeSubgroup]] InclusiveScan %[[#ballot2]]
851856
; CHECK-SPIRV: %[[#]] = OpGroupNonUniformBallotBitCount %[[#int]] %[[#ScopeSubgroup]] ExclusiveScan %[[#ballot]]
857+
; CHECK-SPIRV: %[[#]] = OpGroupNonUniformBallotBitCount %[[#int]] %[[#ScopeSubgroup]] ExclusiveScan %[[#ballot2]]
852858
; CHECK-SPIRV: %[[#]] = OpGroupNonUniformBallotFindLSB %[[#int]] %[[#ScopeSubgroup]] %[[#ballot]]
859+
; CHECK-SPIRV: %[[#]] = OpGroupNonUniformBallotFindLSB %[[#int]] %[[#ScopeSubgroup]] %[[#ballot2]]
853860
; CHECK-SPIRV: %[[#]] = OpGroupNonUniformBallotFindMSB %[[#int]] %[[#ScopeSubgroup]] %[[#ballot]]
861+
; CHECK-SPIRV: %[[#]] = OpGroupNonUniformBallotFindMSB %[[#int]] %[[#ScopeSubgroup]] %[[#ballot2]]
854862
; CHECK-SPIRV: OpFunctionEnd
855863

856864
define dso_local spir_kernel void @testBallotOperations(i32 addrspace(1)* nocapture) local_unnamed_addr {
857865
%2 = tail call spir_func <4 x i32> @_Z16sub_group_balloti(i32 0)
866+
%r2 = tail call spir_func <4 x i32> @__spirv_GroupNonUniformBallot(i32 3, i1 false)
858867
%3 = tail call spir_func i32 @_Z24sub_group_inverse_ballotDv4_j(<4 x i32> %2)
868+
%r3 = tail call spir_func i1 @__spirv_GroupNonUniformInverseBallot(i32 3, <4 x i32> %r2)
859869
store i32 %3, i32 addrspace(1)* %0, align 4
860870
%4 = tail call spir_func i32 @_Z28sub_group_ballot_bit_extractDv4_jj(<4 x i32> %2, i32 0)
871+
%r4 = tail call spir_func i32 @__spirv_GroupNonUniformBallotBitExtract(i32 3, <4 x i32> %r2, i32 0)
861872
%5 = getelementptr inbounds i32, i32 addrspace(1)* %0, i64 1
862873
store i32 %4, i32 addrspace(1)* %5, align 4
863874
%6 = tail call spir_func i32 @_Z26sub_group_ballot_bit_countDv4_j(<4 x i32> %2)
875+
%r6 = tail call spir_func i32 @__spirv_GroupNonUniformBallotBitCount(i32 3, i32 0, <4 x i32> %r2)
864876
%7 = getelementptr inbounds i32, i32 addrspace(1)* %0, i64 2
865877
store i32 %6, i32 addrspace(1)* %7, align 4
866878
%8 = tail call spir_func i32 @_Z31sub_group_ballot_inclusive_scanDv4_j(<4 x i32> %2)
879+
%r8 = tail call spir_func i32 @__spirv_GroupNonUniformBallotBitCount(i32 3, i32 1, <4 x i32> %r2)
867880
%9 = getelementptr inbounds i32, i32 addrspace(1)* %0, i64 3
868881
store i32 %8, i32 addrspace(1)* %9, align 4
869882
%10 = tail call spir_func i32 @_Z31sub_group_ballot_exclusive_scanDv4_j(<4 x i32> %2)
883+
%r10 = tail call spir_func i32 @__spirv_GroupNonUniformBallotBitCount(i32 3, i32 2, <4 x i32> %r2)
870884
%11 = getelementptr inbounds i32, i32 addrspace(1)* %0, i64 4
871885
store i32 %10, i32 addrspace(1)* %11, align 4
872886
%12 = tail call spir_func i32 @_Z25sub_group_ballot_find_lsbDv4_j(<4 x i32> %2)
887+
%r12 = tail call spir_func i32 @__spirv_GroupNonUniformBallotFindLSB(i32 3, <4 x i32> %r2)
873888
%13 = getelementptr inbounds i32, i32 addrspace(1)* %0, i64 5
874889
store i32 %12, i32 addrspace(1)* %13, align 4
875890
%14 = tail call spir_func i32 @_Z25sub_group_ballot_find_msbDv4_j(<4 x i32> %2)
891+
%r14 = tail call spir_func i32 @__spirv_GroupNonUniformBallotFindMSB(i32 3, <4 x i32> %r2)
876892
%15 = getelementptr inbounds i32, i32 addrspace(1)* %0, i64 6
877893
store i32 %14, i32 addrspace(1)* %15, align 4
878894
ret void
879895
}
880896

881897
declare dso_local spir_func <4 x i32> @_Z16sub_group_balloti(i32) local_unnamed_addr
898+
declare dso_local spir_func <4 x i32> @__spirv_GroupNonUniformBallot(i32, i1)
882899

883900
declare dso_local spir_func i32 @_Z24sub_group_inverse_ballotDv4_j(<4 x i32>) local_unnamed_addr
901+
declare dso_local spir_func i1 @__spirv_GroupNonUniformInverseBallot(i32, <4 x i32>)
884902

885903
declare dso_local spir_func i32 @_Z28sub_group_ballot_bit_extractDv4_jj(<4 x i32>, i32) local_unnamed_addr
904+
declare dso_local spir_func i1 @__spirv_GroupNonUniformBallotBitExtract(i32, <4 x i32>, i32) local_unnamed_addr
886905

887906
declare dso_local spir_func i32 @_Z26sub_group_ballot_bit_countDv4_j(<4 x i32>) local_unnamed_addr
907+
declare dso_local spir_func i32 @__spirv_GroupNonUniformBallotBitCount(i32, i32, <4 x i32>)
888908

889909
declare dso_local spir_func i32 @_Z31sub_group_ballot_inclusive_scanDv4_j(<4 x i32>) local_unnamed_addr
890910

891911
declare dso_local spir_func i32 @_Z31sub_group_ballot_exclusive_scanDv4_j(<4 x i32>) local_unnamed_addr
892912

893913
declare dso_local spir_func i32 @_Z25sub_group_ballot_find_lsbDv4_j(<4 x i32>) local_unnamed_addr
914+
declare dso_local spir_func i32 @__spirv_GroupNonUniformBallotFindLSB(i32, <4 x i32>)
894915

895916
declare dso_local spir_func i32 @_Z25sub_group_ballot_find_msbDv4_j(<4 x i32>) local_unnamed_addr
917+
declare dso_local spir_func i32 @__spirv_GroupNonUniformBallotFindMSB(i32, <4 x i32>)
896918

897919
; CHECK-SPIRV: OpFunction
898920
; CHECK-SPIRV: %[[#]] = OpLoad %[[#int4]] %[[#eqMask]]

0 commit comments

Comments
 (0)