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
18using namespace mlir::spirv::AttrNames;
19
20namespace mlir::spirv {
21
22template <typename T>
23static StringRef stringifyTypeName();
24
25template <>
26StringRef stringifyTypeName<IntegerType>() {
27 return "integer";
28}
29
30template <>
31StringRef stringifyTypeName<FloatType>() {
32 return "float";
33}
34
35// Verifies an atomic update op.
36template <typename AtomicOpTy, typename ExpectedElementType>
37static 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
60LogicalResult AtomicAndOp::verify() {
61 return verifyAtomicUpdateOp<AtomicAndOp, IntegerType>(getOperation());
62}
63
64//===----------------------------------------------------------------------===//
65// spirv.AtomicIAddOp
66//===----------------------------------------------------------------------===//
67
68LogicalResult AtomicIAddOp::verify() {
69 return verifyAtomicUpdateOp<AtomicIAddOp, IntegerType>(getOperation());
70}
71
72//===----------------------------------------------------------------------===//
73// spirv.EXT.AtomicFAddOp
74//===----------------------------------------------------------------------===//
75
76LogicalResult EXTAtomicFAddOp::verify() {
77 return verifyAtomicUpdateOp<EXTAtomicFAddOp, FloatType>(getOperation());
78}
79
80//===----------------------------------------------------------------------===//
81// spirv.AtomicIDecrementOp
82//===----------------------------------------------------------------------===//
83
84LogicalResult AtomicIDecrementOp::verify() {
85 return verifyAtomicUpdateOp<AtomicIDecrementOp, IntegerType>(getOperation());
86}
87
88//===----------------------------------------------------------------------===//
89// spirv.AtomicIIncrementOp
90//===----------------------------------------------------------------------===//
91
92LogicalResult AtomicIIncrementOp::verify() {
93 return verifyAtomicUpdateOp<AtomicIIncrementOp, IntegerType>(getOperation());
94}
95
96//===----------------------------------------------------------------------===//
97// spirv.AtomicISubOp
98//===----------------------------------------------------------------------===//
99
100LogicalResult AtomicISubOp::verify() {
101 return verifyAtomicUpdateOp<AtomicISubOp, IntegerType>(getOperation());
102}
103
104//===----------------------------------------------------------------------===//
105// spirv.AtomicOrOp
106//===----------------------------------------------------------------------===//
107
108LogicalResult AtomicOrOp::verify() {
109 return verifyAtomicUpdateOp<AtomicOrOp, IntegerType>(getOperation());
110}
111
112//===----------------------------------------------------------------------===//
113// spirv.AtomicSMaxOp
114//===----------------------------------------------------------------------===//
115
116LogicalResult AtomicSMaxOp::verify() {
117 return verifyAtomicUpdateOp<AtomicSMaxOp, IntegerType>(getOperation());
118}
119
120//===----------------------------------------------------------------------===//
121// spirv.AtomicSMinOp
122//===----------------------------------------------------------------------===//
123
124LogicalResult AtomicSMinOp::verify() {
125 return verifyAtomicUpdateOp<AtomicSMinOp, IntegerType>(getOperation());
126}
127
128//===----------------------------------------------------------------------===//
129// spirv.AtomicUMaxOp
130//===----------------------------------------------------------------------===//
131
132LogicalResult AtomicUMaxOp::verify() {
133 return verifyAtomicUpdateOp<AtomicUMaxOp, IntegerType>(getOperation());
134}
135
136//===----------------------------------------------------------------------===//
137// spirv.AtomicUMinOp
138//===----------------------------------------------------------------------===//
139
140LogicalResult AtomicUMinOp::verify() {
141 return verifyAtomicUpdateOp<AtomicUMinOp, IntegerType>(getOperation());
142}
143
144//===----------------------------------------------------------------------===//
145// spirv.AtomicXorOp
146//===----------------------------------------------------------------------===//
147
148LogicalResult AtomicXorOp::verify() {
149 return verifyAtomicUpdateOp<AtomicXorOp, IntegerType>(getOperation());
150}
151
152} // namespace mlir::spirv
153

source code of mlir/lib/Dialect/SPIRV/IR/AtomicOps.cpp