[Mlir-commits] [mlir] 6c48f6a - [mlir][spirv] add AtomicFAddEXTOp
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Nov 16 03:29:36 PST 2021
Author: Butygin
Date: 2021-11-16T14:24:22+03:00
New Revision: 6c48f6aafe69017065ab424dde11909d9cd5cb44
URL: https://github.com/llvm/llvm-project/commit/6c48f6aafe69017065ab424dde11909d9cd5cb44
DIFF: https://github.com/llvm/llvm-project/commit/6c48f6aafe69017065ab424dde11909d9cd5cb44.diff
LOG: [mlir][spirv] add AtomicFAddEXTOp
Differential Revision: https://reviews.llvm.org/D113764
Added:
Modified:
mlir/include/mlir/Dialect/SPIRV/IR/SPIRVAtomicOps.td
mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp
mlir/test/Dialect/SPIRV/IR/atomic-ops.mlir
mlir/test/Target/SPIRV/atomic-ops.mlir
Removed:
################################################################################
diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVAtomicOps.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVAtomicOps.td
index 406f6647a13d0..71ccee5bfea19 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVAtomicOps.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVAtomicOps.td
@@ -18,7 +18,7 @@ class SPV_AtomicUpdateOp<string mnemonic, list<OpTrait> traits = []> :
SPV_Op<mnemonic, traits> {
let parser = [{ return ::parseAtomicUpdateOp(parser, result, false); }];
let printer = [{ return ::printAtomicUpdateOp(getOperation(), p); }];
- let verifier = [{ return ::verifyAtomicUpdateOp(getOperation()); }];
+ let verifier = [{ return ::verifyAtomicUpdateOp<IntegerType>(getOperation()); }];
let arguments = (ins
SPV_AnyPtr:$pointer,
@@ -35,7 +35,7 @@ class SPV_AtomicUpdateWithValueOp<string mnemonic, list<OpTrait> traits = []> :
SPV_Op<mnemonic, traits> {
let parser = [{ return ::parseAtomicUpdateOp(parser, result, true); }];
let printer = [{ return ::printAtomicUpdateOp(getOperation(), p); }];
- let verifier = [{ return ::verifyAtomicUpdateOp(getOperation()); }];
+ let verifier = [{ return ::verifyAtomicUpdateOp<IntegerType>(getOperation()); }];
let arguments = (ins
SPV_AnyPtr:$pointer,
@@ -278,6 +278,71 @@ def SPV_AtomicExchangeOp : SPV_Op<"AtomicExchange", []> {
// -----
+def SPV_AtomicFAddEXTOp : SPV_Op<"AtomicFAddEXT", []> {
+ let summary = "TBD";
+
+ let description = [{
+
+
+ <!-- End of AutoGen section -->
+
+ Perform the following steps atomically with respect to any other atomic
+ accesses within Scope to the same location:
+
+ 1) load through Pointer to get an Original Value,
+
+ 2) get a New Value by float addition of Original Value and Value, and
+
+ 3) store the New Value back through Pointer.
+
+ The instruction’s result is the Original Value.
+
+ Result Type must be a floating-point type scalar.
+
+ The type of Value must be the same as Result Type. The type of the value
+ pointed to by Pointer must be the same as Result Type.
+
+ Memory must be a valid memory Scope.
+
+ ```
+ atomic-fadd-op ::=
+ `spv.AtomicFAddEXT` scope memory-semantics
+ ssa-use `,` ssa-use `:` spv-pointer-type
+ ```
+
+ #### Example:
+
+ ```mlir
+ %0 = spv.AtomicFAddEXT "Device" "None" %pointer, %value :
+ !spv.ptr<f32, StorageBuffer>
+ ```mlir
+ }];
+
+ let availability = [
+ MinVersion<SPV_V_1_0>,
+ MaxVersion<SPV_V_1_5>,
+ Extension<[SPV_EXT_shader_atomic_float_add]>,
+ Capability<[SPV_C_AtomicFloat16AddEXT, SPV_C_AtomicFloat32AddEXT, SPV_C_AtomicFloat64AddEXT]>
+ ];
+
+ let arguments = (ins
+ SPV_AnyPtr:$pointer,
+ SPV_ScopeAttr:$memory_scope,
+ SPV_MemorySemanticsAttr:$semantics,
+ SPV_Float:$value
+ );
+
+ let results = (outs
+ SPV_Float:$result
+ );
+
+ let parser = [{ return ::parseAtomicUpdateOp(parser, result, true); }];
+ let printer = [{ return ::printAtomicUpdateOp(getOperation(), p); }];
+ let verifier = [{ return ::verifyAtomicUpdateOp<FloatType>(getOperation()); }];
+}
+
+// -----
+
def SPV_AtomicIAddOp : SPV_AtomicUpdateWithValueOp<"AtomicIAdd", []> {
let summary = [{
Perform the following steps atomically with respect to any other atomic
diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
index 3c234e04c365c..8dd9b5c1fcea9 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
@@ -4169,6 +4169,7 @@ def SPV_OC_OpCooperativeMatrixMulAddNV : I32EnumAttrCase<"OpCooperativeMatrixMul
def SPV_OC_OpCooperativeMatrixLengthNV : I32EnumAttrCase<"OpCooperativeMatrixLengthNV", 5362>;
def SPV_OC_OpSubgroupBlockReadINTEL : I32EnumAttrCase<"OpSubgroupBlockReadINTEL", 5575>;
def SPV_OC_OpSubgroupBlockWriteINTEL : I32EnumAttrCase<"OpSubgroupBlockWriteINTEL", 5576>;
+def SPV_OC_OpAtomicFAddEXT : I32EnumAttrCase<"OpAtomicFAddEXT", 6035>;
def SPV_OpcodeAttr :
SPV_I32EnumAttr<"Opcode", "valid SPIR-V instructions", [
@@ -4232,7 +4233,8 @@ def SPV_OpcodeAttr :
SPV_OC_OpSubgroupBallotKHR, SPV_OC_OpTypeCooperativeMatrixNV,
SPV_OC_OpCooperativeMatrixLoadNV, SPV_OC_OpCooperativeMatrixStoreNV,
SPV_OC_OpCooperativeMatrixMulAddNV, SPV_OC_OpCooperativeMatrixLengthNV,
- SPV_OC_OpSubgroupBlockReadINTEL, SPV_OC_OpSubgroupBlockWriteINTEL
+ SPV_OC_OpSubgroupBlockReadINTEL, SPV_OC_OpSubgroupBlockWriteINTEL,
+ SPV_OC_OpAtomicFAddEXT
]>;
// End opcode section. Generated from SPIR-V spec; DO NOT MODIFY!
diff --git a/mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp b/mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp
index 554248f9c5c19..e4bcf462344e7 100644
--- a/mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp
+++ b/mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp
@@ -756,14 +756,28 @@ static void printAtomicUpdateOp(Operation *op, OpAsmPrinter &printer) {
<< "\" " << op->getOperands() << " : " << op->getOperand(0).getType();
}
+template <typename T>
+static StringRef stringifyTypeName();
+
+template <>
+StringRef stringifyTypeName<IntegerType>() {
+ return "integer";
+}
+
+template <>
+StringRef stringifyTypeName<FloatType>() {
+ return "float";
+}
+
// Verifies an atomic update op.
+template <typename ExpectedElementType>
static LogicalResult verifyAtomicUpdateOp(Operation *op) {
auto ptrType = op->getOperand(0).getType().cast<spirv::PointerType>();
auto elementType = ptrType.getPointeeType();
- if (!elementType.isa<IntegerType>())
- return op->emitOpError(
- "pointer operand must point to an integer value, found ")
- << elementType;
+ if (!elementType.isa<ExpectedElementType>())
+ return op->emitOpError() << "pointer operand must point to an "
+ << stringifyTypeName<ExpectedElementType>()
+ << " value, found " << elementType;
if (op->getNumOperands() > 1) {
auto valueType = op->getOperand(1).getType();
diff --git a/mlir/test/Dialect/SPIRV/IR/atomic-ops.mlir b/mlir/test/Dialect/SPIRV/IR/atomic-ops.mlir
index 2bc800025f989..2e0d00e4c84a8 100644
--- a/mlir/test/Dialect/SPIRV/IR/atomic-ops.mlir
+++ b/mlir/test/Dialect/SPIRV/IR/atomic-ops.mlir
@@ -236,3 +236,39 @@ func @atomic_xor(%ptr : !spv.ptr<i32, StorageBuffer>, %value : i32) -> i32 {
%0 = spv.AtomicXor "Workgroup" "None" %ptr, %value : !spv.ptr<i32, StorageBuffer>
return %0 : i32
}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spv.AtomicFAddEXT
+//===----------------------------------------------------------------------===//
+
+func @atomic_fadd(%ptr : !spv.ptr<f32, StorageBuffer>, %value : f32) -> f32 {
+ // CHECK: spv.AtomicFAddEXT "Device" "None" %{{.*}}, %{{.*}} : !spv.ptr<f32, StorageBuffer>
+ %0 = spv.AtomicFAddEXT "Device" "None" %ptr, %value : !spv.ptr<f32, StorageBuffer>
+ return %0 : f32
+}
+
+// -----
+
+func @atomic_fadd(%ptr : !spv.ptr<i32, StorageBuffer>, %value : f32) -> f32 {
+ // expected-error @+1 {{pointer operand must point to an float value, found 'i32'}}
+ %0 = "spv.AtomicFAddEXT"(%ptr, %value) {memory_scope = 4: i32, semantics = 0x4 : i32} : (!spv.ptr<i32, StorageBuffer>, f32) -> (f32)
+ return %0 : f32
+}
+
+// -----
+
+func @atomic_fadd(%ptr : !spv.ptr<f32, StorageBuffer>, %value : f64) -> f64 {
+ // expected-error @+1 {{expected value to have the same type as the pointer operand's pointee type 'f32', but found 'f64'}}
+ %0 = "spv.AtomicFAddEXT"(%ptr, %value) {memory_scope = 2: i32, semantics = 0x8 : i32} : (!spv.ptr<f32, StorageBuffer>, f64) -> (f64)
+ return %0 : f64
+}
+
+// -----
+
+func @atomic_fadd(%ptr : !spv.ptr<f32, StorageBuffer>, %value : f32) -> f32 {
+ // expected-error @+1 {{expected at most one of these four memory constraints to be set: `Acquire`, `Release`,`AcquireRelease` or `SequentiallyConsistent`}}
+ %0 = spv.AtomicFAddEXT "Device" "Acquire|Release" %ptr, %value : !spv.ptr<f32, StorageBuffer>
+ return %0 : f32
+}
diff --git a/mlir/test/Target/SPIRV/atomic-ops.mlir b/mlir/test/Target/SPIRV/atomic-ops.mlir
index 252d3d5deee23..a8706dcca4835 100644
--- a/mlir/test/Target/SPIRV/atomic-ops.mlir
+++ b/mlir/test/Target/SPIRV/atomic-ops.mlir
@@ -1,8 +1,8 @@
// RUN: mlir-translate -test-spirv-roundtrip -split-input-file %s | FileCheck %s
spv.module Logical GLSL450 requires #spv.vce<v1.0, [Shader], []> {
- // CHECK-LABEL: @atomic_compare_exchange_weak
- spv.func @atomic_compare_exchange_weak(%ptr: !spv.ptr<i32, Workgroup>, %value: i32, %comparator: i32) -> i32 "None" {
+ // CHECK-LABEL: @test_int_atomics
+ spv.func @test_int_atomics(%ptr: !spv.ptr<i32, Workgroup>, %value: i32, %comparator: i32) -> i32 "None" {
// CHECK: spv.AtomicCompareExchangeWeak "Workgroup" "Release" "Acquire" %{{.*}}, %{{.*}}, %{{.*}} : !spv.ptr<i32, Workgroup>
%0 = spv.AtomicCompareExchangeWeak "Workgroup" "Release" "Acquire" %ptr, %value, %comparator: !spv.ptr<i32, Workgroup>
// CHECK: spv.AtomicAnd "Device" "None" %{{.*}}, %{{.*}} : !spv.ptr<i32, Workgroup>
@@ -33,4 +33,11 @@ spv.module Logical GLSL450 requires #spv.vce<v1.0, [Shader], []> {
%13 = spv.AtomicExchange "Workgroup" "Release" %ptr, %value: !spv.ptr<i32, Workgroup>
spv.ReturnValue %0: i32
}
+
+ // CHECK-LABEL: @test_float_atomics
+ spv.func @test_float_atomics(%ptr: !spv.ptr<f32, Workgroup>, %value: f32) -> f32 "None" {
+ // CHECK: spv.AtomicFAddEXT "Workgroup" "Acquire" %{{.*}}, %{{.*}} : !spv.ptr<f32, Workgroup>
+ %0 = spv.AtomicFAddEXT "Workgroup" "Acquire" %ptr, %value : !spv.ptr<f32, Workgroup>
+ spv.ReturnValue %0: f32
+ }
}
More information about the Mlir-commits
mailing list