diff --git a/patches/spirv/0002-Add-support-for-split-barriers-extension-SPV_INTEL_s.patch b/patches/spirv/0002-Add-support-for-split-barriers-extension-SPV_INTEL_s.patch new file mode 100644 index 00000000..e3482f39 --- /dev/null +++ b/patches/spirv/0002-Add-support-for-split-barriers-extension-SPV_INTEL_s.patch @@ -0,0 +1,794 @@ +From 296d49b2f6579f1480585c4655ccd711a9c4986d Mon Sep 17 00:00:00 2001 +From: haonanya +Date: Mon, 28 Feb 2022 22:50:20 +0800 +Subject: [PATCH] Add support for split barriers extension + SPV_INTEL_split_barrier + +Signed-off-by: haonanya +--- + include/LLVMSPIRVExtensions.inc | 1 + + lib/SPIRV/OCLToSPIRV.cpp | 37 ++++ + lib/SPIRV/OCLUtil.cpp | 7 +- + lib/SPIRV/OCLUtil.h | 1 + + lib/SPIRV/SPIRVReader.cpp | 3 +- + lib/SPIRV/SPIRVToOCL.cpp | 4 + + lib/SPIRV/SPIRVToOCL.h | 5 + + lib/SPIRV/SPIRVToOCL12.cpp | 17 ++ + lib/SPIRV/SPIRVToOCL20.cpp | 26 +++ + lib/SPIRV/libSPIRV/SPIRVInstruction.h | 19 ++ + lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h | 1 + + lib/SPIRV/libSPIRV/SPIRVOpCode.h | 5 + + lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h | 2 + + .../split_work_group_barrier_12.ll | 99 ++++++++++ + .../split_work_group_barrier_20.ll | 175 ++++++++++++++++++ + .../split_work_group_barrier_spirv.ll | 170 +++++++++++++++++ + 16 files changed, 570 insertions(+), 2 deletions(-) + create mode 100644 test/transcoding/SPV_INTEL_split_barrier/split_work_group_barrier_12.ll + create mode 100644 test/transcoding/SPV_INTEL_split_barrier/split_work_group_barrier_20.ll + create mode 100644 test/transcoding/SPV_INTEL_split_barrier/split_work_group_barrier_spirv.ll + +diff --git a/include/LLVMSPIRVExtensions.inc b/include/LLVMSPIRVExtensions.inc +index 74ba7827..262737b9 100644 +--- a/include/LLVMSPIRVExtensions.inc ++++ b/include/LLVMSPIRVExtensions.inc +@@ -37,3 +37,4 @@ EXT(SPV_INTEL_loop_fuse) + EXT(SPV_INTEL_long_constant_composite) + EXT(SPV_INTEL_optnone) + EXT(SPV_INTEL_memory_access_aliasing) ++EXT(SPV_INTEL_split_barrier) +diff --git a/lib/SPIRV/OCLToSPIRV.cpp b/lib/SPIRV/OCLToSPIRV.cpp +index 9f6e214d..d003a1d0 100644 +--- a/lib/SPIRV/OCLToSPIRV.cpp ++++ b/lib/SPIRV/OCLToSPIRV.cpp +@@ -263,6 +263,8 @@ public: + StringRef DemangledName); + 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); +@@ -527,6 +529,10 @@ void OCLToSPIRV::visitCallInst(CallInst &CI) { + 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 +@@ -1847,6 +1853,37 @@ void OCLToSPIRV::visitSubgroupAVCBuiltinCallWithSampler( + &Attrs); + } + ++void OCLToSPIRV::visitCallSplitBarrierINTEL(CallInst *CI, ++ StringRef DemangledName) { ++ auto Lit = getBarrierLiterals(CI); ++ AttributeList Attrs = CI->getCalledFunction()->getAttributes(); ++ Op OpCode = ++ StringSwitch(DemangledName) ++ .Case("intel_work_group_barrier_arrive", OpControlBarrierArriveINTEL) ++ .Case("intel_work_group_barrier_wait", OpControlBarrierWaitINTEL) ++ .Default(OpNop); ++ ++ mutateCallInstSPIRV( ++ M, CI, ++ [=](CallInst *, std::vector &Args) { ++ Args.resize(3); ++ // Execution scope ++ Args[0] = addInt32(map(std::get<2>(Lit))); ++ // Memory scope ++ Args[1] = addInt32(map(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 OCLToSPIRV::visitCallLdexp(CallInst *CI, StringRef MangledName, + StringRef DemangledName) { + auto Args = getArguments(CI); +diff --git a/lib/SPIRV/OCLUtil.cpp b/lib/SPIRV/OCLUtil.cpp +index b74a1d7b..4dfad287 100644 +--- a/lib/SPIRV/OCLUtil.cpp ++++ b/lib/SPIRV/OCLUtil.cpp +@@ -414,6 +414,9 @@ template <> void SPIRVMap::init() { + // cl_khr_subgroup_shuffle_relative + _SPIRV_OP(group_shuffle_up, GroupNonUniformShuffleUp) + _SPIRV_OP(group_shuffle_down, GroupNonUniformShuffleDown) ++ // 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 + } + +@@ -1019,7 +1022,9 @@ public: + } 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); +diff --git a/lib/SPIRV/OCLUtil.h b/lib/SPIRV/OCLUtil.h +index 0283f407..04093ff8 100644 +--- a/lib/SPIRV/OCLUtil.h ++++ b/lib/SPIRV/OCLUtil.h +@@ -294,6 +294,7 @@ const static char SubgroupBlockWriteINTELPrefix[] = + "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"; + } // namespace kOCLBuiltinName + +diff --git a/lib/SPIRV/SPIRVReader.cpp b/lib/SPIRV/SPIRVReader.cpp +index 7f682224..b9404613 100644 +--- a/lib/SPIRV/SPIRVReader.cpp ++++ b/lib/SPIRV/SPIRVReader.cpp +@@ -2796,7 +2796,8 @@ Instruction *SPIRVToLLVM::transBuiltinFromInst(const std::string &FuncName, + if (isFuncNoUnwind()) + Func->addFnAttr(Attribute::NoUnwind); + auto OC = BI->getOpCode(); +- if (isGroupOpCode(OC) || isIntelSubgroupOpCode(OC)) ++ if (isGroupOpCode(OC) || isIntelSubgroupOpCode(OC) || ++ isSplitBarrierINTELOpCode(OC)) + Func->addFnAttr(Attribute::Convergent); + } + auto Call = +diff --git a/lib/SPIRV/SPIRVToOCL.cpp b/lib/SPIRV/SPIRVToOCL.cpp +index 011eb531..c3922bc3 100644 +--- a/lib/SPIRV/SPIRVToOCL.cpp ++++ b/lib/SPIRV/SPIRVToOCL.cpp +@@ -107,6 +107,10 @@ void SPIRVToOCL::visitCallInst(CallInst &CI) { + if (OC == OpControlBarrier) { + visitCallSPIRVControlBarrier(&CI); + } ++ if (isSplitBarrierINTELOpCode(OC)) { ++ visitCallSPIRVSplitBarrierINTEL(&CI, OC); ++ return; ++ } + if (isAtomicOpCode(OC)) { + visitCallSPIRVAtomicBuiltin(&CI, OC); + return; +diff --git a/lib/SPIRV/SPIRVToOCL.h b/lib/SPIRV/SPIRVToOCL.h +index 83aef320..2821dcd7 100644 +--- a/lib/SPIRV/SPIRVToOCL.h ++++ b/lib/SPIRV/SPIRVToOCL.h +@@ -210,6 +210,11 @@ public: + /// - OCL1.2: barrier + virtual void visitCallSPIRVControlBarrier(CallInst *CI) = 0; + ++ /// Transform split __spirv_ControlBarrier 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; + +diff --git a/lib/SPIRV/SPIRVToOCL12.cpp b/lib/SPIRV/SPIRVToOCL12.cpp +index e3aadb62..a766b793 100644 +--- a/lib/SPIRV/SPIRVToOCL12.cpp ++++ b/lib/SPIRV/SPIRVToOCL12.cpp +@@ -60,6 +60,10 @@ public: + /// barrier(flag(sema)) + void visitCallSPIRVControlBarrier(CallInst *CI) override; + ++ /// Transform split __spirv_ControlBarrier barrier to overloads with 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; +@@ -168,6 +172,19 @@ void SPIRVToOCL12::visitCallSPIRVControlBarrier(CallInst *CI) { + &Attrs); + } + ++void SPIRVToOCL12::visitCallSPIRVSplitBarrierINTEL(CallInst *CI, Op OC) { ++ AttributeList Attrs = CI->getCalledFunction()->getAttributes(); ++ mutateCallInstOCL( ++ M, CI, ++ [=](CallInst *, std::vector &Args) { ++ Value *MemFenceFlags = ++ SPIRV::transSPIRVMemorySemanticsIntoOCLMemFenceFlags(Args[2], CI); ++ Args.assign(1, MemFenceFlags); ++ return OCLSPIRVBuiltinMap::rmap(OC); ++ }, ++ &Attrs); ++} ++ + Instruction *SPIRVToOCL12::visitCallSPIRVAtomicIncDec(CallInst *CI, Op OC) { + AttributeList Attrs = CI->getCalledFunction()->getAttributes(); + return mutateCallInstOCL( +diff --git a/lib/SPIRV/SPIRVToOCL20.cpp b/lib/SPIRV/SPIRVToOCL20.cpp +index c65d7db4..6c416023 100644 +--- a/lib/SPIRV/SPIRVToOCL20.cpp ++++ b/lib/SPIRV/SPIRVToOCL20.cpp +@@ -64,6 +64,10 @@ public: + /// sub_group_barrier(flag(sema), map(memScope)) + void visitCallSPIRVControlBarrier(CallInst *CI) override; + ++ /// Transform split __spirv_ControlBarrier barrier to overloads without 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)) +@@ -167,6 +171,28 @@ void SPIRVToOCL20::visitCallSPIRVControlBarrier(CallInst *CI) { + &Attrs); + } + ++void SPIRVToOCL20::visitCallSPIRVSplitBarrierINTEL(CallInst *CI, Op OC) { ++ AttributeList Attrs = CI->getCalledFunction()->getAttributes(); ++ mutateCallInstOCL( ++ M, CI, ++ [=](CallInst *, std::vector &Args) { ++ auto GetArg = [=](unsigned I) { ++ return cast(Args[I])->getZExtValue(); ++ }; ++ Value *MemScope = ++ getInt32(M, rmap(static_cast(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 SPIRVToOCL20::mapFPAtomicName(Op OC) { + assert(isFPAtomicOpCode(OC) && "Not intended to handle other opcodes than " + "AtomicF{Add/Min/Max}EXT!"); +diff --git a/lib/SPIRV/libSPIRV/SPIRVInstruction.h b/lib/SPIRV/libSPIRV/SPIRVInstruction.h +index 46bf852c..77ce05eb 100644 +--- a/lib/SPIRV/libSPIRV/SPIRVInstruction.h ++++ b/lib/SPIRV/libSPIRV/SPIRVInstruction.h +@@ -3278,6 +3278,25 @@ _SPIRV_OP(VariableLengthArray, true, 4) + _SPIRV_OP(SaveMemory, true, 3) + _SPIRV_OP(RestoreMemory, false, 2) + #undef _SPIRV_OP ++ ++class SPIRVSplitBarrierINTELBase : public SPIRVInstTemplateBase { ++protected: ++ SPIRVCapVec getRequiredCapability() const override { ++ return getVec(CapabilitySplitBarrierINTEL); ++ } ++ ++ llvm::Optional getRequiredExtension() const override { ++ return ExtensionID::SPV_INTEL_split_barrier; ++ } ++}; ++ ++#define _SPIRV_OP(x, ...) \ ++ typedef SPIRVInstTemplate \ ++ SPIRV##x; ++_SPIRV_OP(ControlBarrierArriveINTEL, false, 4) ++_SPIRV_OP(ControlBarrierWaitINTEL, false, 4) ++#undef _SPIRV_OP ++ + } // namespace SPIRV + + #endif // SPIRV_LIBSPIRV_SPIRVINSTRUCTION_H +diff --git a/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h b/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h +index 1734cbd3..e05b0de1 100644 +--- a/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h ++++ b/lib/SPIRV/libSPIRV/SPIRVNameMapEnum.h +@@ -527,6 +527,7 @@ template <> inline void SPIRVMap::init() { + add(internal::CapabilityOptNoneINTEL, "OptNoneINTEL"); + add(internal::CapabilityMemoryAccessAliasingINTEL, + "MemoryAccessAliasingINTEL"); ++ add(CapabilitySplitBarrierINTEL, "SplitBarrierINTEL"); + } + SPIRV_DEF_NAMEMAP(Capability, SPIRVCapabilityNameMap) + +diff --git a/lib/SPIRV/libSPIRV/SPIRVOpCode.h b/lib/SPIRV/libSPIRV/SPIRVOpCode.h +index a4cfe2a8..d0423e88 100644 +--- a/lib/SPIRV/libSPIRV/SPIRVOpCode.h ++++ b/lib/SPIRV/libSPIRV/SPIRVOpCode.h +@@ -244,6 +244,11 @@ inline bool isEventOpCode(Op OpCode) { + return OpRetainEvent <= OpCode && OpCode <= OpCaptureEventProfilingInfo; + } + ++inline bool isSplitBarrierINTELOpCode(Op OpCode) { ++ return OpCode == OpControlBarrierArriveINTEL || ++ OpCode == OpControlBarrierWaitINTEL; ++} ++ + } // namespace SPIRV + + #endif // SPIRV_LIBSPIRV_SPIRVOPCODE_H +diff --git a/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h b/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h +index df0242f1..f902f624 100644 +--- a/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h ++++ b/lib/SPIRV/libSPIRV/SPIRVOpCodeEnum.h +@@ -541,3 +541,5 @@ _SPIRV_OP(TypeBufferSurfaceINTEL, 6086) + _SPIRV_OP(TypeStructContinuedINTEL, 6090) + _SPIRV_OP(ConstantCompositeContinuedINTEL, 6091) + _SPIRV_OP(SpecConstantCompositeContinuedINTEL, 6092) ++_SPIRV_OP(ControlBarrierArriveINTEL, 6142) ++_SPIRV_OP(ControlBarrierWaitINTEL, 6143) +diff --git a/test/transcoding/SPV_INTEL_split_barrier/split_work_group_barrier_12.ll b/test/transcoding/SPV_INTEL_split_barrier/split_work_group_barrier_12.ll +new file mode 100644 +index 00000000..8ab1e85c +--- /dev/null ++++ b/test/transcoding/SPV_INTEL_split_barrier/split_work_group_barrier_12.ll +@@ -0,0 +1,99 @@ ++;; 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 = !{!""} +diff --git a/test/transcoding/SPV_INTEL_split_barrier/split_work_group_barrier_20.ll b/test/transcoding/SPV_INTEL_split_barrier/split_work_group_barrier_20.ll +new file mode 100644 +index 00000000..4cdbcf23 +--- /dev/null ++++ b/test/transcoding/SPV_INTEL_split_barrier/split_work_group_barrier_20.ll +@@ -0,0 +1,175 @@ ++;; 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 = !{!""} +diff --git a/test/transcoding/SPV_INTEL_split_barrier/split_work_group_barrier_spirv.ll b/test/transcoding/SPV_INTEL_split_barrier/split_work_group_barrier_spirv.ll +new file mode 100644 +index 00000000..ae5b57f1 +--- /dev/null ++++ b/test/transcoding/SPV_INTEL_split_barrier/split_work_group_barrier_spirv.ll +@@ -0,0 +1,170 @@ ++;; 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 = !{!""} +-- +2.17.1 +