153 lines · cpp
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-exception6//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>(op->getOperand(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.AtomicAndOp58//===----------------------------------------------------------------------===//59 60LogicalResult AtomicAndOp::verify() {61 return verifyAtomicUpdateOp<AtomicAndOp, IntegerType>(getOperation());62}63 64//===----------------------------------------------------------------------===//65// spirv.AtomicIAddOp66//===----------------------------------------------------------------------===//67 68LogicalResult AtomicIAddOp::verify() {69 return verifyAtomicUpdateOp<AtomicIAddOp, IntegerType>(getOperation());70}71 72//===----------------------------------------------------------------------===//73// spirv.EXT.AtomicFAddOp74//===----------------------------------------------------------------------===//75 76LogicalResult EXTAtomicFAddOp::verify() {77 return verifyAtomicUpdateOp<EXTAtomicFAddOp, FloatType>(getOperation());78}79 80//===----------------------------------------------------------------------===//81// spirv.AtomicIDecrementOp82//===----------------------------------------------------------------------===//83 84LogicalResult AtomicIDecrementOp::verify() {85 return verifyAtomicUpdateOp<AtomicIDecrementOp, IntegerType>(getOperation());86}87 88//===----------------------------------------------------------------------===//89// spirv.AtomicIIncrementOp90//===----------------------------------------------------------------------===//91 92LogicalResult AtomicIIncrementOp::verify() {93 return verifyAtomicUpdateOp<AtomicIIncrementOp, IntegerType>(getOperation());94}95 96//===----------------------------------------------------------------------===//97// spirv.AtomicISubOp98//===----------------------------------------------------------------------===//99 100LogicalResult AtomicISubOp::verify() {101 return verifyAtomicUpdateOp<AtomicISubOp, IntegerType>(getOperation());102}103 104//===----------------------------------------------------------------------===//105// spirv.AtomicOrOp106//===----------------------------------------------------------------------===//107 108LogicalResult AtomicOrOp::verify() {109 return verifyAtomicUpdateOp<AtomicOrOp, IntegerType>(getOperation());110}111 112//===----------------------------------------------------------------------===//113// spirv.AtomicSMaxOp114//===----------------------------------------------------------------------===//115 116LogicalResult AtomicSMaxOp::verify() {117 return verifyAtomicUpdateOp<AtomicSMaxOp, IntegerType>(getOperation());118}119 120//===----------------------------------------------------------------------===//121// spirv.AtomicSMinOp122//===----------------------------------------------------------------------===//123 124LogicalResult AtomicSMinOp::verify() {125 return verifyAtomicUpdateOp<AtomicSMinOp, IntegerType>(getOperation());126}127 128//===----------------------------------------------------------------------===//129// spirv.AtomicUMaxOp130//===----------------------------------------------------------------------===//131 132LogicalResult AtomicUMaxOp::verify() {133 return verifyAtomicUpdateOp<AtomicUMaxOp, IntegerType>(getOperation());134}135 136//===----------------------------------------------------------------------===//137// spirv.AtomicUMinOp138//===----------------------------------------------------------------------===//139 140LogicalResult AtomicUMinOp::verify() {141 return verifyAtomicUpdateOp<AtomicUMinOp, IntegerType>(getOperation());142}143 144//===----------------------------------------------------------------------===//145// spirv.AtomicXorOp146//===----------------------------------------------------------------------===//147 148LogicalResult AtomicXorOp::verify() {149 return verifyAtomicUpdateOp<AtomicXorOp, IntegerType>(getOperation());150}151 152} // namespace mlir::spirv153