This PR adds support for split barriers and the SPV_INTEL_split_barrier extension.
The related SPIR-V extension spec can be found here:
* https://github.com/KhronosGroup/SPIRV-Registry/pull/136
The related OpenCL C extension spec can be found here:
* https://github.com/KhronosGroup/OpenCL-Docs/pull/765
Co-authored-by: Ben Ashbaugh <ben.ashbaugh@intel.com>
Gbp-Pq: Name 0002-Add-support-for-split-barriers-extension-SPV_INTEL_s.patch
EXT(SPV_INTEL_global_variable_decorations)
EXT(SPV_INTEL_non_constant_addrspace_printf)
EXT(SPV_INTEL_complex_float_mul_div)
+EXT(SPV_INTEL_split_barrier)
visitSubgroupImageMediaBlockINTEL(&CI, DemangledName);
return;
}
+ if (DemangledName.find(kOCLBuiltinName::SplitBarrierINTELPrefix) == 0) {
+ visitCallSplitBarrierINTEL(&CI, DemangledName);
+ return;
+ }
// Handle 'cl_intel_device_side_avc_motion_estimation' extension built-ins
if (DemangledName.find(kOCLSubgroupsAVCIntel::Prefix) == 0 ||
// Workaround for a bug in the extension specification
&Attrs);
}
+void OCLToSPIRVBase::visitCallSplitBarrierINTEL(CallInst *CI,
+ StringRef DemangledName) {
+ auto Lit = getBarrierLiterals(CI);
+ AttributeList Attrs = CI->getCalledFunction()->getAttributes();
+ Op OpCode =
+ StringSwitch<Op>(DemangledName)
+ .Case("intel_work_group_barrier_arrive", OpControlBarrierArriveINTEL)
+ .Case("intel_work_group_barrier_wait", OpControlBarrierWaitINTEL)
+ .Default(OpNop);
+
+ mutateCallInstSPIRV(
+ M, CI,
+ [=](CallInst *, std::vector<Value *> &Args) {
+ Args.resize(3);
+ // Execution scope
+ Args[0] = addInt32(map<Scope>(std::get<2>(Lit)));
+ // Memory scope
+ Args[1] = addInt32(map<Scope>(std::get<1>(Lit)));
+ // Memory semantics
+ // OpControlBarrierArriveINTEL -> Release,
+ // OpControlBarrierWaitINTEL -> Acquire
+ unsigned MemFenceFlag = std::get<0>(Lit);
+ OCLMemOrderKind MemOrder = OpCode == OpControlBarrierArriveINTEL
+ ? OCLMO_release
+ : OCLMO_acquire;
+ Args[2] = addInt32(mapOCLMemSemanticToSPIRV(MemFenceFlag, MemOrder));
+ return getSPIRVFuncName(OpCode);
+ },
+ &Attrs);
+}
+
void OCLToSPIRVBase::visitCallLdexp(CallInst *CI, StringRef MangledName,
StringRef DemangledName) {
auto Args = getArguments(CI);
void visitSubgroupAVCBuiltinCallWithSampler(CallInst *CI,
StringRef DemangledName);
+ /// For cl_intel_split_work_group_barrier built-ins:
+ void visitCallSplitBarrierINTEL(CallInst *CI, StringRef DemangledName);
+
void visitCallLdexp(CallInst *CI, StringRef MangledName,
StringRef DemangledName);
_SPIRV_OP(bitfield_extract_signed, BitFieldSExtract)
_SPIRV_OP(bitfield_extract_unsigned, BitFieldUExtract)
_SPIRV_OP(bit_reverse, BitReverse)
+ // cl_khr_split_work_group_barrier
+ _SPIRV_OP(intel_work_group_barrier_arrive, ControlBarrierArriveINTEL)
+ _SPIRV_OP(intel_work_group_barrier_wait, ControlBarrierWaitINTEL)
#undef _SPIRV_OP
}
} else if (NameRef.contains("barrier")) {
addUnsignedArg(0);
if (NameRef.equals("work_group_barrier") ||
- NameRef.equals("sub_group_barrier"))
+ NameRef.equals("sub_group_barrier") ||
+ NameRef.equals("intel_work_group_barrier_arrive") ||
+ NameRef.equals("intel_work_group_barrier_wait"))
setEnumArg(1, SPIR::PRIMITIVE_MEMORY_SCOPE);
} else if (NameRef.startswith("atomic_work_item_fence")) {
addUnsignedArg(0);
"intel_sub_group_block_write";
const static char SubgroupImageMediaBlockINTELPrefix[] =
"intel_sub_group_media_block";
+const static char SplitBarrierINTELPrefix[] = "intel_work_group_barrier_";
const static char LDEXP[] = "ldexp";
#define _SPIRV_OP(x) \
const static char ConvertBFloat16##x##AsUShort##x[] = \
Func->addFnAttr(Attribute::NoUnwind);
auto OC = BI->getOpCode();
if (isGroupOpCode(OC) || isIntelSubgroupOpCode(OC) ||
- OC == OpControlBarrier)
+ isSplitBarrierINTELOpCode(OC) || OC == OpControlBarrier)
Func->addFnAttr(Attribute::Convergent);
}
auto Call =
if (OC == OpControlBarrier) {
visitCallSPIRVControlBarrier(&CI);
}
+ if (isSplitBarrierINTELOpCode(OC)) {
+ visitCallSPIRVSplitBarrierINTEL(&CI, OC);
+ return;
+ }
if (isAtomicOpCode(OC)) {
visitCallSPIRVAtomicBuiltin(&CI, OC);
return;
/// - OCL1.2: barrier
virtual void visitCallSPIRVControlBarrier(CallInst *CI) = 0;
+ /// Transform split __spirv_ControlBarrierArriveINTEL and
+ /// __spirv_ControlBarrierWaitINTEL barrier to:
+ /// - OCL2.0: overload with a memory_scope argument
+ /// - OCL1.2: overload with no memory_scope argument
+ virtual void visitCallSPIRVSplitBarrierINTEL(CallInst *CI, Op OC) = 0;
+
/// Transform __spirv_EnqueueKernel to __enqueue_kernel
virtual void visitCallSPIRVEnqueueKernel(CallInst *CI, Op OC) = 0;
/// barrier(flag(sema))
void visitCallSPIRVControlBarrier(CallInst *CI) override;
+ /// Transform split __spirv_ControlBarrierArriveINTEL and
+ /// __spirv_ControlBarrierWaitINTEL barrier to overloads without a
+ /// memory_scope argument.
+ void visitCallSPIRVSplitBarrierINTEL(CallInst *CI, Op OC) override;
+
/// Transform __spirv_OpAtomic functions. It firstly conduct generic
/// mutations for all builtins and then mutate some of them seperately
Instruction *visitCallSPIRVAtomicBuiltin(CallInst *CI, Op OC) override;
/// sub_group_barrier(flag(sema), map(memScope))
void visitCallSPIRVControlBarrier(CallInst *CI) override;
+ /// Transform split __spirv_ControlBarrierArriveINTEL and
+ /// __spirv_ControlBarrierWaitINTEL barrier to overloads with a
+ /// memory_scope argument.
+ void visitCallSPIRVSplitBarrierINTEL(CallInst *CI, Op OC) override;
+
/// Transform __spirv_Atomic* to atomic_*.
/// __spirv_Atomic*(atomic_op, scope, sema, ops, ...) =>
/// atomic_*(generic atomic_op, ops, ..., order(sema), map(scope))
&Attrs);
}
+void SPIRVToOCL12Base::visitCallSPIRVSplitBarrierINTEL(CallInst *CI, Op OC) {
+ AttributeList Attrs = CI->getCalledFunction()->getAttributes();
+ mutateCallInstOCL(
+ M, CI,
+ [=](CallInst *, std::vector<Value *> &Args) {
+ Value *MemFenceFlags =
+ SPIRV::transSPIRVMemorySemanticsIntoOCLMemFenceFlags(Args[2], CI);
+ Args.assign(1, MemFenceFlags);
+ return OCLSPIRVBuiltinMap::rmap(OC);
+ },
+ &Attrs);
+}
+
Instruction *SPIRVToOCL12Base::visitCallSPIRVAtomicIncDec(CallInst *CI, Op OC) {
AttributeList Attrs = CI->getCalledFunction()->getAttributes();
return mutateCallInstOCL(
&NewAttrs);
}
+void SPIRVToOCL20Base::visitCallSPIRVSplitBarrierINTEL(CallInst *CI, Op OC) {
+ AttributeList Attrs = CI->getCalledFunction()->getAttributes();
+ mutateCallInstOCL(
+ M, CI,
+ [=](CallInst *, std::vector<Value *> &Args) {
+ auto GetArg = [=](unsigned I) {
+ return cast<ConstantInt>(Args[I])->getZExtValue();
+ };
+ Value *MemScope =
+ getInt32(M, rmap<OCLScopeKind>(static_cast<Scope>(GetArg(1))));
+ Value *MemFenceFlags =
+ SPIRV::transSPIRVMemorySemanticsIntoOCLMemFenceFlags(Args[2], CI);
+
+ Args.resize(2);
+ Args[0] = MemFenceFlags;
+ Args[1] = MemScope;
+
+ return OCLSPIRVBuiltinMap::rmap(OC);
+ },
+ &Attrs);
+}
+
std::string SPIRVToOCL20Base::mapFPAtomicName(Op OC) {
assert(isFPAtomicOpCode(OC) && "Not intended to handle other opcodes than "
"AtomicF{Add/Min/Max}EXT!");
_SPIRV_OP(JointMatrixWorkItemLength, true, 4)
#undef _SPIRV_OP
+class SPIRVSplitBarrierINTELBase : public SPIRVInstTemplateBase {
+protected:
+ SPIRVCapVec getRequiredCapability() const override {
+ return getVec(CapabilitySplitBarrierINTEL);
+ }
+
+ llvm::Optional<ExtensionID> getRequiredExtension() const override {
+ return ExtensionID::SPV_INTEL_split_barrier;
+ }
+};
+
+#define _SPIRV_OP(x, ...) \
+ typedef SPIRVInstTemplate<SPIRVSplitBarrierINTELBase, Op##x, __VA_ARGS__> \
+ SPIRV##x;
+_SPIRV_OP(ControlBarrierArriveINTEL, false, 4)
+_SPIRV_OP(ControlBarrierWaitINTEL, false, 4)
+#undef _SPIRV_OP
+
class SPIRVGroupUniformArithmeticKHRInstBase : public SPIRVInstTemplateBase {
public:
SPIRVCapVec getRequiredCapability() const override {
return OpRetainEvent <= OpCode && OpCode <= OpCaptureEventProfilingInfo;
}
+inline bool isSplitBarrierINTELOpCode(Op OpCode) {
+ return OpCode == OpControlBarrierArriveINTEL ||
+ OpCode == OpControlBarrierWaitINTEL;
+}
+
} // namespace SPIRV
#endif // SPIRV_LIBSPIRV_SPIRVOPCODE_H
_SPIRV_OP(TypeStructContinuedINTEL, 6090)
_SPIRV_OP(ConstantCompositeContinuedINTEL, 6091)
_SPIRV_OP(SpecConstantCompositeContinuedINTEL, 6092)
+_SPIRV_OP(ControlBarrierArriveINTEL, 6142)
+_SPIRV_OP(ControlBarrierWaitINTEL, 6143)
_SPIRV_OP(GroupIMulKHR, 6401)
_SPIRV_OP(GroupFMulKHR, 6402)
_SPIRV_OP(GroupBitwiseAndKHR, 6403)
--- /dev/null
+;; kernel void test(global uint* dst)
+;; {
+;; intel_work_group_barrier_arrive(CLK_LOCAL_MEM_FENCE);
+;; intel_work_group_barrier_wait(CLK_LOCAL_MEM_FENCE);
+;; intel_work_group_barrier_arrive(CLK_GLOBAL_MEM_FENCE);
+;; intel_work_group_barrier_wait(CLK_GLOBAL_MEM_FENCE);
+;;
+;; intel_work_group_barrier_arrive(CLK_LOCAL_MEM_FENCE | CLK_GLOBAL_MEM_FENCE);
+;; intel_work_group_barrier_wait(CLK_LOCAL_MEM_FENCE | CLK_GLOBAL_MEM_FENCE);
+;;}
+
+; Test for SPV_INTEL_split_barrier (OpenCL C LLVM IR)
+; RUN: llvm-as %s -o %t.bc
+; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_split_barrier
+; RUN: llvm-spirv %t.spv -o %t.spt --to-text
+; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
+; RUN: llvm-spirv %t.spv -o %t.rev.bc -r --spirv-target-env=CL1.2
+; RUN: llvm-dis %t.rev.bc -o %t.rev.ll
+; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM
+
+; RUN: not llvm-spirv %t.bc 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
+; CHECK-ERROR: RequiresExtension: Feature requires the following SPIR-V extension:
+; CHECK-ERROR-NEXT: SPV_INTEL_split_barrier
+
+; ModuleID = 'split_barrier.cl'
+source_filename = "split_barrier.cl"
+target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
+target triple = "spir64"
+
+; CHECK-SPIRV: Capability SplitBarrierINTEL
+; CHECK-SPIRV: Extension "SPV_INTEL_split_barrier"
+; CHECK-SPIRV: TypeInt [[UINT:[0-9]+]] 32 0
+;
+; Scopes:
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[SCOPE_WORK_GROUP:[0-9]+]] 2
+;
+; Memory Semantics:
+; 0x2 Acquire + 0x100 WorkgroupMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[ACQUIRE_LOCAL:[0-9]+]] 258
+; 0x4 Release + 0x100 WorkgroupMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[RELEASE_LOCAL:[0-9]+]] 260
+; 0x2 Acquire + 0x200 CrossWorkgroupMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[ACQUIRE_GLOBAL:[0-9]+]] 514
+; 0x4 Release + 0x200 CrossWorkgroupMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[RELEASE_GLOBAL:[0-9]+]] 516
+; 0x2 Acquire + 0x100 WorkgroupMemory + 0x200 CrossWorkgroupMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[ACQUIRE_LOCAL_GLOBAL:[0-9]+]] 770
+; 0x4 Release + 0x100 WorkgroupMemory + 0x200 CrossWorkgroupMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[RELEASE_LOCAL_GLOBAL:[0-9]+]] 772
+;
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[RELEASE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[ACQUIRE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[RELEASE_GLOBAL]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[ACQUIRE_GLOBAL]]
+;
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[RELEASE_LOCAL_GLOBAL]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[ACQUIRE_LOCAL_GLOBAL]]
+
+; CHECK-LLVM-LABEL: define spir_kernel void @test
+; Function Attrs: convergent norecurse nounwind
+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 {
+ tail call spir_func void @_Z31intel_work_group_barrier_arrivej(i32 noundef 1) #2
+ ; CHECK-LLVM: call spir_func void @_Z31intel_work_group_barrier_arrivej(i32 1)
+ tail call spir_func void @_Z29intel_work_group_barrier_waitj(i32 noundef 1) #2
+ ; CHECK-LLVM: call spir_func void @_Z29intel_work_group_barrier_waitj(i32 1)
+ tail call spir_func void @_Z31intel_work_group_barrier_arrivej(i32 noundef 2) #2
+ ; CHECK-LLVM: call spir_func void @_Z31intel_work_group_barrier_arrivej(i32 2)
+ tail call spir_func void @_Z29intel_work_group_barrier_waitj(i32 noundef 2) #2
+ ; CHECK-LLVM: call spir_func void @_Z29intel_work_group_barrier_waitj(i32 2)
+ tail call spir_func void @_Z31intel_work_group_barrier_arrivej(i32 noundef 3) #2
+ ; CHECK-LLVM: call spir_func void @_Z31intel_work_group_barrier_arrivej(i32 3)
+ tail call spir_func void @_Z29intel_work_group_barrier_waitj(i32 noundef 3) #2
+ ; CHECK-LLVM: call spir_func void @_Z29intel_work_group_barrier_waitj(i32 3)
+ ret void
+}
+
+; Function Attrs: convergent
+declare dso_local spir_func void @_Z31intel_work_group_barrier_arrivej(i32 noundef) local_unnamed_addr #1
+
+; Function Attrs: convergent
+declare dso_local spir_func void @_Z29intel_work_group_barrier_waitj(i32 noundef) local_unnamed_addr #1
+
+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" }
+attributes #1 = { convergent "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #2 = { convergent nounwind }
+
+!llvm.module.flags = !{!0, !1}
+!opencl.ocl.version = !{!2}
+!opencl.spir.version = !{!2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 7, !"frame-pointer", i32 2}
+!2 = !{i32 1, i32 2}
+!3 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project 861386dbd6ff0d91636b7c674c2abb2eccd9d3f2)"}
+!4 = !{i32 1}
+!5 = !{!"none"}
+!6 = !{!"uint*"}
+!7 = !{!""}
--- /dev/null
+;; kernel void test(global uint* dst)
+;; {
+;; intel_work_group_barrier_arrive(CLK_LOCAL_MEM_FENCE);
+;; intel_work_group_barrier_wait(CLK_LOCAL_MEM_FENCE);
+;; intel_work_group_barrier_arrive(CLK_GLOBAL_MEM_FENCE);
+;; intel_work_group_barrier_wait(CLK_GLOBAL_MEM_FENCE);
+;; intel_work_group_barrier_arrive(CLK_IMAGE_MEM_FENCE);
+;; intel_work_group_barrier_wait(CLK_IMAGE_MEM_FENCE);
+;;
+;; intel_work_group_barrier_arrive(CLK_LOCAL_MEM_FENCE | CLK_GLOBAL_MEM_FENCE);
+;; intel_work_group_barrier_wait(CLK_LOCAL_MEM_FENCE | CLK_GLOBAL_MEM_FENCE);
+;; intel_work_group_barrier_arrive(CLK_LOCAL_MEM_FENCE | CLK_GLOBAL_MEM_FENCE | CLK_IMAGE_MEM_FENCE);
+;; intel_work_group_barrier_wait(CLK_LOCAL_MEM_FENCE | CLK_GLOBAL_MEM_FENCE | CLK_IMAGE_MEM_FENCE);
+;;
+;; intel_work_group_barrier_arrive(CLK_LOCAL_MEM_FENCE, memory_scope_work_item);
+;; intel_work_group_barrier_wait(CLK_LOCAL_MEM_FENCE, memory_scope_work_item);
+;; intel_work_group_barrier_arrive(CLK_LOCAL_MEM_FENCE, memory_scope_work_group);
+;; intel_work_group_barrier_wait(CLK_LOCAL_MEM_FENCE, memory_scope_work_group);
+;; intel_work_group_barrier_arrive(CLK_LOCAL_MEM_FENCE, memory_scope_device);
+;; intel_work_group_barrier_wait(CLK_LOCAL_MEM_FENCE, memory_scope_device);
+;; intel_work_group_barrier_arrive(CLK_LOCAL_MEM_FENCE, memory_scope_all_svm_devices);
+;; intel_work_group_barrier_wait(CLK_LOCAL_MEM_FENCE, memory_scope_all_svm_devices);
+;; intel_work_group_barrier_arrive(CLK_LOCAL_MEM_FENCE, memory_scope_sub_group);
+;; intel_work_group_barrier_wait(CLK_LOCAL_MEM_FENCE, memory_scope_sub_group);
+;;}
+
+; Test for SPV_INTEL_split_barrier (OpenCL C LLVM IR)
+; RUN: llvm-as %s -o %t.bc
+; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_split_barrier
+; RUN: llvm-spirv %t.spv -o %t.spt --to-text
+; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
+; RUN: llvm-spirv %t.spv -o %t.rev.bc -r --spirv-target-env=CL2.0
+; RUN: llvm-dis %t.rev.bc -o %t.rev.ll
+; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM
+
+; RUN: not llvm-spirv %t.bc 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
+; CHECK-ERROR: RequiresExtension: Feature requires the following SPIR-V extension:
+; CHECK-ERROR-NEXT: SPV_INTEL_split_barrier
+
+; ModuleID = 'split_barrier.cl'
+source_filename = "split_barrier.cl"
+target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
+target triple = "spir64"
+
+; CHECK-SPIRV: Capability SplitBarrierINTEL
+; CHECK-SPIRV: Extension "SPV_INTEL_split_barrier"
+; CHECK-SPIRV: TypeInt [[UINT:[0-9]+]] 32 0
+;
+; Scopes:
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[SCOPE_WORK_GROUP:[0-9]+]] 2
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[SCOPE_INVOCATION:[0-9]+]] 4
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[SCOPE_DEVICE:[0-9]+]] 1
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[SCOPE_CROSS_DEVICE:[0-9]+]] 0
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[SCOPE_SUBGROUP:[0-9]+]] 3
+;
+; Memory Semantics:
+; 0x2 Acquire + 0x100 WorkgroupMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[ACQUIRE_LOCAL:[0-9]+]] 258
+; 0x4 Release + 0x100 WorkgroupMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[RELEASE_LOCAL:[0-9]+]] 260
+; 0x2 Acquire + 0x200 CrossWorkgroupMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[ACQUIRE_GLOBAL:[0-9]+]] 514
+; 0x4 Release + 0x200 CrossWorkgroupMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[RELEASE_GLOBAL:[0-9]+]] 516
+; 0x2 Acquire + 0x800 ImageMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[ACQUIRE_IMAGE:[0-9]+]] 2050
+; 0x4 Acquire + 0x800 ImageMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[RELEASE_IMAGE:[0-9]+]] 2052
+; 0x2 Acquire + 0x100 WorkgroupMemory + 0x200 CrossWorkgroupMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[ACQUIRE_LOCAL_GLOBAL:[0-9]+]] 770
+; 0x4 Release + 0x100 WorkgroupMemory + 0x200 CrossWorkgroupMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[RELEASE_LOCAL_GLOBAL:[0-9]+]] 772
+; 0x2 Acquire + 0x100 WorkgroupMemory + 0x200 CrossWorkgroupMemory + 0x800 ImageMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[ACQUIRE_LOCAL_GLOBAL_IMAGE:[0-9]+]] 2818
+; 0x4 Release + 0x100 WorkgroupMemory + 0x200 CrossWorkgroupMemory + 0x800 ImageMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[RELEASE_LOCAL_GLOBAL_IMAGE:[0-9]+]] 2820
+;
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[RELEASE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[ACQUIRE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[RELEASE_GLOBAL]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[ACQUIRE_GLOBAL]]
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[RELEASE_IMAGE]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[ACQUIRE_IMAGE]]
+;
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[RELEASE_LOCAL_GLOBAL]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[ACQUIRE_LOCAL_GLOBAL]]
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[RELEASE_LOCAL_GLOBAL_IMAGE]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[ACQUIRE_LOCAL_GLOBAL_IMAGE]]
+;
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_INVOCATION]] [[RELEASE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_INVOCATION]] [[ACQUIRE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[RELEASE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[ACQUIRE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_DEVICE]] [[RELEASE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_DEVICE]] [[ACQUIRE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_CROSS_DEVICE]] [[RELEASE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_CROSS_DEVICE]] [[ACQUIRE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_SUBGROUP]] [[RELEASE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_SUBGROUP]] [[ACQUIRE_LOCAL]]
+
+; CHECK-LLVM-LABEL: define spir_kernel void @test
+; Function Attrs: convergent norecurse nounwind
+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 {
+ tail call spir_func void @_Z31intel_work_group_barrier_arrivej(i32 noundef 1) #2
+ ; CHECK-LLVM: call spir_func void @_Z31intel_work_group_barrier_arrivej12memory_scope(i32 1, i32 1)
+ tail call spir_func void @_Z29intel_work_group_barrier_waitj(i32 noundef 1) #2
+ ; CHECK-LLVM: call spir_func void @_Z29intel_work_group_barrier_waitj12memory_scope(i32 1, i32 1)
+ tail call spir_func void @_Z31intel_work_group_barrier_arrivej(i32 noundef 2) #2
+ ; CHECK-LLVM: call spir_func void @_Z31intel_work_group_barrier_arrivej12memory_scope(i32 2, i32 1)
+ tail call spir_func void @_Z29intel_work_group_barrier_waitj(i32 noundef 2) #2
+ ; CHECK-LLVM: call spir_func void @_Z29intel_work_group_barrier_waitj12memory_scope(i32 2, i32 1)
+ tail call spir_func void @_Z31intel_work_group_barrier_arrivej(i32 noundef 4) #2
+ ; CHECK-LLVM: call spir_func void @_Z31intel_work_group_barrier_arrivej12memory_scope(i32 4, i32 1)
+ tail call spir_func void @_Z29intel_work_group_barrier_waitj(i32 noundef 4) #2
+ ; CHECK-LLVM: call spir_func void @_Z29intel_work_group_barrier_waitj12memory_scope(i32 4, i32 1)
+ tail call spir_func void @_Z31intel_work_group_barrier_arrivej(i32 noundef 3) #2
+ ; CHECK-LLVM: call spir_func void @_Z31intel_work_group_barrier_arrivej12memory_scope(i32 3, i32 1)
+ tail call spir_func void @_Z29intel_work_group_barrier_waitj(i32 noundef 3) #2
+ ; CHECK-LLVM: call spir_func void @_Z29intel_work_group_barrier_waitj12memory_scope(i32 3, i32 1)
+ tail call spir_func void @_Z31intel_work_group_barrier_arrivej(i32 noundef 7) #2
+ ; CHECK-LLVM: call spir_func void @_Z31intel_work_group_barrier_arrivej12memory_scope(i32 7, i32 1)
+ tail call spir_func void @_Z29intel_work_group_barrier_waitj(i32 noundef 7) #2
+ ; CHECK-LLVM: call spir_func void @_Z29intel_work_group_barrier_waitj12memory_scope(i32 7, i32 1)
+ tail call spir_func void @_Z31intel_work_group_barrier_arrivej12memory_scope(i32 noundef 1, i32 noundef 0) #2
+ ; CHECK-LLVM: call spir_func void @_Z31intel_work_group_barrier_arrivej12memory_scope(i32 1, i32 0)
+ tail call spir_func void @_Z29intel_work_group_barrier_waitj12memory_scope(i32 noundef 1, i32 noundef 0) #2
+ ; CHECK-LLVM: call spir_func void @_Z29intel_work_group_barrier_waitj12memory_scope(i32 1, i32 0)
+ tail call spir_func void @_Z31intel_work_group_barrier_arrivej12memory_scope(i32 noundef 1, i32 noundef 1) #2
+ ; CHECK-LLVM: call spir_func void @_Z31intel_work_group_barrier_arrivej12memory_scope(i32 1, i32 1)
+ tail call spir_func void @_Z29intel_work_group_barrier_waitj12memory_scope(i32 noundef 1, i32 noundef 1) #2
+ ; CHECK-LLVM: call spir_func void @_Z29intel_work_group_barrier_waitj12memory_scope(i32 1, i32 1)
+ tail call spir_func void @_Z31intel_work_group_barrier_arrivej12memory_scope(i32 noundef 1, i32 noundef 2) #2
+ ; CHECK-LLVM: call spir_func void @_Z31intel_work_group_barrier_arrivej12memory_scope(i32 1, i32 2)
+ tail call spir_func void @_Z29intel_work_group_barrier_waitj12memory_scope(i32 noundef 1, i32 noundef 2) #2
+ ; CHECK-LLVM: call spir_func void @_Z29intel_work_group_barrier_waitj12memory_scope(i32 1, i32 2)
+ tail call spir_func void @_Z31intel_work_group_barrier_arrivej12memory_scope(i32 noundef 1, i32 noundef 3) #2
+ ; CHECK-LLVM: call spir_func void @_Z31intel_work_group_barrier_arrivej12memory_scope(i32 1, i32 3)
+ tail call spir_func void @_Z29intel_work_group_barrier_waitj12memory_scope(i32 noundef 1, i32 noundef 3) #2
+ ; CHECK-LLVM: call spir_func void @_Z29intel_work_group_barrier_waitj12memory_scope(i32 1, i32 3)
+ tail call spir_func void @_Z31intel_work_group_barrier_arrivej12memory_scope(i32 noundef 1, i32 noundef 4) #2
+ ; CHECK-LLVM: call spir_func void @_Z31intel_work_group_barrier_arrivej12memory_scope(i32 1, i32 4)
+ tail call spir_func void @_Z29intel_work_group_barrier_waitj12memory_scope(i32 noundef 1, i32 noundef 4) #2
+ ; CHECK-LLVM: call spir_func void @_Z29intel_work_group_barrier_waitj12memory_scope(i32 1, i32 4)
+ ret void
+}
+
+; Function Attrs: convergent
+declare dso_local spir_func void @_Z31intel_work_group_barrier_arrivej(i32 noundef) local_unnamed_addr #1
+
+; Function Attrs: convergent
+declare dso_local spir_func void @_Z29intel_work_group_barrier_waitj(i32 noundef) local_unnamed_addr #1
+
+; Function Attrs: convergent
+declare dso_local spir_func void @_Z31intel_work_group_barrier_arrivej12memory_scope(i32 noundef, i32 noundef) local_unnamed_addr #1
+
+; Function Attrs: convergent
+declare dso_local spir_func void @_Z29intel_work_group_barrier_waitj12memory_scope(i32 noundef, i32 noundef) local_unnamed_addr #1
+
+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"="false" }
+attributes #1 = { convergent "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #2 = { convergent nounwind }
+
+!llvm.module.flags = !{!0, !1}
+!opencl.ocl.version = !{!2}
+!opencl.spir.version = !{!2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 7, !"frame-pointer", i32 2}
+!2 = !{i32 2, i32 0}
+!3 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project 861386dbd6ff0d91636b7c674c2abb2eccd9d3f2)"}
+!4 = !{i32 1}
+!5 = !{!"none"}
+!6 = !{!"uint*"}
+!7 = !{!""}
--- /dev/null
+;; kernel void test(global uint* dst)
+;; {
+;; __spirv_ControlBarrierArriveINTEL(2, 2, 260); // local
+;; __spirv_ControlBarrierWaitINTEL(2, 2, 258); // local
+;; __spirv_ControlBarrierArriveINTEL(2, 2, 516); // global
+;; __spirv_ControlBarrierWaitINTEL(2, 2, 514); // global
+;; __spirv_ControlBarrierArriveINTEL(2, 2, 2052); // image
+;; __spirv_ControlBarrierWaitINTEL(2, 2, 2050); // image
+;;
+;; __spirv_ControlBarrierArriveINTEL(2, 2, 772); // local + global
+;; __spirv_ControlBarrierWaitINTEL(2, 2, 770); // local + global
+;; __spirv_ControlBarrierArriveINTEL(2, 2, 2820); // local + global + image
+;; __spirv_ControlBarrierWaitINTEL(2, 2, 2818); // local + global + image
+;;
+;; __spirv_ControlBarrierArriveINTEL(2, 4, 260); // local, work_item
+;; __spirv_ControlBarrierWaitINTEL(2, 4, 258); // local, work_item
+;; __spirv_ControlBarrierArriveINTEL(2, 2, 260); // local, work_group
+;; __spirv_ControlBarrierWaitINTEL(2, 2, 258); // local, work_group
+;; __spirv_ControlBarrierArriveINTEL(2, 1, 260); // local, device
+;; __spirv_ControlBarrierWaitINTEL(2, 1, 258); // local, device
+;; __spirv_ControlBarrierArriveINTEL(2, 0, 260); // local, all_svm_devices
+;; __spirv_ControlBarrierWaitINTEL(2, 0, 258); // local, all_svm_devices
+;; __spirv_ControlBarrierArriveINTEL(2, 3, 260); // local, subgroup
+;; __spirv_ControlBarrierWaitINTEL(2, 3, 258); // local, subgroup
+;;}
+
+; Test for SPV_INTEL_split_barrier (SPIR-V friendly LLVM IR)
+; RUN: llvm-as %s -o %t.bc
+; RUN: llvm-spirv %t.bc -o %t.spv --spirv-ext=+SPV_INTEL_split_barrier
+; RUN: llvm-spirv %t.spv -o %t.spt --to-text
+; RUN: FileCheck < %t.spt %s --check-prefix=CHECK-SPIRV
+
+; RUN: llvm-spirv %t.spv -o %t.rev.bc -r --spirv-target-env=SPV-IR
+; RUN: llvm-dis %t.rev.bc -o %t.rev.ll
+; RUN: FileCheck < %t.rev.ll %s --check-prefix=CHECK-LLVM
+
+; RUN: not llvm-spirv %t.bc 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
+; CHECK-ERROR: RequiresExtension: Feature requires the following SPIR-V extension:
+; CHECK-ERROR-NEXT: SPV_INTEL_split_barrier
+
+; ModuleID = 'split_barrier_spirv.cl'
+source_filename = "split_barrier_spirv.cl"
+target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
+target triple = "spir64"
+
+; CHECK-SPIRV: Capability SplitBarrierINTEL
+; CHECK-SPIRV: Extension "SPV_INTEL_split_barrier"
+; CHECK-SPIRV: TypeInt [[UINT:[0-9]+]] 32 0
+;
+; Scopes:
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[SCOPE_WORK_GROUP:[0-9]+]] 2
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[SCOPE_INVOCATION:[0-9]+]] 4
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[SCOPE_DEVICE:[0-9]+]] 1
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[SCOPE_CROSS_DEVICE:[0-9]+]] 0
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[SCOPE_SUBGROUP:[0-9]+]] 3
+;
+; Memory Semantics:
+; 0x2 Acquire + 0x100 WorkgroupMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[ACQUIRE_LOCAL:[0-9]+]] 258
+; 0x4 Release + 0x100 WorkgroupMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[RELEASE_LOCAL:[0-9]+]] 260
+; 0x2 Acquire + 0x200 CrossWorkgroupMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[ACQUIRE_GLOBAL:[0-9]+]] 514
+; 0x4 Release + 0x200 CrossWorkgroupMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[RELEASE_GLOBAL:[0-9]+]] 516
+; 0x2 Acquire + 0x800 ImageMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[ACQUIRE_IMAGE:[0-9]+]] 2050
+; 0x4 Acquire + 0x800 ImageMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[RELEASE_IMAGE:[0-9]+]] 2052
+; 0x2 Acquire + 0x100 WorkgroupMemory + 0x200 CrossWorkgroupMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[ACQUIRE_LOCAL_GLOBAL:[0-9]+]] 770
+; 0x4 Release + 0x100 WorkgroupMemory + 0x200 CrossWorkgroupMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[RELEASE_LOCAL_GLOBAL:[0-9]+]] 772
+; 0x2 Acquire + 0x100 WorkgroupMemory + 0x200 CrossWorkgroupMemory + 0x800 ImageMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[ACQUIRE_LOCAL_GLOBAL_IMAGE:[0-9]+]] 2818
+; 0x4 Release + 0x100 WorkgroupMemory + 0x200 CrossWorkgroupMemory + 0x800 ImageMemory
+; CHECK-SPIRV-DAG: Constant [[UINT]] [[RELEASE_LOCAL_GLOBAL_IMAGE:[0-9]+]] 2820
+;
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[RELEASE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[ACQUIRE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[RELEASE_GLOBAL]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[ACQUIRE_GLOBAL]]
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[RELEASE_IMAGE]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[ACQUIRE_IMAGE]]
+;
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[RELEASE_LOCAL_GLOBAL]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[ACQUIRE_LOCAL_GLOBAL]]
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[RELEASE_LOCAL_GLOBAL_IMAGE]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[ACQUIRE_LOCAL_GLOBAL_IMAGE]]
+;
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_INVOCATION]] [[RELEASE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_INVOCATION]] [[ACQUIRE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[RELEASE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_WORK_GROUP]] [[ACQUIRE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_DEVICE]] [[RELEASE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_DEVICE]] [[ACQUIRE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_CROSS_DEVICE]] [[RELEASE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_CROSS_DEVICE]] [[ACQUIRE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierArriveINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_SUBGROUP]] [[RELEASE_LOCAL]]
+; CHECK-SPIRV: ControlBarrierWaitINTEL [[SCOPE_WORK_GROUP]] [[SCOPE_SUBGROUP]] [[ACQUIRE_LOCAL]]
+
+; CHECK-LLVM-LABEL: define spir_kernel void @test
+; Function Attrs: convergent norecurse nounwind
+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 {
+ tail call spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 noundef 2, i32 noundef 2, i32 noundef 260) #2
+ ; CHECK-LLVM: call spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 2, i32 2, i32 260) #1
+ tail call spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 noundef 2, i32 noundef 2, i32 noundef 258) #2
+ ; CHECK-LLVM: call spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 2, i32 2, i32 258) #1
+ tail call spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 noundef 2, i32 noundef 2, i32 noundef 516) #2
+ ; CHECK-LLVM: call spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 2, i32 2, i32 516) #1
+ tail call spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 noundef 2, i32 noundef 2, i32 noundef 514) #2
+ ; CHECK-LLVM: call spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 2, i32 2, i32 514) #1
+ tail call spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 noundef 2, i32 noundef 2, i32 noundef 2052) #2
+ ; CHECK-LLVM: call spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 2, i32 2, i32 2052) #1
+ tail call spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 noundef 2, i32 noundef 2, i32 noundef 2050) #2
+ ; CHECK-LLVM: call spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 2, i32 2, i32 2050) #1
+ tail call spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 noundef 2, i32 noundef 2, i32 noundef 772) #2
+ ; CHECK-LLVM: call spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 2, i32 2, i32 772) #1
+ tail call spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 noundef 2, i32 noundef 2, i32 noundef 770) #2
+ ; CHECK-LLVM: call spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 2, i32 2, i32 770) #1
+ tail call spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 noundef 2, i32 noundef 2, i32 noundef 2820) #2
+ ; CHECK-LLVM: call spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 2, i32 2, i32 2820) #1
+ tail call spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 noundef 2, i32 noundef 2, i32 noundef 2818) #2
+ ; CHECK-LLVM: call spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 2, i32 2, i32 2818) #1
+ tail call spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 noundef 2, i32 noundef 4, i32 noundef 260) #2
+ ; CHECK-LLVM: call spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 2, i32 4, i32 260) #1
+ tail call spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 noundef 2, i32 noundef 4, i32 noundef 258) #2
+ ; CHECK-LLVM: call spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 2, i32 4, i32 258) #1
+ tail call spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 noundef 2, i32 noundef 2, i32 noundef 260) #2
+ ; CHECK-LLVM: call spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 2, i32 2, i32 260) #1
+ tail call spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 noundef 2, i32 noundef 2, i32 noundef 258) #2
+ ; CHECK-LLVM: call spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 2, i32 2, i32 258) #1
+ tail call spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 noundef 2, i32 noundef 1, i32 noundef 260) #2
+ ; CHECK-LLVM: call spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 2, i32 1, i32 260) #1
+ tail call spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 noundef 2, i32 noundef 1, i32 noundef 258) #2
+ ; CHECK-LLVM: call spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 2, i32 1, i32 258) #1
+ tail call spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 noundef 2, i32 noundef 0, i32 noundef 260) #2
+ ; CHECK-LLVM: call spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 2, i32 0, i32 260) #1
+ tail call spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 noundef 2, i32 noundef 0, i32 noundef 258) #2
+ ; CHECK-LLVM: call spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 2, i32 0, i32 258) #1
+ tail call spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 noundef 2, i32 noundef 3, i32 noundef 260) #2
+ ; CHECK-LLVM: call spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 2, i32 3, i32 260) #1
+ tail call spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 noundef 2, i32 noundef 3, i32 noundef 258) #2
+ ; CHECK-LLVM: call spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 2, i32 3, i32 258) #1
+ ret void
+}
+
+; Function Attrs: convergent
+declare dso_local spir_func void @_Z33__spirv_ControlBarrierArriveINTELiii(i32 noundef, i32 noundef, i32 noundef) local_unnamed_addr #1
+
+; Function Attrs: convergent
+declare dso_local spir_func void @_Z31__spirv_ControlBarrierWaitINTELiii(i32 noundef, i32 noundef, i32 noundef) local_unnamed_addr #1
+
+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"="false" }
+attributes #1 = { convergent "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #2 = { convergent nounwind }
+
+!llvm.module.flags = !{!0, !1}
+!opencl.ocl.version = !{!2}
+!opencl.spir.version = !{!2}
+!llvm.ident = !{!3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 7, !"frame-pointer", i32 2}
+!2 = !{i32 2, i32 0}
+!3 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project 861386dbd6ff0d91636b7c674c2abb2eccd9d3f2)"}
+!4 = !{i32 1}
+!5 = !{!"none"}
+!6 = !{!"uint*"}
+!7 = !{!""}