Skip to content

Commit

Permalink
Improve handling of OpMemoryBarrier
Browse files Browse the repository at this point in the history
Added support for non-constant 'Semantics' operand
  • Loading branch information
AlexeySachkov committed May 21, 2020
1 parent 96af6ec commit ef1606f
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 17 deletions.
33 changes: 19 additions & 14 deletions lib/SPIRV/SPIRVToOCL20.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,20 +107,25 @@ bool SPIRVToOCL20::runOnModule(Module &Module) {

void SPIRVToOCL20::visitCallSPIRVMemoryBarrier(CallInst *CI) {
AttributeList Attrs = CI->getCalledFunction()->getAttributes();
mutateCallInstOCL(M, CI,
[=](CallInst *, std::vector<Value *> &Args) {
auto GetArg = [=](unsigned I) {
return cast<ConstantInt>(Args[I])->getZExtValue();
};
auto MScope = static_cast<Scope>(GetArg(0));
auto Sema = mapSPIRVMemSemanticToOCL(GetArg(1));
Args.resize(3);
Args[0] = getInt32(M, Sema.first);
Args[1] = getInt32(M, Sema.second);
Args[2] = getInt32(M, rmap<OCLScopeKind>(MScope));
return kOCLBuiltinName::AtomicWorkItemFence;
},
&Attrs);
mutateCallInstOCL(
M, CI,
[=](CallInst *, std::vector<Value *> &Args) {
Value *MemScope =
getInt32(M, rmap<OCLScopeKind>(static_cast<Scope>(
cast<ConstantInt>(Args[0])->getZExtValue())));
Value *MemFenceFlags =
SPIRV::transSPIRVMemorySemanticsIntoOCLMemFenceFlags(Args[1], CI);
Value *MemOrder =
SPIRV::transSPIRVMemorySemanticsIntoOCLMemoryOrder(Args[1], CI);

Args.resize(3);
Args[0] = MemFenceFlags;
Args[1] = MemOrder;
Args[2] = MemScope;

return kOCLBuiltinName::AtomicWorkItemFence;
},
&Attrs);
}

void SPIRVToOCL20::visitCallSPIRVControlBarrier(CallInst *CI) {
Expand Down
32 changes: 29 additions & 3 deletions test/mem_fence_explicit_arguments.spt
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,15 @@
; RUN: llvm-spirv %s -to-binary -o %t.spv
; RUN: spirv-val %t.spv
; RUN: llvm-spirv -r %t.spv -o %t.bc
; RUN: llvm-dis < %t.bc | FileCheck %s
; RUN: llvm-dis < %t.bc | FileCheck %s --check-prefixes CHECK,CHECK-12
; RUN: llvm-spirv -r %t.spv --spirv-target-env=CL2.0 -o %t.bc
; RUN: llvm-dis < %t.bc | FileCheck %s --check-prefixes CHECK,CHECK-20

; CHECK: define spir_func void @test(i32 %val)
; CHECK: %call = call spir_func i32 @__translate_spirv_memory_fence(i32 %val)
; CHECK: call spir_func void @_Z9mem_fencej(i32 %call)
; CHECK-12: call spir_func void @_Z9mem_fencej(i32 %call)
; CHECK-20: %call1 = call spir_func i32 @__translate_spirv_memory_order(i32 %val)
; CHECK-20: call spir_func void @_Z22atomic_work_item_fencej12memory_order12memory_scope(i32 %call, i32 %call1
; CHECK: define private spir_func i32 @__translate_spirv_memory_fence(i32 %key)
; CHECK: entry:
; CHECK: %key.masked = and i32 2816, %key
Expand Down Expand Up @@ -60,4 +64,26 @@
; CHECK: case.2816:
; CHECK: ret i32 7
; CHECK: }
; CHECK: declare spir_func void @_Z9mem_fencej(i32)
; CHECK-20: define private spir_func i32 @__translate_spirv_memory_order(i32 %key) {
; CHECK-20: entry:
; CHECK-20: %key.masked = and i32 30, %key
; CHECK-20: switch i32 %key.masked, label %default [
; CHECK-20: i32 0, label %case.0
; CHECK-20: i32 2, label %case.2
; CHECK-20: i32 4, label %case.4
; CHECK-20: i32 8, label %case.8
; CHECK-20: i32 16, label %case.16
; CHECK-20: ]
; CHECK-20: default:
; CHECK-20: unreachable
; CHECK-20: case.0:
; CHECK-20: ret i32 0
; CHECK-20: case.2:
; CHECK-20: ret i32 2
; CHECK-20: case.4:
; CHECK-20: ret i32 3
; CHECK-20: case.8:
; CHECK-20: ret i32 4
; CHECK-20: case.16:
; CHECK-20: ret i32 5
; CHECK-20: }

0 comments on commit ef1606f

Please sign in to comment.