Skip to content

Commit b6aa028

Browse files
bashbaugdbudanov-cmplr
authored andcommitted
Add support for split barriers extension SPV_INTEL_split_barrier (#1424)
This PR adds support for split barriers and the SPV_INTEL_split_barrier extension. The related SPIR-V extension spec can be found here: * KhronosGroup/SPIRV-Registry#136 The related OpenCL C extension spec can be found here: * KhronosGroup/OpenCL-Docs#765 Original commit: KhronosGroup/SPIRV-LLVM-Translator@e3cd296
1 parent ee0eea2 commit b6aa028

16 files changed

+571
-2
lines changed

llvm-spirv/include/LLVMSPIRVExtensions.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,4 @@ EXT(SPV_INTEL_hw_thread_queries)
5353
EXT(SPV_INTEL_global_variable_decorations)
5454
EXT(SPV_INTEL_non_constant_addrspace_printf)
5555
EXT(SPV_INTEL_complex_float_mul_div)
56+
EXT(SPV_INTEL_split_barrier)

llvm-spirv/lib/SPIRV/OCLToSPIRV.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,10 @@ void OCLToSPIRVBase::visitCallInst(CallInst &CI) {
379379
visitSubgroupImageMediaBlockINTEL(&CI, DemangledName);
380380
return;
381381
}
382+
if (DemangledName.find(kOCLBuiltinName::SplitBarrierINTELPrefix) == 0) {
383+
visitCallSplitBarrierINTEL(&CI, DemangledName);
384+
return;
385+
}
382386
// Handle 'cl_intel_device_side_avc_motion_estimation' extension built-ins
383387
if (DemangledName.find(kOCLSubgroupsAVCIntel::Prefix) == 0 ||
384388
// Workaround for a bug in the extension specification
@@ -1870,6 +1874,37 @@ void OCLToSPIRVBase::visitSubgroupAVCBuiltinCallWithSampler(
18701874
&Attrs);
18711875
}
18721876

1877+
void OCLToSPIRVBase::visitCallSplitBarrierINTEL(CallInst *CI,
1878+
StringRef DemangledName) {
1879+
auto Lit = getBarrierLiterals(CI);
1880+
AttributeList Attrs = CI->getCalledFunction()->getAttributes();
1881+
Op OpCode =
1882+
StringSwitch<Op>(DemangledName)
1883+
.Case("intel_work_group_barrier_arrive", OpControlBarrierArriveINTEL)
1884+
.Case("intel_work_group_barrier_wait", OpControlBarrierWaitINTEL)
1885+
.Default(OpNop);
1886+
1887+
mutateCallInstSPIRV(
1888+
M, CI,
1889+
[=](CallInst *, std::vector<Value *> &Args) {
1890+
Args.resize(3);
1891+
// Execution scope
1892+
Args[0] = addInt32(map<Scope>(std::get<2>(Lit)));
1893+
// Memory scope
1894+
Args[1] = addInt32(map<Scope>(std::get<1>(Lit)));
1895+
// Memory semantics
1896+
// OpControlBarrierArriveINTEL -> Release,
1897+
// OpControlBarrierWaitINTEL -> Acquire
1898+
unsigned MemFenceFlag = std::get<0>(Lit);
1899+
OCLMemOrderKind MemOrder = OpCode == OpControlBarrierArriveINTEL
1900+
? OCLMO_release
1901+
: OCLMO_acquire;
1902+
Args[2] = addInt32(mapOCLMemSemanticToSPIRV(MemFenceFlag, MemOrder));
1903+
return getSPIRVFuncName(OpCode);
1904+
},
1905+
&Attrs);
1906+
}
1907+
18731908
void OCLToSPIRVBase::visitCallLdexp(CallInst *CI, StringRef MangledName,
18741909
StringRef DemangledName) {
18751910
auto Args = getArguments(CI);

llvm-spirv/lib/SPIRV/OCLToSPIRV.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,9 @@ class OCLToSPIRVBase : public InstVisitor<OCLToSPIRVBase> {
247247
void visitSubgroupAVCBuiltinCallWithSampler(CallInst *CI,
248248
StringRef DemangledName);
249249

250+
/// For cl_intel_split_work_group_barrier built-ins:
251+
void visitCallSplitBarrierINTEL(CallInst *CI, StringRef DemangledName);
252+
250253
void visitCallLdexp(CallInst *CI, StringRef MangledName,
251254
StringRef DemangledName);
252255

llvm-spirv/lib/SPIRV/OCLUtil.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,9 @@ template <> void SPIRVMap<std::string, Op, SPIRVInstruction>::init() {
424424
_SPIRV_OP(bitfield_extract_signed, BitFieldSExtract)
425425
_SPIRV_OP(bitfield_extract_unsigned, BitFieldUExtract)
426426
_SPIRV_OP(bit_reverse, BitReverse)
427+
// cl_khr_split_work_group_barrier
428+
_SPIRV_OP(intel_work_group_barrier_arrive, ControlBarrierArriveINTEL)
429+
_SPIRV_OP(intel_work_group_barrier_wait, ControlBarrierWaitINTEL)
427430
#undef _SPIRV_OP
428431
}
429432

@@ -1030,7 +1033,9 @@ class OCLBuiltinFuncMangleInfo : public SPIRV::BuiltinFuncMangleInfo {
10301033
} else if (NameRef.contains("barrier")) {
10311034
addUnsignedArg(0);
10321035
if (NameRef.equals("work_group_barrier") ||
1033-
NameRef.equals("sub_group_barrier"))
1036+
NameRef.equals("sub_group_barrier") ||
1037+
NameRef.equals("intel_work_group_barrier_arrive") ||
1038+
NameRef.equals("intel_work_group_barrier_wait"))
10341039
setEnumArg(1, SPIR::PRIMITIVE_MEMORY_SCOPE);
10351040
} else if (NameRef.startswith("atomic_work_item_fence")) {
10361041
addUnsignedArg(0);

llvm-spirv/lib/SPIRV/OCLUtil.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ const static char SubgroupBlockWriteINTELPrefix[] =
305305
"intel_sub_group_block_write";
306306
const static char SubgroupImageMediaBlockINTELPrefix[] =
307307
"intel_sub_group_media_block";
308+
const static char SplitBarrierINTELPrefix[] = "intel_work_group_barrier_";
308309
const static char LDEXP[] = "ldexp";
309310
#define _SPIRV_OP(x) \
310311
const static char ConvertBFloat16##x##AsUShort##x[] = \

llvm-spirv/lib/SPIRV/SPIRVReader.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3077,7 +3077,7 @@ Instruction *SPIRVToLLVM::transBuiltinFromInst(const std::string &FuncName,
30773077
Func->addFnAttr(Attribute::NoUnwind);
30783078
auto OC = BI->getOpCode();
30793079
if (isGroupOpCode(OC) || isIntelSubgroupOpCode(OC) ||
3080-
OC == OpControlBarrier)
3080+
isSplitBarrierINTELOpCode(OC) || OC == OpControlBarrier)
30813081
Func->addFnAttr(Attribute::Convergent);
30823082
}
30833083
auto Call =

llvm-spirv/lib/SPIRV/SPIRVToOCL.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ void SPIRVToOCLBase::visitCallInst(CallInst &CI) {
119119
if (OC == OpControlBarrier) {
120120
visitCallSPIRVControlBarrier(&CI);
121121
}
122+
if (isSplitBarrierINTELOpCode(OC)) {
123+
visitCallSPIRVSplitBarrierINTEL(&CI, OC);
124+
return;
125+
}
122126
if (isAtomicOpCode(OC)) {
123127
visitCallSPIRVAtomicBuiltin(&CI, OC);
124128
return;

llvm-spirv/lib/SPIRV/SPIRVToOCL.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,12 @@ class SPIRVToOCLBase : public InstVisitor<SPIRVToOCLBase> {
222222
/// - OCL1.2: barrier
223223
virtual void visitCallSPIRVControlBarrier(CallInst *CI) = 0;
224224

225+
/// Transform split __spirv_ControlBarrierArriveINTEL and
226+
/// __spirv_ControlBarrierWaitINTEL barrier to:
227+
/// - OCL2.0: overload with a memory_scope argument
228+
/// - OCL1.2: overload with no memory_scope argument
229+
virtual void visitCallSPIRVSplitBarrierINTEL(CallInst *CI, Op OC) = 0;
230+
225231
/// Transform __spirv_EnqueueKernel to __enqueue_kernel
226232
virtual void visitCallSPIRVEnqueueKernel(CallInst *CI, Op OC) = 0;
227233

@@ -305,6 +311,11 @@ class SPIRVToOCL12Base : public SPIRVToOCLBase {
305311
/// barrier(flag(sema))
306312
void visitCallSPIRVControlBarrier(CallInst *CI) override;
307313

314+
/// Transform split __spirv_ControlBarrierArriveINTEL and
315+
/// __spirv_ControlBarrierWaitINTEL barrier to overloads without a
316+
/// memory_scope argument.
317+
void visitCallSPIRVSplitBarrierINTEL(CallInst *CI, Op OC) override;
318+
308319
/// Transform __spirv_OpAtomic functions. It firstly conduct generic
309320
/// mutations for all builtins and then mutate some of them seperately
310321
Instruction *visitCallSPIRVAtomicBuiltin(CallInst *CI, Op OC) override;
@@ -394,6 +405,11 @@ class SPIRVToOCL20Base : public SPIRVToOCLBase {
394405
/// sub_group_barrier(flag(sema), map(memScope))
395406
void visitCallSPIRVControlBarrier(CallInst *CI) override;
396407

408+
/// Transform split __spirv_ControlBarrierArriveINTEL and
409+
/// __spirv_ControlBarrierWaitINTEL barrier to overloads with a
410+
/// memory_scope argument.
411+
void visitCallSPIRVSplitBarrierINTEL(CallInst *CI, Op OC) override;
412+
397413
/// Transform __spirv_Atomic* to atomic_*.
398414
/// __spirv_Atomic*(atomic_op, scope, sema, ops, ...) =>
399415
/// atomic_*(generic atomic_op, ops, ..., order(sema), map(scope))

llvm-spirv/lib/SPIRV/SPIRVToOCL12.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,19 @@ void SPIRVToOCL12Base::visitCallSPIRVControlBarrier(CallInst *CI) {
100100
&Attrs);
101101
}
102102

103+
void SPIRVToOCL12Base::visitCallSPIRVSplitBarrierINTEL(CallInst *CI, Op OC) {
104+
AttributeList Attrs = CI->getCalledFunction()->getAttributes();
105+
mutateCallInstOCL(
106+
M, CI,
107+
[=](CallInst *, std::vector<Value *> &Args) {
108+
Value *MemFenceFlags =
109+
SPIRV::transSPIRVMemorySemanticsIntoOCLMemFenceFlags(Args[2], CI);
110+
Args.assign(1, MemFenceFlags);
111+
return OCLSPIRVBuiltinMap::rmap(OC);
112+
},
113+
&Attrs);
114+
}
115+
103116
Instruction *SPIRVToOCL12Base::visitCallSPIRVAtomicIncDec(CallInst *CI, Op OC) {
104117
AttributeList Attrs = CI->getCalledFunction()->getAttributes();
105118
return mutateCallInstOCL(

llvm-spirv/lib/SPIRV/SPIRVToOCL20.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,28 @@ void SPIRVToOCL20Base::visitCallSPIRVControlBarrier(CallInst *CI) {
123123
&NewAttrs);
124124
}
125125

126+
void SPIRVToOCL20Base::visitCallSPIRVSplitBarrierINTEL(CallInst *CI, Op OC) {
127+
AttributeList Attrs = CI->getCalledFunction()->getAttributes();
128+
mutateCallInstOCL(
129+
M, CI,
130+
[=](CallInst *, std::vector<Value *> &Args) {
131+
auto GetArg = [=](unsigned I) {
132+
return cast<ConstantInt>(Args[I])->getZExtValue();
133+
};
134+
Value *MemScope =
135+
getInt32(M, rmap<OCLScopeKind>(static_cast<Scope>(GetArg(1))));
136+
Value *MemFenceFlags =
137+
SPIRV::transSPIRVMemorySemanticsIntoOCLMemFenceFlags(Args[2], CI);
138+
139+
Args.resize(2);
140+
Args[0] = MemFenceFlags;
141+
Args[1] = MemScope;
142+
143+
return OCLSPIRVBuiltinMap::rmap(OC);
144+
},
145+
&Attrs);
146+
}
147+
126148
std::string SPIRVToOCL20Base::mapFPAtomicName(Op OC) {
127149
assert(isFPAtomicOpCode(OC) && "Not intended to handle other opcodes than "
128150
"AtomicF{Add/Min/Max}EXT!");

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVInstruction.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3327,6 +3327,24 @@ _SPIRV_OP(JointMatrixMad, true, 7)
33273327
_SPIRV_OP(JointMatrixWorkItemLength, true, 4)
33283328
#undef _SPIRV_OP
33293329

3330+
class SPIRVSplitBarrierINTELBase : public SPIRVInstTemplateBase {
3331+
protected:
3332+
SPIRVCapVec getRequiredCapability() const override {
3333+
return getVec(CapabilitySplitBarrierINTEL);
3334+
}
3335+
3336+
llvm::Optional<ExtensionID> getRequiredExtension() const override {
3337+
return ExtensionID::SPV_INTEL_split_barrier;
3338+
}
3339+
};
3340+
3341+
#define _SPIRV_OP(x, ...) \
3342+
typedef SPIRVInstTemplate<SPIRVSplitBarrierINTELBase, Op##x, __VA_ARGS__> \
3343+
SPIRV##x;
3344+
_SPIRV_OP(ControlBarrierArriveINTEL, false, 4)
3345+
_SPIRV_OP(ControlBarrierWaitINTEL, false, 4)
3346+
#undef _SPIRV_OP
3347+
33303348
class SPIRVGroupUniformArithmeticKHRInstBase : public SPIRVInstTemplateBase {
33313349
public:
33323350
SPIRVCapVec getRequiredCapability() const override {

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVOpCode.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,11 @@ inline bool isEventOpCode(Op OpCode) {
247247
return OpRetainEvent <= OpCode && OpCode <= OpCaptureEventProfilingInfo;
248248
}
249249

250+
inline bool isSplitBarrierINTELOpCode(Op OpCode) {
251+
return OpCode == OpControlBarrierArriveINTEL ||
252+
OpCode == OpControlBarrierWaitINTEL;
253+
}
254+
250255
} // namespace SPIRV
251256

252257
#endif // SPIRV_LIBSPIRV_SPIRVOPCODE_H

llvm-spirv/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,8 @@ _SPIRV_OP(TypeBufferSurfaceINTEL, 6086)
547547
_SPIRV_OP(TypeStructContinuedINTEL, 6090)
548548
_SPIRV_OP(ConstantCompositeContinuedINTEL, 6091)
549549
_SPIRV_OP(SpecConstantCompositeContinuedINTEL, 6092)
550+
_SPIRV_OP(ControlBarrierArriveINTEL, 6142)
551+
_SPIRV_OP(ControlBarrierWaitINTEL, 6143)
550552
_SPIRV_OP(GroupIMulKHR, 6401)
551553
_SPIRV_OP(GroupFMulKHR, 6402)
552554
_SPIRV_OP(GroupBitwiseAndKHR, 6403)
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
;; kernel void test(global uint* dst)
2+
;; {
3+
;; intel_work_group_barrier_arrive(CLK_LOCAL_MEM_FENCE);
4+
;; intel_work_group_barrier_wait(CLK_LOCAL_MEM_FENCE);
5+
;; intel_work_group_barrier_arrive(CLK_GLOBAL_MEM_FENCE);
6+
;; intel_work_group_barrier_wait(CLK_GLOBAL_MEM_FENCE);
7+
;;
8+
;; intel_work_group_barrier_arrive(CLK_LOCAL_MEM_FENCE | CLK_GLOBAL_MEM_FENCE);
9+
;; intel_work_group_barrier_wait(CLK_LOCAL_MEM_FENCE | CLK_GLOBAL_MEM_FENCE);
10+
;;}
11+
12+
; Test for SPV_INTEL_split_barrier (OpenCL C LLVM IR)
13+
; RUN: llvm-as %s -o %t.bc
14+
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_split_barrier
15+
; RUN: llvm-spirv %t.spv -o %t.spt --to-text
16+
; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
17+
; RUN: llvm-spirv %t.spv -o %t.rev.bc -r --spirv-target-env=CL1.2
18+
; RUN: llvm-dis %t.rev.bc -o %t.rev.ll
19+
; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM
20+
21+
; RUN: not llvm-spirv %t.bc 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
22+
; CHECK-ERROR: RequiresExtension: Feature requires the following SPIR-V extension:
23+
; CHECK-ERROR-NEXT: SPV_INTEL_split_barrier
24+
25+
; ModuleID = 'split_barrier.cl'
26+
source_filename = "split_barrier.cl"
27+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
28+
target triple = "spir64"
29+
30+
; CHECK-SPIRV: Capability SplitBarrierINTEL
31+
; CHECK-SPIRV: Extension "SPV_INTEL_split_barrier"
32+
; CHECK-SPIRV: TypeInt [[UINT:[0-9]+]] 32 0
33+
;
34+
; Scopes:
35+
; CHECK-SPIRV-DAG: Constant [[UINT]] [[SCOPE_WORK_GROUP:[0-9]+]] 2
36+
;
37+
; Memory Semantics:
38+
; 0x2 Acquire + 0x100 WorkgroupMemory
39+
; CHECK-SPIRV-DAG: Constant [[UINT]] [[ACQUIRE_LOCAL:[0-9]+]] 258
40+
; 0x4 Release + 0x100 WorkgroupMemory
41+
; CHECK-SPIRV-DAG: Constant [[UINT]] [[RELEASE_LOCAL:[0-9]+]] 260
42+
; 0x2 Acquire + 0x200 CrossWorkgroupMemory
43+
; CHECK-SPIRV-DAG: Constant [[UINT]] [[ACQUIRE_GLOBAL:[0-9]+]] 514
44+
; 0x4 Release + 0x200 CrossWorkgroupMemory
45+
; CHECK-SPIRV-DAG: Constant [[UINT]] [[RELEASE_GLOBAL:[0-9]+]] 516
46+
; 0x2 Acquire + 0x100 WorkgroupMemory + 0x200 CrossWorkgroupMemory
47+
; CHECK-SPIRV-DAG: Constant [[UINT]] [[ACQUIRE_LOCAL_GLOBAL:[0-9]+]] 770
48+
; 0x4 Release + 0x100 WorkgroupMemory + 0x200 CrossWorkgroupMemory
49+
; CHECK-SPIRV-DAG: Constant [[UINT]] [[RELEASE_LOCAL_GLOBAL:[0-9]+]] 772
50+
;
51+
; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[RELEASE_LOCAL]]
52+
; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[ACQUIRE_LOCAL]]
53+
; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[RELEASE_GLOBAL]]
54+
; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[ACQUIRE_GLOBAL]]
55+
;
56+
; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[RELEASE_LOCAL_GLOBAL]]
57+
; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[ACQUIRE_LOCAL_GLOBAL]]
58+
59+
; CHECK-LLVM-LABEL: define spir_kernel void @test
60+
; Function Attrs: convergent norecurse nounwind
61+
define dso_local spir_kernel void @test(i32 addrspace(1)* nocapture noundef readnone align 4 %0) local_unnamed_addr #0 !kernel_arg_addr_space !4 !kernel_arg_access_qual !5 !kernel_arg_type !6 !kernel_arg_base_type !6 !kernel_arg_type_qual !7 {
62+
tail call spir_func void @_Z31intel_work_group_barrier_arrivej(i32 noundef 1) #2
63+
; CHECK-LLVM: call spir_func void @_Z31intel_work_group_barrier_arrivej(i32 1)
64+
tail call spir_func void @_Z29intel_work_group_barrier_waitj(i32 noundef 1) #2
65+
; CHECK-LLVM: call spir_func void @_Z29intel_work_group_barrier_waitj(i32 1)
66+
tail call spir_func void @_Z31intel_work_group_barrier_arrivej(i32 noundef 2) #2
67+
; CHECK-LLVM: call spir_func void @_Z31intel_work_group_barrier_arrivej(i32 2)
68+
tail call spir_func void @_Z29intel_work_group_barrier_waitj(i32 noundef 2) #2
69+
; CHECK-LLVM: call spir_func void @_Z29intel_work_group_barrier_waitj(i32 2)
70+
tail call spir_func void @_Z31intel_work_group_barrier_arrivej(i32 noundef 3) #2
71+
; CHECK-LLVM: call spir_func void @_Z31intel_work_group_barrier_arrivej(i32 3)
72+
tail call spir_func void @_Z29intel_work_group_barrier_waitj(i32 noundef 3) #2
73+
; CHECK-LLVM: call spir_func void @_Z29intel_work_group_barrier_waitj(i32 3)
74+
ret void
75+
}
76+
77+
; Function Attrs: convergent
78+
declare dso_local spir_func void @_Z31intel_work_group_barrier_arrivej(i32 noundef) local_unnamed_addr #1
79+
80+
; Function Attrs: convergent
81+
declare dso_local spir_func void @_Z29intel_work_group_barrier_waitj(i32 noundef) local_unnamed_addr #1
82+
83+
attributes #0 = { convergent norecurse nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "uniform-work-group-size"="true" }
84+
attributes #1 = { convergent "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
85+
attributes #2 = { convergent nounwind }
86+
87+
!llvm.module.flags = !{!0, !1}
88+
!opencl.ocl.version = !{!2}
89+
!opencl.spir.version = !{!2}
90+
!llvm.ident = !{!3}
91+
92+
!0 = !{i32 1, !"wchar_size", i32 4}
93+
!1 = !{i32 7, !"frame-pointer", i32 2}
94+
!2 = !{i32 1, i32 2}
95+
!3 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project 861386dbd6ff0d91636b7c674c2abb2eccd9d3f2)"}
96+
!4 = !{i32 1}
97+
!5 = !{!"none"}
98+
!6 = !{!"uint*"}
99+
!7 = !{!""}

0 commit comments

Comments
 (0)