1 | //===- AtomicOps.cpp - MLIR SPIR-V Atomic Ops ----------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // Defines the atomic operations in the SPIR-V dialect. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "mlir/Dialect/SPIRV/IR/SPIRVOps.h" |
14 | |
15 | #include "SPIRVOpUtils.h" |
16 | #include "SPIRVParsingUtils.h" |
17 | |
18 | using namespace mlir::spirv::AttrNames; |
19 | |
20 | namespace mlir::spirv { |
21 | |
22 | template <typename T> |
23 | static StringRef stringifyTypeName(); |
24 | |
25 | template <> |
26 | StringRef stringifyTypeName<IntegerType>() { |
27 | return "integer" ; |
28 | } |
29 | |
30 | template <> |
31 | StringRef stringifyTypeName<FloatType>() { |
32 | return "float" ; |
33 | } |
34 | |
35 | // Verifies an atomic update op. |
36 | template <typename AtomicOpTy, typename ExpectedElementType> |
37 | static LogicalResult verifyAtomicUpdateOp(Operation *op) { |
38 | auto ptrType = llvm::cast<spirv::PointerType>(Val: op->getOperand(idx: 0).getType()); |
39 | auto elementType = ptrType.getPointeeType(); |
40 | if (!llvm::isa<ExpectedElementType>(elementType)) |
41 | return op->emitOpError() << "pointer operand must point to an " |
42 | << stringifyTypeName<ExpectedElementType>() |
43 | << " value, found " << elementType; |
44 | |
45 | StringAttr semanticsAttrName = |
46 | AtomicOpTy::getSemanticsAttrName(op->getName()); |
47 | auto memorySemantics = |
48 | op->getAttrOfType<spirv::MemorySemanticsAttr>(semanticsAttrName) |
49 | .getValue(); |
50 | if (failed(verifyMemorySemantics(op, memorySemantics))) { |
51 | return failure(); |
52 | } |
53 | return success(); |
54 | } |
55 | |
56 | //===----------------------------------------------------------------------===// |
57 | // spirv.AtomicAndOp |
58 | //===----------------------------------------------------------------------===// |
59 | |
60 | LogicalResult AtomicAndOp::verify() { |
61 | return verifyAtomicUpdateOp<AtomicAndOp, IntegerType>(getOperation()); |
62 | } |
63 | |
64 | //===----------------------------------------------------------------------===// |
65 | // spirv.AtomicIAddOp |
66 | //===----------------------------------------------------------------------===// |
67 | |
68 | LogicalResult AtomicIAddOp::verify() { |
69 | return verifyAtomicUpdateOp<AtomicIAddOp, IntegerType>(getOperation()); |
70 | } |
71 | |
72 | //===----------------------------------------------------------------------===// |
73 | // spirv.EXT.AtomicFAddOp |
74 | //===----------------------------------------------------------------------===// |
75 | |
76 | LogicalResult EXTAtomicFAddOp::verify() { |
77 | return verifyAtomicUpdateOp<EXTAtomicFAddOp, FloatType>(getOperation()); |
78 | } |
79 | |
80 | //===----------------------------------------------------------------------===// |
81 | // spirv.AtomicIDecrementOp |
82 | //===----------------------------------------------------------------------===// |
83 | |
84 | LogicalResult AtomicIDecrementOp::verify() { |
85 | return verifyAtomicUpdateOp<AtomicIDecrementOp, IntegerType>(getOperation()); |
86 | } |
87 | |
88 | //===----------------------------------------------------------------------===// |
89 | // spirv.AtomicIIncrementOp |
90 | //===----------------------------------------------------------------------===// |
91 | |
92 | LogicalResult AtomicIIncrementOp::verify() { |
93 | return verifyAtomicUpdateOp<AtomicIIncrementOp, IntegerType>(getOperation()); |
94 | } |
95 | |
96 | //===----------------------------------------------------------------------===// |
97 | // spirv.AtomicISubOp |
98 | //===----------------------------------------------------------------------===// |
99 | |
100 | LogicalResult AtomicISubOp::verify() { |
101 | return verifyAtomicUpdateOp<AtomicISubOp, IntegerType>(getOperation()); |
102 | } |
103 | |
104 | //===----------------------------------------------------------------------===// |
105 | // spirv.AtomicOrOp |
106 | //===----------------------------------------------------------------------===// |
107 | |
108 | LogicalResult AtomicOrOp::verify() { |
109 | return verifyAtomicUpdateOp<AtomicOrOp, IntegerType>(getOperation()); |
110 | } |
111 | |
112 | //===----------------------------------------------------------------------===// |
113 | // spirv.AtomicSMaxOp |
114 | //===----------------------------------------------------------------------===// |
115 | |
116 | LogicalResult AtomicSMaxOp::verify() { |
117 | return verifyAtomicUpdateOp<AtomicSMaxOp, IntegerType>(getOperation()); |
118 | } |
119 | |
120 | //===----------------------------------------------------------------------===// |
121 | // spirv.AtomicSMinOp |
122 | //===----------------------------------------------------------------------===// |
123 | |
124 | LogicalResult AtomicSMinOp::verify() { |
125 | return verifyAtomicUpdateOp<AtomicSMinOp, IntegerType>(getOperation()); |
126 | } |
127 | |
128 | //===----------------------------------------------------------------------===// |
129 | // spirv.AtomicUMaxOp |
130 | //===----------------------------------------------------------------------===// |
131 | |
132 | LogicalResult AtomicUMaxOp::verify() { |
133 | return verifyAtomicUpdateOp<AtomicUMaxOp, IntegerType>(getOperation()); |
134 | } |
135 | |
136 | //===----------------------------------------------------------------------===// |
137 | // spirv.AtomicUMinOp |
138 | //===----------------------------------------------------------------------===// |
139 | |
140 | LogicalResult AtomicUMinOp::verify() { |
141 | return verifyAtomicUpdateOp<AtomicUMinOp, IntegerType>(getOperation()); |
142 | } |
143 | |
144 | //===----------------------------------------------------------------------===// |
145 | // spirv.AtomicXorOp |
146 | //===----------------------------------------------------------------------===// |
147 | |
148 | LogicalResult AtomicXorOp::verify() { |
149 | return verifyAtomicUpdateOp<AtomicXorOp, IntegerType>(getOperation()); |
150 | } |
151 | |
152 | } // namespace mlir::spirv |
153 | |