diff options
author | Alexey Sotkin <alexey.sotkin@intel.com> | 2018-02-06 22:08:41 +0300 |
---|---|---|
committer | Yaxun (Sam) Liu <yaxun.liu@amd.com> | 2018-02-06 14:08:41 -0500 |
commit | 2bb7e2eaafef38229e21a10b4da9050dae194492 (patch) | |
tree | 2f747b7c2585035e7240e31c98b436c6d3abd004 | |
parent | d526f83cce796953e06f35c9be7f769bf44b1065 (diff) |
[SPIRV] Fix capabilities for Atomic instructions (#227)
-rw-r--r-- | lib/SPIRV/libSPIRV/SPIRVInstruction.h | 26 | ||||
-rw-r--r-- | test/AtomicCompareExchange_cl20.ll | 3 | ||||
-rw-r--r-- | test/capability-Int64Atomics-store.ll | 38 | ||||
-rw-r--r-- | test/capability-Int64Atomics.ll | 38 |
4 files changed, 103 insertions, 2 deletions
diff --git a/lib/SPIRV/libSPIRV/SPIRVInstruction.h b/lib/SPIRV/libSPIRV/SPIRVInstruction.h index 7fb0758..ae5d778 100644 --- a/lib/SPIRV/libSPIRV/SPIRVInstruction.h +++ b/lib/SPIRV/libSPIRV/SPIRVInstruction.h @@ -2044,10 +2044,32 @@ _SPIRV_OP(GroupCommitReadPipe, false, 6) _SPIRV_OP(GroupCommitWritePipe, false, 6)
#undef _SPIRV_OP
-class SPIRVAtomicInstBase:public SPIRVInstTemplateBase {
+class SPIRVAtomicInstBase : public SPIRVInstTemplateBase {
public:
SPIRVCapVec getRequiredCapability() const override {
- return getVec(CapabilityInt64Atomics);
+ SPIRVCapVec CapVec;
+ // Most of atomic instructions do not require any capabilities
+ // ... unless they operate on 64-bit integers.
+ if (hasType() && getType()->isTypeInt(64)) {
+ // In SPIRV 1.2 spec only 2 atomic instructions have no result type:
+ // 1. OpAtomicStore - need to check type of the Value operand
+ // 2. OpAtomicFlagClear - doesn't require Int64Atomics capability.
+ CapVec.push_back(CapabilityInt64Atomics);
+ }
+ // Per the spec OpAtomicCompareExchangeWeak, OpAtomicFlagTestAndSet and
+ // OpAtomicFlagClear instructions require kernel capability. But this
+ // capability should be added by setting OpenCL memory model.
+ return CapVec;
+ }
+
+ // Overriding the following method only because of OpAtomicStore.
+ // We have to declare Int64Atomics capability if the Value operand is int64.
+ void setOpWords(const std::vector<SPIRVWord> &TheOps) override {
+ SPIRVInstTemplateBase::setOpWords(TheOps);
+ static const unsigned ValueOperandIndex = 3;
+ if (getOpCode() == OpAtomicStore &&
+ getOperand(ValueOperandIndex)->getType()->isTypeInt(64))
+ Module->addCapability(CapabilityInt64Atomics);
}
};
diff --git a/test/AtomicCompareExchange_cl20.ll b/test/AtomicCompareExchange_cl20.ll index be6a85a..3dc4f39 100644 --- a/test/AtomicCompareExchange_cl20.ll +++ b/test/AtomicCompareExchange_cl20.ll @@ -5,6 +5,9 @@ target triple = "spir-unknown-unknown" ; CHECK: 3 Source 3 200000 +; Int64Atomics capability must be declared only if atomic builtins have 64-bit integers arguments. +; CHECK-NOT: Capability Int64Atomics + ; CHECK: Name [[Pointer:[0-9]+]] "object" ; CHECK: Name [[ComparatorPtr:[0-9]+]] "expected" ; CHECK: Name [[Value:[0-9]+]] "desired" diff --git a/test/capability-Int64Atomics-store.ll b/test/capability-Int64Atomics-store.ll new file mode 100644 index 0000000..4bceae4 --- /dev/null +++ b/test/capability-Int64Atomics-store.ll @@ -0,0 +1,38 @@ +; OpenCL C source: +; #pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable +; #pragma OPENCL EXTENSION cl_khr_int64_extended_atomics : enable +; +; void foo (volatile atomic_long *object, long desired) { +; atomic_store(object, desired); +;} + +; RUN: llvm-as < %s | llvm-spirv -spirv-text -o - | FileCheck %s + +; CHECK: Capability Int64Atomics + +target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" +target triple = "spir64" + +; Function Attrs: nounwind +define spir_func void @foo(i64 addrspace(4)* %object, i64 %desired) #0 { +entry: + tail call spir_func void @_Z12atomic_storePVU3AS4U7_Atomicll(i64 addrspace(4)* %object, i64 %desired) #2 + ret void +} + +declare spir_func void @_Z12atomic_storePVU3AS4U7_Atomicll(i64 addrspace(4)*, i64) #1 + +attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind } + +!opencl.enable.FP_CONTRACT = !{} +!opencl.spir.version = !{!0} +!opencl.ocl.version = !{!1} +!opencl.used.extensions = !{!2} +!opencl.used.optional.core.features = !{!2} +!opencl.compiler.options = !{!2} + +!0 = !{i32 1, i32 2} +!1 = !{i32 2, i32 0} +!2 = !{} diff --git a/test/capability-Int64Atomics.ll b/test/capability-Int64Atomics.ll new file mode 100644 index 0000000..7152b89 --- /dev/null +++ b/test/capability-Int64Atomics.ll @@ -0,0 +1,38 @@ +; OpenCL C source: +; #pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable +; #pragma OPENCL EXTENSION cl_khr_int64_extended_atomics : enable +; +; void foo (volatile atomic_long *object, long desired) { +; atomic_fetch_xor(object, desired); +;} + +; RUN: llvm-as < %s | llvm-spirv -spirv-text -o - | FileCheck %s + +; CHECK: Capability Int64Atomics + +target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64" +target triple = "spir64" + +; Function Attrs: nounwind +define spir_func void @foo(i64 addrspace(4)* %object, i64 %desired) #0 { +entry: + %call = tail call spir_func i64 @_Z16atomic_fetch_xorPVU3AS4U7_Atomicll(i64 addrspace(4)* %object, i64 %desired) #2 + ret void +} + +declare spir_func i64 @_Z16atomic_fetch_xorPVU3AS4U7_Atomicll(i64 addrspace(4)*, i64) #1 + +attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #2 = { nounwind } + +!opencl.enable.FP_CONTRACT = !{} +!opencl.spir.version = !{!0} +!opencl.ocl.version = !{!1} +!opencl.used.extensions = !{!2} +!opencl.used.optional.core.features = !{!2} +!opencl.compiler.options = !{!2} + +!0 = !{i32 1, i32 2} +!1 = !{i32 2, i32 0} +!2 = !{} |