[mlir][spirv] Use assemblyFormat to define atomic op assembly (#76323)

see #73359

Declarative assemblyFormat ODS is more concise and requires less
boilerplate than filling out CPP interfaces.

Changes:
* updates the Ops defined in `SPIRVAtomicOps.td` to use assemblyFormat.
* Removes print/parse from`AtomcOps.cpp` which is now generated by
assemblyFormat
* Adds `Trait` to verify that a pointer operand `foo`'s pointee type
matches operand `bar`'s type
* * Updates error message expected in tests from new Trait
* Updates tests to updated format (largely using <operand> in place of
"operand")
This commit is contained in:
Alex Beloi
2024-01-06 19:55:55 -08:00
committed by GitHub
parent 0ebe97115d
commit c63febb102
11 changed files with 192 additions and 517 deletions

View File

@@ -14,8 +14,20 @@
#ifndef MLIR_DIALECT_SPIRV_IR_ATOMIC_OPS
#define MLIR_DIALECT_SPIRV_IR_ATOMIC_OPS
class SPIRV_AtomicUpdateOp<string mnemonic, list<Trait> traits = []> :
SPIRV_Op<mnemonic, traits> {
include "mlir/Dialect/SPIRV/IR/SPIRVBase.td"
include "mlir/Interfaces/SideEffectInterfaces.td"
class PointeeTypeMatchTrait<string pointer, string name>
: TypesMatchWith<
"`" # name # "` type matches pointee type of " # "`" # pointer # "`",
pointer, name, "llvm::cast<PointerType>($_self).getPointeeType()">;
// -----
class SPIRV_AtomicUpdateOp<string mnemonic, list<Trait> traits = []>
: SPIRV_Op<mnemonic,
!listconcat(traits,
[PointeeTypeMatchTrait<"pointer", "result">])> {
let arguments = (ins
SPIRV_AnyPtr:$pointer,
SPIRV_ScopeAttr:$memory_scope,
@@ -25,10 +37,19 @@ class SPIRV_AtomicUpdateOp<string mnemonic, list<Trait> traits = []> :
let results = (outs
SPIRV_Integer:$result
);
let assemblyFormat = [{
$memory_scope $semantics operands attr-dict `:` type($pointer)
}];
let hasCustomAssemblyFormat = 0;
}
class SPIRV_AtomicUpdateWithValueOp<string mnemonic, list<Trait> traits = []> :
SPIRV_Op<mnemonic, traits> {
class SPIRV_AtomicUpdateWithValueOp<string mnemonic, list<Trait> traits = []>
: SPIRV_Op<mnemonic, !listconcat(traits, [
PointeeTypeMatchTrait<"pointer", "value">,
PointeeTypeMatchTrait<"pointer", "result">,
])> {
let arguments = (ins
SPIRV_AnyPtr:$pointer,
SPIRV_ScopeAttr:$memory_scope,
@@ -40,11 +61,11 @@ class SPIRV_AtomicUpdateWithValueOp<string mnemonic, list<Trait> traits = []> :
SPIRV_Integer:$result
);
let builders = [
OpBuilder<(ins "Value":$pointer, "::mlir::spirv::Scope":$scope,
"::mlir::spirv::MemorySemantics":$memory, "Value":$value),
[{build($_builder, $_state, value.getType(), pointer, scope, memory, value);}]>
];
let assemblyFormat = [{
$memory_scope $semantics operands attr-dict `:` type($pointer)
}];
let hasCustomAssemblyFormat = 0;
}
// -----
@@ -73,20 +94,10 @@ def SPIRV_AtomicAndOp : SPIRV_AtomicUpdateWithValueOp<"AtomicAnd", []> {
<!-- End of AutoGen section -->
```
scope ::= `"CrossDevice"` | `"Device"` | `"Workgroup"` | ...
memory-semantics ::= `"None"` | `"Acquire"` | "Release"` | ...
atomic-and-op ::=
`spirv.AtomicAnd` scope memory-semantics
ssa-use `,` ssa-use `:` spv-pointer-type
```
#### Example:
```mlir
%0 = spirv.AtomicAnd "Device" "None" %pointer, %value :
%0 = spirv.AtomicAnd <Device> <None> %pointer, %value :
!spirv.ptr<i32, StorageBuffer>
```
}];
@@ -94,7 +105,11 @@ def SPIRV_AtomicAndOp : SPIRV_AtomicUpdateWithValueOp<"AtomicAnd", []> {
// -----
def SPIRV_AtomicCompareExchangeOp : SPIRV_Op<"AtomicCompareExchange", []> {
def SPIRV_AtomicCompareExchangeOp : SPIRV_Op<"AtomicCompareExchange", [
PointeeTypeMatchTrait<"pointer", "result">,
PointeeTypeMatchTrait<"pointer", "value">,
PointeeTypeMatchTrait<"pointer", "comparator">,
]> {
let summary = [{
Perform the following steps atomically with respect to any other atomic
accesses within Scope to the same location:
@@ -129,17 +144,10 @@ def SPIRV_AtomicCompareExchangeOp : SPIRV_Op<"AtomicCompareExchange", []> {
<!-- End of AutoGen section -->
```
atomic-compare-exchange-op ::=
`spirv.AtomicCompareExchange` scope memory-semantics memory-semantics
ssa-use `,` ssa-use `,` ssa-use
`:` spv-pointer-type
```
#### Example:
```
%0 = spirv.AtomicCompareExchange "Workgroup" "Acquire" "None"
%0 = spirv.AtomicCompareExchange <Workgroup> <Acquire> <None>
%pointer, %value, %comparator
: !spirv.ptr<i32, WorkGroup>
```
@@ -157,11 +165,23 @@ def SPIRV_AtomicCompareExchangeOp : SPIRV_Op<"AtomicCompareExchange", []> {
let results = (outs
SPIRV_Integer:$result
);
let assemblyFormat = [{
$memory_scope $equal_semantics $unequal_semantics operands attr-dict `:`
type($pointer)
}];
let hasCustomAssemblyFormat = 0;
let hasVerifier = 0;
}
// -----
def SPIRV_AtomicCompareExchangeWeakOp : SPIRV_Op<"AtomicCompareExchangeWeak", []> {
def SPIRV_AtomicCompareExchangeWeakOp : SPIRV_Op<"AtomicCompareExchangeWeak", [
PointeeTypeMatchTrait<"pointer", "result">,
PointeeTypeMatchTrait<"pointer", "value">,
PointeeTypeMatchTrait<"pointer", "comparator">,
]> {
let summary = "Deprecated (use OpAtomicCompareExchange).";
let description = [{
@@ -171,17 +191,10 @@ def SPIRV_AtomicCompareExchangeWeakOp : SPIRV_Op<"AtomicCompareExchangeWeak", []
<!-- End of AutoGen section -->
```
atomic-compare-exchange-weak-op ::=
`spirv.AtomicCompareExchangeWeak` scope memory-semantics memory-semantics
ssa-use `,` ssa-use `,` ssa-use
`:` spv-pointer-type
```
#### Example:
```mlir
%0 = spirv.AtomicCompareExchangeWeak "Workgroup" "Acquire" "None"
%0 = spirv.AtomicCompareExchangeWeak <Workgroup> <Acquire> <None>
%pointer, %value, %comparator
: !spirv.ptr<i32, WorkGroup>
```
@@ -206,11 +219,22 @@ def SPIRV_AtomicCompareExchangeWeakOp : SPIRV_Op<"AtomicCompareExchangeWeak", []
let results = (outs
SPIRV_Integer:$result
);
let assemblyFormat = [{
$memory_scope $equal_semantics $unequal_semantics operands attr-dict `:`
type($pointer)
}];
let hasCustomAssemblyFormat = 0;
let hasVerifier = 0;
}
// -----
def SPIRV_AtomicExchangeOp : SPIRV_Op<"AtomicExchange", []> {
def SPIRV_AtomicExchangeOp : SPIRV_Op<"AtomicExchange", [
PointeeTypeMatchTrait<"pointer", "value">,
PointeeTypeMatchTrait<"pointer", "result">,
]> {
let summary = [{
Perform the following steps atomically with respect to any other atomic
accesses within Scope to the same location:
@@ -234,16 +258,10 @@ def SPIRV_AtomicExchangeOp : SPIRV_Op<"AtomicExchange", []> {
<!-- End of AutoGen section -->
```
atomic-exchange-op ::=
`spirv.AtomicCompareExchange` scope memory-semantics
ssa-use `,` ssa-use `:` spv-pointer-type
```
#### Example:
```mlir
%0 = spirv.AtomicExchange "Workgroup" "Acquire" %pointer, %value,
%0 = spirv.AtomicExchange <Workgroup> <Acquire> %pointer, %value,
: !spirv.ptr<i32, WorkGroup>
```
}];
@@ -258,11 +276,21 @@ def SPIRV_AtomicExchangeOp : SPIRV_Op<"AtomicExchange", []> {
let results = (outs
SPIRV_Numerical:$result
);
let assemblyFormat = [{
$memory_scope $semantics operands attr-dict `:` type($pointer)
}];
let hasCustomAssemblyFormat = 0;
let hasVerifier = 0;
}
// -----
def SPIRV_EXTAtomicFAddOp : SPIRV_ExtVendorOp<"AtomicFAdd", []> {
def SPIRV_EXTAtomicFAddOp : SPIRV_ExtVendorOp<"AtomicFAdd", [
PointeeTypeMatchTrait<"pointer", "result">,
PointeeTypeMatchTrait<"pointer", "value">,
]> {
let summary = "TBD";
let description = [{
@@ -288,16 +316,10 @@ def SPIRV_EXTAtomicFAddOp : SPIRV_ExtVendorOp<"AtomicFAdd", []> {
Memory must be a valid memory Scope.
```
atomic-fadd-op ::=
`spirv.EXT.AtomicFAdd` scope memory-semantics
ssa-use `,` ssa-use `:` spv-pointer-type
```
#### Example:
```mlir
%0 = spirv.EXT.AtomicFAdd "Device" "None" %pointer, %value :
%0 = spirv.EXT.AtomicFAdd <Device> <None> %pointer, %value :
!spirv.ptr<f32, StorageBuffer>
```
}];
@@ -319,6 +341,10 @@ def SPIRV_EXTAtomicFAddOp : SPIRV_ExtVendorOp<"AtomicFAdd", []> {
let results = (outs
SPIRV_Float:$result
);
let assemblyFormat = [{
$memory_scope $semantics operands attr-dict `:` type($pointer)
}];
}
// -----
@@ -347,16 +373,10 @@ def SPIRV_AtomicIAddOp : SPIRV_AtomicUpdateWithValueOp<"AtomicIAdd", []> {
<!-- End of AutoGen section -->
```
atomic-iadd-op ::=
`spirv.AtomicIAdd` scope memory-semantics
ssa-use `,` ssa-use `:` spv-pointer-type
```
#### Example:
```mlir
%0 = spirv.AtomicIAdd "Device" "None" %pointer, %value :
%0 = spirv.AtomicIAdd <Device> <None> %pointer, %value :
!spirv.ptr<i32, StorageBuffer>
```
}];
@@ -387,16 +407,10 @@ def SPIRV_AtomicIDecrementOp : SPIRV_AtomicUpdateOp<"AtomicIDecrement", []> {
<!-- End of AutoGen section -->
```
atomic-idecrement-op ::=
`spirv.AtomicIDecrement` scope memory-semantics ssa-use
`:` spv-pointer-type
```
#### Example:
```mlir
%0 = spirv.AtomicIDecrement "Device" "None" %pointer :
%0 = spirv.AtomicIDecrement <Device> <None> %pointer :
!spirv.ptr<i32, StorageBuffer>
```
}];
@@ -426,16 +440,10 @@ def SPIRV_AtomicIIncrementOp : SPIRV_AtomicUpdateOp<"AtomicIIncrement", []> {
<!-- End of AutoGen section -->
```
atomic-iincrement-op ::=
`spirv.AtomicIIncrement` scope memory-semantics ssa-use
`:` spv-pointer-type
```
#### Example:
```mlir
%0 = spirv.AtomicIncrement "Device" "None" %pointer :
%0 = spirv.AtomicIncrement <Device> <None> %pointer :
!spirv.ptr<i32, StorageBuffer>
```
}];
@@ -468,16 +476,10 @@ def SPIRV_AtomicISubOp : SPIRV_AtomicUpdateWithValueOp<"AtomicISub", []> {
<!-- End of AutoGen section -->
```
atomic-isub-op ::=
`spirv.AtomicISub` scope memory-semantics
ssa-use `,` ssa-use `:` spv-pointer-type
```
#### Example:
```mlir
%0 = spirv.AtomicISub "Device" "None" %pointer, %value :
%0 = spirv.AtomicISub <Device> <None> %pointer, %value :
!spirv.ptr<i32, StorageBuffer>
```
}];
@@ -509,16 +511,10 @@ def SPIRV_AtomicOrOp : SPIRV_AtomicUpdateWithValueOp<"AtomicOr", []> {
<!-- End of AutoGen section -->
```
atomic-or-op ::=
`spirv.AtomicOr` scope memory-semantics
ssa-use `,` ssa-use `:` spv-pointer-type
```
#### Example:
```mlir
%0 = spirv.AtomicOr "Device" "None" %pointer, %value :
%0 = spirv.AtomicOr <Device> <None> %pointer, %value :
!spirv.ptr<i32, StorageBuffer>
```
}];
@@ -551,16 +547,10 @@ def SPIRV_AtomicSMaxOp : SPIRV_AtomicUpdateWithValueOp<"AtomicSMax", []> {
<!-- End of AutoGen section -->
```
atomic-smax-op ::=
`spirv.AtomicSMax` scope memory-semantics
ssa-use `,` ssa-use `:` spv-pointer-type
```
#### Example:
```mlir
%0 = spirv.AtomicSMax "Device" "None" %pointer, %value :
%0 = spirv.AtomicSMax <Device> <None> %pointer, %value :
!spirv.ptr<i32, StorageBuffer>
```
}];
@@ -593,16 +583,10 @@ def SPIRV_AtomicSMinOp : SPIRV_AtomicUpdateWithValueOp<"AtomicSMin", []> {
<!-- End of AutoGen section -->
```
atomic-smin-op ::=
`spirv.AtomicSMin` scope memory-semantics
ssa-use `,` ssa-use `:` spv-pointer-type
```
#### Example:
```mlir
%0 = spirv.AtomicSMin "Device" "None" %pointer, %value :
%0 = spirv.AtomicSMin <Device> <None> %pointer, %value :
!spirv.ptr<i32, StorageBuffer>
```
}];
@@ -635,16 +619,10 @@ def SPIRV_AtomicUMaxOp : SPIRV_AtomicUpdateWithValueOp<"AtomicUMax", [UnsignedOp
<!-- End of AutoGen section -->
```
atomic-umax-op ::=
`spirv.AtomicUMax` scope memory-semantics
ssa-use `,` ssa-use `:` spv-pointer-type
```
#### Example:
```mlir
%0 = spirv.AtomicUMax "Device" "None" %pointer, %value :
%0 = spirv.AtomicUMax <Device> <None> %pointer, %value :
!spirv.ptr<i32, StorageBuffer>
```
}];
@@ -677,16 +655,10 @@ def SPIRV_AtomicUMinOp : SPIRV_AtomicUpdateWithValueOp<"AtomicUMin", [UnsignedOp
<!-- End of AutoGen section -->
```
atomic-umin-op ::=
`spirv.AtomicUMin` scope memory-semantics
ssa-use `,` ssa-use `:` spv-pointer-type
```
#### Example:
```mlir
%0 = spirv.AtomicUMin "Device" "None" %pointer, %value :
%0 = spirv.AtomicUMin <Device> <None> %pointer, %value :
!spirv.ptr<i32, StorageBuffer>
```
}];
@@ -719,16 +691,10 @@ def SPIRV_AtomicXorOp : SPIRV_AtomicUpdateWithValueOp<"AtomicXor", []> {
<!-- End of AutoGen section -->
```
atomic-xor-op ::=
`spirv.AtomicXor` scope memory-semantics
ssa-use `,` ssa-use `:` spv-pointer-type
```
#### Example:
```mlir
%0 = spirv.AtomicXor "Device" "None" %pointer, %value :
%0 = spirv.AtomicXor <Device> <None> %pointer, %value :
!spirv.ptr<i32, StorageBuffer>
```
}];

View File

@@ -19,49 +19,6 @@ using namespace mlir::spirv::AttrNames;
namespace mlir::spirv {
// Parses an atomic update op. If the update op does not take a value (like
// AtomicIIncrement) `hasValue` must be false.
static ParseResult parseAtomicUpdateOp(OpAsmParser &parser,
OperationState &state, bool hasValue) {
spirv::Scope scope;
spirv::MemorySemantics memoryScope;
SmallVector<OpAsmParser::UnresolvedOperand, 2> operandInfo;
OpAsmParser::UnresolvedOperand ptrInfo, valueInfo;
Type type;
SMLoc loc;
if (parseEnumStrAttr<spirv::ScopeAttr>(scope, parser, state,
kMemoryScopeAttrName) ||
parseEnumStrAttr<spirv::MemorySemanticsAttr>(memoryScope, parser, state,
kSemanticsAttrName) ||
parser.parseOperandList(operandInfo, (hasValue ? 2 : 1)) ||
parser.getCurrentLocation(&loc) || parser.parseColonType(type))
return failure();
auto ptrType = llvm::dyn_cast<spirv::PointerType>(type);
if (!ptrType)
return parser.emitError(loc, "expected pointer type");
SmallVector<Type, 2> operandTypes;
operandTypes.push_back(ptrType);
if (hasValue)
operandTypes.push_back(ptrType.getPointeeType());
if (parser.resolveOperands(operandInfo, operandTypes, parser.getNameLoc(),
state.operands))
return failure();
return parser.addTypeToList(ptrType.getPointeeType(), state.types);
}
// Prints an atomic update op.
static void printAtomicUpdateOp(Operation *op, OpAsmPrinter &printer) {
printer << " \"";
auto scopeAttr = op->getAttrOfType<spirv::ScopeAttr>(kMemoryScopeAttrName);
printer << spirv::stringifyScope(scopeAttr.getValue()) << "\" \"";
auto memorySemanticsAttr =
op->getAttrOfType<spirv::MemorySemanticsAttr>(kSemanticsAttrName);
printer << spirv::stringifyMemorySemantics(memorySemanticsAttr.getValue())
<< "\" " << op->getOperands() << " : " << op->getOperand(0).getType();
}
template <typename T>
static StringRef stringifyTypeName();
@@ -85,13 +42,6 @@ static LogicalResult verifyAtomicUpdateOp(Operation *op) {
<< stringifyTypeName<ExpectedElementType>()
<< " value, found " << elementType;
if (op->getNumOperands() > 1) {
auto valueType = op->getOperand(1).getType();
if (valueType != elementType)
return op->emitOpError("expected value to have the same type as the "
"pointer operand's pointee type ")
<< elementType << ", but found " << valueType;
}
auto memorySemantics =
op->getAttrOfType<spirv::MemorySemanticsAttr>(kSemanticsAttrName)
.getValue();
@@ -101,78 +51,6 @@ static LogicalResult verifyAtomicUpdateOp(Operation *op) {
return success();
}
template <typename T>
static void printAtomicCompareExchangeImpl(T atomOp, OpAsmPrinter &printer) {
printer << " \"" << stringifyScope(atomOp.getMemoryScope()) << "\" \""
<< stringifyMemorySemantics(atomOp.getEqualSemantics()) << "\" \""
<< stringifyMemorySemantics(atomOp.getUnequalSemantics()) << "\" "
<< atomOp.getOperands() << " : " << atomOp.getPointer().getType();
}
static ParseResult parseAtomicCompareExchangeImpl(OpAsmParser &parser,
OperationState &state) {
spirv::Scope memoryScope;
spirv::MemorySemantics equalSemantics, unequalSemantics;
SmallVector<OpAsmParser::UnresolvedOperand, 3> operandInfo;
Type type;
if (parseEnumStrAttr<spirv::ScopeAttr>(memoryScope, parser, state,
kMemoryScopeAttrName) ||
parseEnumStrAttr<spirv::MemorySemanticsAttr>(
equalSemantics, parser, state, kEqualSemanticsAttrName) ||
parseEnumStrAttr<spirv::MemorySemanticsAttr>(
unequalSemantics, parser, state, kUnequalSemanticsAttrName) ||
parser.parseOperandList(operandInfo, 3))
return failure();
auto loc = parser.getCurrentLocation();
if (parser.parseColonType(type))
return failure();
auto ptrType = llvm::dyn_cast<spirv::PointerType>(type);
if (!ptrType)
return parser.emitError(loc, "expected pointer type");
if (parser.resolveOperands(
operandInfo,
{ptrType, ptrType.getPointeeType(), ptrType.getPointeeType()},
parser.getNameLoc(), state.operands))
return failure();
return parser.addTypeToList(ptrType.getPointeeType(), state.types);
}
template <typename T>
static LogicalResult verifyAtomicCompareExchangeImpl(T atomOp) {
// According to the spec:
// "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. This type must also
// match the type of Comparator."
if (atomOp.getType() != atomOp.getValue().getType())
return atomOp.emitOpError("value operand must have the same type as the op "
"result, but found ")
<< atomOp.getValue().getType() << " vs " << atomOp.getType();
if (atomOp.getType() != atomOp.getComparator().getType())
return atomOp.emitOpError(
"comparator operand must have the same type as the op "
"result, but found ")
<< atomOp.getComparator().getType() << " vs " << atomOp.getType();
Type pointeeType =
llvm::cast<spirv::PointerType>(atomOp.getPointer().getType())
.getPointeeType();
if (atomOp.getType() != pointeeType)
return atomOp.emitOpError(
"pointer operand's pointee type must have the same "
"as the op result type, but found ")
<< pointeeType << " vs " << atomOp.getType();
// TODO: Unequal cannot be set to Release or Acquire and Release.
// In addition, Unequal cannot be set to a stronger memory-order then Equal.
return success();
}
//===----------------------------------------------------------------------===//
// spirv.AtomicAndOp
//===----------------------------------------------------------------------===//
@@ -181,100 +59,6 @@ LogicalResult AtomicAndOp::verify() {
return verifyAtomicUpdateOp<IntegerType>(getOperation());
}
ParseResult AtomicAndOp::parse(OpAsmParser &parser, OperationState &result) {
return parseAtomicUpdateOp(parser, result, true);
}
void AtomicAndOp::print(OpAsmPrinter &p) { printAtomicUpdateOp(*this, p); }
//===----------------------------------------------------------------------===//
// spirv.AtomicCompareExchangeOp
//===----------------------------------------------------------------------===//
LogicalResult AtomicCompareExchangeOp::verify() {
return verifyAtomicCompareExchangeImpl(*this);
}
ParseResult AtomicCompareExchangeOp::parse(OpAsmParser &parser,
OperationState &result) {
return parseAtomicCompareExchangeImpl(parser, result);
}
void AtomicCompareExchangeOp::print(OpAsmPrinter &p) {
printAtomicCompareExchangeImpl(*this, p);
}
//===----------------------------------------------------------------------===//
// spirv.AtomicCompareExchangeWeakOp
//===----------------------------------------------------------------------===//
LogicalResult AtomicCompareExchangeWeakOp::verify() {
return verifyAtomicCompareExchangeImpl(*this);
}
ParseResult AtomicCompareExchangeWeakOp::parse(OpAsmParser &parser,
OperationState &result) {
return parseAtomicCompareExchangeImpl(parser, result);
}
void AtomicCompareExchangeWeakOp::print(OpAsmPrinter &p) {
printAtomicCompareExchangeImpl(*this, p);
}
//===----------------------------------------------------------------------===//
// spirv.AtomicExchange
//===----------------------------------------------------------------------===//
void AtomicExchangeOp::print(OpAsmPrinter &printer) {
printer << " \"" << stringifyScope(getMemoryScope()) << "\" \""
<< stringifyMemorySemantics(getSemantics()) << "\" " << getOperands()
<< " : " << getPointer().getType();
}
ParseResult AtomicExchangeOp::parse(OpAsmParser &parser,
OperationState &result) {
spirv::Scope memoryScope;
spirv::MemorySemantics semantics;
SmallVector<OpAsmParser::UnresolvedOperand, 2> operandInfo;
Type type;
if (parseEnumStrAttr<spirv::ScopeAttr>(memoryScope, parser, result,
kMemoryScopeAttrName) ||
parseEnumStrAttr<spirv::MemorySemanticsAttr>(semantics, parser, result,
kSemanticsAttrName) ||
parser.parseOperandList(operandInfo, 2))
return failure();
auto loc = parser.getCurrentLocation();
if (parser.parseColonType(type))
return failure();
auto ptrType = llvm::dyn_cast<spirv::PointerType>(type);
if (!ptrType)
return parser.emitError(loc, "expected pointer type");
if (parser.resolveOperands(operandInfo, {ptrType, ptrType.getPointeeType()},
parser.getNameLoc(), result.operands))
return failure();
return parser.addTypeToList(ptrType.getPointeeType(), result.types);
}
LogicalResult AtomicExchangeOp::verify() {
if (getType() != getValue().getType())
return emitOpError("value operand must have the same type as the op "
"result, but found ")
<< getValue().getType() << " vs " << getType();
Type pointeeType =
llvm::cast<spirv::PointerType>(getPointer().getType()).getPointeeType();
if (getType() != pointeeType)
return emitOpError("pointer operand's pointee type must have the same "
"as the op result type, but found ")
<< pointeeType << " vs " << getType();
return success();
}
//===----------------------------------------------------------------------===//
// spirv.AtomicIAddOp
//===----------------------------------------------------------------------===//
@@ -283,12 +67,6 @@ LogicalResult AtomicIAddOp::verify() {
return verifyAtomicUpdateOp<IntegerType>(getOperation());
}
ParseResult AtomicIAddOp::parse(OpAsmParser &parser, OperationState &result) {
return parseAtomicUpdateOp(parser, result, true);
}
void AtomicIAddOp::print(OpAsmPrinter &p) { printAtomicUpdateOp(*this, p); }
//===----------------------------------------------------------------------===//
// spirv.EXT.AtomicFAddOp
//===----------------------------------------------------------------------===//
@@ -297,15 +75,6 @@ LogicalResult EXTAtomicFAddOp::verify() {
return verifyAtomicUpdateOp<FloatType>(getOperation());
}
ParseResult EXTAtomicFAddOp::parse(OpAsmParser &parser,
OperationState &result) {
return parseAtomicUpdateOp(parser, result, true);
}
void spirv::EXTAtomicFAddOp::print(OpAsmPrinter &p) {
printAtomicUpdateOp(*this, p);
}
//===----------------------------------------------------------------------===//
// spirv.AtomicIDecrementOp
//===----------------------------------------------------------------------===//
@@ -314,15 +83,6 @@ LogicalResult AtomicIDecrementOp::verify() {
return verifyAtomicUpdateOp<IntegerType>(getOperation());
}
ParseResult AtomicIDecrementOp::parse(OpAsmParser &parser,
OperationState &result) {
return parseAtomicUpdateOp(parser, result, false);
}
void AtomicIDecrementOp::print(OpAsmPrinter &p) {
printAtomicUpdateOp(*this, p);
}
//===----------------------------------------------------------------------===//
// spirv.AtomicIIncrementOp
//===----------------------------------------------------------------------===//
@@ -331,15 +91,6 @@ LogicalResult AtomicIIncrementOp::verify() {
return verifyAtomicUpdateOp<IntegerType>(getOperation());
}
ParseResult AtomicIIncrementOp::parse(OpAsmParser &parser,
OperationState &result) {
return parseAtomicUpdateOp(parser, result, false);
}
void AtomicIIncrementOp::print(OpAsmPrinter &p) {
printAtomicUpdateOp(*this, p);
}
//===----------------------------------------------------------------------===//
// spirv.AtomicISubOp
//===----------------------------------------------------------------------===//
@@ -348,12 +99,6 @@ LogicalResult AtomicISubOp::verify() {
return verifyAtomicUpdateOp<IntegerType>(getOperation());
}
ParseResult AtomicISubOp::parse(OpAsmParser &parser, OperationState &result) {
return parseAtomicUpdateOp(parser, result, true);
}
void AtomicISubOp::print(OpAsmPrinter &p) { printAtomicUpdateOp(*this, p); }
//===----------------------------------------------------------------------===//
// spirv.AtomicOrOp
//===----------------------------------------------------------------------===//
@@ -362,12 +107,6 @@ LogicalResult AtomicOrOp::verify() {
return verifyAtomicUpdateOp<IntegerType>(getOperation());
}
ParseResult AtomicOrOp::parse(OpAsmParser &parser, OperationState &result) {
return parseAtomicUpdateOp(parser, result, true);
}
void AtomicOrOp::print(OpAsmPrinter &p) { printAtomicUpdateOp(*this, p); }
//===----------------------------------------------------------------------===//
// spirv.AtomicSMaxOp
//===----------------------------------------------------------------------===//
@@ -376,12 +115,6 @@ LogicalResult AtomicSMaxOp::verify() {
return verifyAtomicUpdateOp<IntegerType>(getOperation());
}
ParseResult AtomicSMaxOp::parse(OpAsmParser &parser, OperationState &result) {
return parseAtomicUpdateOp(parser, result, true);
}
void AtomicSMaxOp::print(OpAsmPrinter &p) { printAtomicUpdateOp(*this, p); }
//===----------------------------------------------------------------------===//
// spirv.AtomicSMinOp
//===----------------------------------------------------------------------===//
@@ -390,12 +123,6 @@ LogicalResult AtomicSMinOp::verify() {
return verifyAtomicUpdateOp<IntegerType>(getOperation());
}
ParseResult AtomicSMinOp::parse(OpAsmParser &parser, OperationState &result) {
return parseAtomicUpdateOp(parser, result, true);
}
void AtomicSMinOp::print(OpAsmPrinter &p) { printAtomicUpdateOp(*this, p); }
//===----------------------------------------------------------------------===//
// spirv.AtomicUMaxOp
//===----------------------------------------------------------------------===//
@@ -404,12 +131,6 @@ LogicalResult AtomicUMaxOp::verify() {
return verifyAtomicUpdateOp<IntegerType>(getOperation());
}
ParseResult AtomicUMaxOp::parse(OpAsmParser &parser, OperationState &result) {
return parseAtomicUpdateOp(parser, result, true);
}
void AtomicUMaxOp::print(OpAsmPrinter &p) { printAtomicUpdateOp(*this, p); }
//===----------------------------------------------------------------------===//
// spirv.AtomicUMinOp
//===----------------------------------------------------------------------===//
@@ -418,12 +139,6 @@ LogicalResult AtomicUMinOp::verify() {
return verifyAtomicUpdateOp<IntegerType>(getOperation());
}
ParseResult AtomicUMinOp::parse(OpAsmParser &parser, OperationState &result) {
return parseAtomicUpdateOp(parser, result, true);
}
void AtomicUMinOp::print(OpAsmPrinter &p) { printAtomicUpdateOp(*this, p); }
//===----------------------------------------------------------------------===//
// spirv.AtomicXorOp
//===----------------------------------------------------------------------===//
@@ -432,10 +147,4 @@ LogicalResult AtomicXorOp::verify() {
return verifyAtomicUpdateOp<IntegerType>(getOperation());
}
ParseResult AtomicXorOp::parse(OpAsmParser &parser, OperationState &result) {
return parseAtomicUpdateOp(parser, result, true);
}
void AtomicXorOp::print(OpAsmPrinter &p) { printAtomicUpdateOp(*this, p); }
} // namespace mlir::spirv

View File

@@ -48,8 +48,8 @@ module attributes {
// CHECK: %{{.+}} = spirv.Load "Workgroup" %[[PTR]] : i32
// CHECK: %[[LOC:.+]] = spirv.SDiv
// CHECK: %[[PTR:.+]] = spirv.AccessChain %[[VAR]][%{{.+}}, %[[LOC]]]
// CHECK: %{{.+}} = spirv.AtomicAnd "Workgroup" "AcquireRelease" %[[PTR]], %{{.+}} : !spirv.ptr<i32, Workgroup>
// CHECK: %{{.+}} = spirv.AtomicOr "Workgroup" "AcquireRelease" %[[PTR]], %{{.+}} : !spirv.ptr<i32, Workgroup>
// CHECK: %{{.+}} = spirv.AtomicAnd <Workgroup> <AcquireRelease> %[[PTR]], %{{.+}} : !spirv.ptr<i32, Workgroup>
// CHECK: %{{.+}} = spirv.AtomicOr <Workgroup> <AcquireRelease> %[[PTR]], %{{.+}} : !spirv.ptr<i32, Workgroup>
// -----

View File

@@ -6,7 +6,7 @@ module attributes {spirv.target_env = #spirv.target_env<#spirv.vce<v1.3, [Shader
// CHECK-SAME: (%[[VAL:.+]]: i32,
func.func @atomic_addi_storage_buffer(%value: i32, %memref: memref<2x3x4xi32, #spirv.storage_class<StorageBuffer>>, %i0: index, %i1: index, %i2: index) -> i32 {
// CHECK: %[[AC:.+]] = spirv.AccessChain
// CHECK: %[[ATOMIC:.+]] = spirv.AtomicIAdd "Device" "AcquireRelease" %[[AC]], %[[VAL]] : !spirv.ptr<i32, StorageBuffer>
// CHECK: %[[ATOMIC:.+]] = spirv.AtomicIAdd <Device> <AcquireRelease> %[[AC]], %[[VAL]] : !spirv.ptr<i32, StorageBuffer>
// CHECK: return %[[ATOMIC]]
%0 = memref.atomic_rmw "addi" %value, %memref[%i0, %i1, %i2] : (i32, memref<2x3x4xi32, #spirv.storage_class<StorageBuffer>>) -> i32
return %0: i32
@@ -16,7 +16,7 @@ func.func @atomic_addi_storage_buffer(%value: i32, %memref: memref<2x3x4xi32, #s
// CHECK-SAME: (%[[VAL:.+]]: i32,
func.func @atomic_maxs_workgroup(%value: i32, %memref: memref<2x3x4xi32, #spirv.storage_class<Workgroup>>, %i0: index, %i1: index, %i2: index) -> i32 {
// CHECK: %[[AC:.+]] = spirv.AccessChain
// CHECK: %[[ATOMIC:.+]] = spirv.AtomicSMax "Workgroup" "AcquireRelease" %[[AC]], %[[VAL]] : !spirv.ptr<i32, Workgroup>
// CHECK: %[[ATOMIC:.+]] = spirv.AtomicSMax <Workgroup> <AcquireRelease> %[[AC]], %[[VAL]] : !spirv.ptr<i32, Workgroup>
// CHECK: return %[[ATOMIC]]
%0 = memref.atomic_rmw "maxs" %value, %memref[%i0, %i1, %i2] : (i32, memref<2x3x4xi32, #spirv.storage_class<Workgroup>>) -> i32
return %0: i32
@@ -26,7 +26,7 @@ func.func @atomic_maxs_workgroup(%value: i32, %memref: memref<2x3x4xi32, #spirv.
// CHECK-SAME: (%[[VAL:.+]]: i32,
func.func @atomic_maxu_storage_buffer(%value: i32, %memref: memref<2x3x4xi32, #spirv.storage_class<StorageBuffer>>, %i0: index, %i1: index, %i2: index) -> i32 {
// CHECK: %[[AC:.+]] = spirv.AccessChain
// CHECK: %[[ATOMIC:.+]] = spirv.AtomicUMax "Device" "AcquireRelease" %[[AC]], %[[VAL]] : !spirv.ptr<i32, StorageBuffer>
// CHECK: %[[ATOMIC:.+]] = spirv.AtomicUMax <Device> <AcquireRelease> %[[AC]], %[[VAL]] : !spirv.ptr<i32, StorageBuffer>
// CHECK: return %[[ATOMIC]]
%0 = memref.atomic_rmw "maxu" %value, %memref[%i0, %i1, %i2] : (i32, memref<2x3x4xi32, #spirv.storage_class<StorageBuffer>>) -> i32
return %0: i32
@@ -36,7 +36,7 @@ func.func @atomic_maxu_storage_buffer(%value: i32, %memref: memref<2x3x4xi32, #s
// CHECK-SAME: (%[[VAL:.+]]: i32,
func.func @atomic_mins_workgroup(%value: i32, %memref: memref<2x3x4xi32, #spirv.storage_class<Workgroup>>, %i0: index, %i1: index, %i2: index) -> i32 {
// CHECK: %[[AC:.+]] = spirv.AccessChain
// CHECK: %[[ATOMIC:.+]] = spirv.AtomicSMin "Workgroup" "AcquireRelease" %[[AC]], %[[VAL]] : !spirv.ptr<i32, Workgroup>
// CHECK: %[[ATOMIC:.+]] = spirv.AtomicSMin <Workgroup> <AcquireRelease> %[[AC]], %[[VAL]] : !spirv.ptr<i32, Workgroup>
// CHECK: return %[[ATOMIC]]
%0 = memref.atomic_rmw "mins" %value, %memref[%i0, %i1, %i2] : (i32, memref<2x3x4xi32, #spirv.storage_class<Workgroup>>) -> i32
return %0: i32
@@ -46,7 +46,7 @@ func.func @atomic_mins_workgroup(%value: i32, %memref: memref<2x3x4xi32, #spirv.
// CHECK-SAME: (%[[VAL:.+]]: i32,
func.func @atomic_minu_storage_buffer(%value: i32, %memref: memref<2x3x4xi32, #spirv.storage_class<StorageBuffer>>, %i0: index, %i1: index, %i2: index) -> i32 {
// CHECK: %[[AC:.+]] = spirv.AccessChain
// CHECK: %[[ATOMIC:.+]] = spirv.AtomicUMin "Device" "AcquireRelease" %[[AC]], %[[VAL]] : !spirv.ptr<i32, StorageBuffer>
// CHECK: %[[ATOMIC:.+]] = spirv.AtomicUMin <Device> <AcquireRelease> %[[AC]], %[[VAL]] : !spirv.ptr<i32, StorageBuffer>
// CHECK: return %[[ATOMIC]]
%0 = memref.atomic_rmw "minu" %value, %memref[%i0, %i1, %i2] : (i32, memref<2x3x4xi32, #spirv.storage_class<StorageBuffer>>) -> i32
return %0: i32
@@ -56,7 +56,7 @@ func.func @atomic_minu_storage_buffer(%value: i32, %memref: memref<2x3x4xi32, #s
// CHECK-SAME: (%[[VAL:.+]]: i32,
func.func @atomic_ori_workgroup(%value: i32, %memref: memref<2x3x4xi32, #spirv.storage_class<Workgroup>>, %i0: index, %i1: index, %i2: index) -> i32 {
// CHECK: %[[AC:.+]] = spirv.AccessChain
// CHECK: %[[ATOMIC:.+]] = spirv.AtomicOr "Workgroup" "AcquireRelease" %[[AC]], %[[VAL]] : !spirv.ptr<i32, Workgroup>
// CHECK: %[[ATOMIC:.+]] = spirv.AtomicOr <Workgroup> <AcquireRelease> %[[AC]], %[[VAL]] : !spirv.ptr<i32, Workgroup>
// CHECK: return %[[ATOMIC]]
%0 = memref.atomic_rmw "ori" %value, %memref[%i0, %i1, %i2] : (i32, memref<2x3x4xi32, #spirv.storage_class<Workgroup>>) -> i32
return %0: i32
@@ -66,7 +66,7 @@ func.func @atomic_ori_workgroup(%value: i32, %memref: memref<2x3x4xi32, #spirv.s
// CHECK-SAME: (%[[VAL:.+]]: i32,
func.func @atomic_andi_storage_buffer(%value: i32, %memref: memref<2x3x4xi32, #spirv.storage_class<StorageBuffer>>, %i0: index, %i1: index, %i2: index) -> i32 {
// CHECK: %[[AC:.+]] = spirv.AccessChain
// CHECK: %[[ATOMIC:.+]] = spirv.AtomicAnd "Device" "AcquireRelease" %[[AC]], %[[VAL]] : !spirv.ptr<i32, StorageBuffer>
// CHECK: %[[ATOMIC:.+]] = spirv.AtomicAnd <Device> <AcquireRelease> %[[AC]], %[[VAL]] : !spirv.ptr<i32, StorageBuffer>
// CHECK: return %[[ATOMIC]]
%0 = memref.atomic_rmw "andi" %value, %memref[%i0, %i1, %i2] : (i32, memref<2x3x4xi32, #spirv.storage_class<StorageBuffer>>) -> i32
return %0: i32

View File

@@ -122,8 +122,8 @@ func.func @store_i1(%arg0: memref<i1, #spirv.storage_class<StorageBuffer>>, %val
// CHECK: %[[STORE_VAL:.+]] = spirv.ShiftLeftLogical %[[CASTED_ARG1]], %[[OFFSET]] : i32, i32
// CHECK: %[[ACCESS_IDX:.+]] = spirv.SDiv %[[ZERO]], %[[FOUR]] : i32
// CHECK: %[[PTR:.+]] = spirv.AccessChain %[[ARG0_CAST]][%[[ZERO]], %[[ACCESS_IDX]]]
// CHECK: spirv.AtomicAnd "Device" "AcquireRelease" %[[PTR]], %[[MASK]]
// CHECK: spirv.AtomicOr "Device" "AcquireRelease" %[[PTR]], %[[STORE_VAL]]
// CHECK: spirv.AtomicAnd <Device> <AcquireRelease> %[[PTR]], %[[MASK]]
// CHECK: spirv.AtomicOr <Device> <AcquireRelease> %[[PTR]], %[[STORE_VAL]]
memref.store %value, %arg0[] : memref<i1, #spirv.storage_class<StorageBuffer>>
return
}
@@ -147,8 +147,8 @@ func.func @store_i8(%arg0: memref<i8, #spirv.storage_class<StorageBuffer>>, %val
// CHECK: %[[STORE_VAL:.+]] = spirv.ShiftLeftLogical %[[CLAMPED_VAL]], %[[OFFSET]] : i32, i32
// CHECK: %[[ACCESS_IDX:.+]] = spirv.SDiv %[[ZERO]], %[[FOUR]] : i32
// CHECK: %[[PTR:.+]] = spirv.AccessChain %[[ARG0_CAST]][%[[ZERO]], %[[ACCESS_IDX]]]
// CHECK: spirv.AtomicAnd "Device" "AcquireRelease" %[[PTR]], %[[MASK]]
// CHECK: spirv.AtomicOr "Device" "AcquireRelease" %[[PTR]], %[[STORE_VAL]]
// CHECK: spirv.AtomicAnd <Device> <AcquireRelease> %[[PTR]], %[[MASK]]
// CHECK: spirv.AtomicOr <Device> <AcquireRelease> %[[PTR]], %[[STORE_VAL]]
// INDEX64-DAG: %[[ARG1_CAST:.+]] = builtin.unrealized_conversion_cast %[[ARG1]] : i8 to i32
// INDEX64-DAG: %[[ARG0_CAST:.+]] = builtin.unrealized_conversion_cast %[[ARG0]]
@@ -164,8 +164,8 @@ func.func @store_i8(%arg0: memref<i8, #spirv.storage_class<StorageBuffer>>, %val
// INDEX64: %[[STORE_VAL:.+]] = spirv.ShiftLeftLogical %[[CLAMPED_VAL]], %[[OFFSET]] : i32, i64
// INDEX64: %[[ACCESS_IDX:.+]] = spirv.SDiv %[[ZERO]], %[[FOUR]] : i64
// INDEX64: %[[PTR:.+]] = spirv.AccessChain %[[ARG0_CAST]][%[[ZERO]], %[[ACCESS_IDX]]] : {{.+}}, i64, i64
// INDEX64: spirv.AtomicAnd "Device" "AcquireRelease" %[[PTR]], %[[MASK]]
// INDEX64: spirv.AtomicOr "Device" "AcquireRelease" %[[PTR]], %[[STORE_VAL]]
// INDEX64: spirv.AtomicAnd <Device> <AcquireRelease> %[[PTR]], %[[MASK]]
// INDEX64: spirv.AtomicOr <Device> <AcquireRelease> %[[PTR]], %[[STORE_VAL]]
memref.store %value, %arg0[] : memref<i8, #spirv.storage_class<StorageBuffer>>
return
}
@@ -191,8 +191,8 @@ func.func @store_i16(%arg0: memref<10xi16, #spirv.storage_class<StorageBuffer>>,
// CHECK: %[[STORE_VAL:.+]] = spirv.ShiftLeftLogical %[[CLAMPED_VAL]], %[[OFFSET]] : i32, i32
// CHECK: %[[ACCESS_IDX:.+]] = spirv.SDiv %[[FLAT_IDX]], %[[TWO]] : i32
// CHECK: %[[PTR:.+]] = spirv.AccessChain %[[ARG0_CAST]][%[[ZERO]], %[[ACCESS_IDX]]]
// CHECK: spirv.AtomicAnd "Device" "AcquireRelease" %[[PTR]], %[[MASK]]
// CHECK: spirv.AtomicOr "Device" "AcquireRelease" %[[PTR]], %[[STORE_VAL]]
// CHECK: spirv.AtomicAnd <Device> <AcquireRelease> %[[PTR]], %[[MASK]]
// CHECK: spirv.AtomicOr <Device> <AcquireRelease> %[[PTR]], %[[STORE_VAL]]
memref.store %value, %arg0[%index] : memref<10xi16, #spirv.storage_class<StorageBuffer>>
return
}
@@ -262,8 +262,8 @@ func.func @store_i4(%arg0: memref<?xi4, #spirv.storage_class<StorageBuffer>>, %v
// CHECK: %[[STORE_VAL:.+]] = spirv.ShiftLeftLogical %[[CLAMPED_VAL]], %[[BITS]] : i32, i32
// CHECK: %[[ACCESS_INDEX:.+]] = spirv.SDiv %[[OFFSET]], %[[EIGHT]] : i32
// CHECK: %[[PTR:.+]] = spirv.AccessChain %{{.+}}[%[[ZERO]], %[[ACCESS_INDEX]]]
// CHECK: spirv.AtomicAnd "Device" "AcquireRelease" %[[PTR]], %[[MASK2]]
// CHECK: spirv.AtomicOr "Device" "AcquireRelease" %[[PTR]], %[[STORE_VAL]]
// CHECK: spirv.AtomicAnd <Device> <AcquireRelease> %[[PTR]], %[[MASK2]]
// CHECK: spirv.AtomicOr <Device> <AcquireRelease> %[[PTR]], %[[STORE_VAL]]
memref.store %value, %arg0[%i] : memref<?xi4, #spirv.storage_class<StorageBuffer>>
return
}
@@ -338,8 +338,8 @@ func.func @store_i8(%arg0: memref<i8, #spirv.storage_class<StorageBuffer>>, %val
// CHECK: %[[STORE_VAL:.+]] = spirv.ShiftLeftLogical %[[CLAMPED_VAL]], %[[OFFSET]] : i32, i32
// CHECK: %[[ACCESS_IDX:.+]] = spirv.SDiv %[[ZERO]], %[[FOUR]] : i32
// CHECK: %[[PTR:.+]] = spirv.AccessChain %[[ARG0_CAST]][%[[ZERO]], %[[ACCESS_IDX]]]
// CHECK: spirv.AtomicAnd "Device" "AcquireRelease" %[[PTR]], %[[MASK]]
// CHECK: spirv.AtomicOr "Device" "AcquireRelease" %[[PTR]], %[[STORE_VAL]]
// CHECK: spirv.AtomicAnd <Device> <AcquireRelease> %[[PTR]], %[[MASK]]
// CHECK: spirv.AtomicOr <Device> <AcquireRelease> %[[PTR]], %[[STORE_VAL]]
// INDEX64-DAG: %[[ARG0_CAST:.+]] = builtin.unrealized_conversion_cast %[[ARG0]]
// INDEX64: %[[ZERO:.+]] = spirv.Constant 0 : i64
@@ -355,8 +355,8 @@ func.func @store_i8(%arg0: memref<i8, #spirv.storage_class<StorageBuffer>>, %val
// INDEX64: %[[STORE_VAL:.+]] = spirv.ShiftLeftLogical %[[CLAMPED_VAL]], %[[OFFSET]] : i32, i64
// INDEX64: %[[ACCESS_IDX:.+]] = spirv.SDiv %[[ZERO]], %[[FOUR]] : i64
// INDEX64: %[[PTR:.+]] = spirv.AccessChain %[[ARG0_CAST]][%[[ZERO]], %[[ACCESS_IDX]]] : {{.+}}, i64, i64
// INDEX64: spirv.AtomicAnd "Device" "AcquireRelease" %[[PTR]], %[[MASK]]
// INDEX64: spirv.AtomicOr "Device" "AcquireRelease" %[[PTR]], %[[STORE_VAL]]
// INDEX64: spirv.AtomicAnd <Device> <AcquireRelease> %[[PTR]], %[[MASK]]
// INDEX64: spirv.AtomicOr <Device> <AcquireRelease> %[[PTR]], %[[STORE_VAL]]
memref.store %value, %arg0[] : memref<i8, #spirv.storage_class<StorageBuffer>>
return
}

View File

@@ -5,15 +5,15 @@
//===----------------------------------------------------------------------===//
func.func @atomic_and(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32 {
// CHECK: spirv.AtomicAnd "Device" "None" %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicAnd "Device" "None" %ptr, %value : !spirv.ptr<i32, StorageBuffer>
// CHECK: spirv.AtomicAnd <Device> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicAnd <Device> <None> %ptr, %value : !spirv.ptr<i32, StorageBuffer>
return %0 : i32
}
// -----
func.func @atomic_and(%ptr : !spirv.ptr<f32, StorageBuffer>, %value : i32) -> i32 {
// expected-error @+1 {{pointer operand must point to an integer value, found 'f32'}}
// expected-error @+1 {{'spirv.AtomicAnd' op failed to verify that `value` type matches pointee type of `pointer`}}
%0 = "spirv.AtomicAnd"(%ptr, %value) {memory_scope = #spirv.scope<Workgroup>, semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<f32, StorageBuffer>, i32) -> (i32)
return %0 : i32
}
@@ -22,7 +22,7 @@ func.func @atomic_and(%ptr : !spirv.ptr<f32, StorageBuffer>, %value : i32) -> i3
// -----
func.func @atomic_and(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i64) -> i64 {
// expected-error @+1 {{expected value to have the same type as the pointer operand's pointee type 'i32', but found 'i64'}}
// expected-error @+1 {{'spirv.AtomicAnd' op failed to verify that `value` type matches pointee type of `pointer`}}
%0 = "spirv.AtomicAnd"(%ptr, %value) {memory_scope = #spirv.scope<Workgroup>, semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<i32, StorageBuffer>, i64) -> (i64)
return %0 : i64
}
@@ -31,7 +31,7 @@ func.func @atomic_and(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i64) -> i6
func.func @atomic_and(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32 {
// expected-error @+1 {{expected at most one of these four memory constraints to be set: `Acquire`, `Release`,`AcquireRelease` or `SequentiallyConsistent`}}
%0 = spirv.AtomicAnd "Device" "Acquire|Release" %ptr, %value : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicAnd <Device> <Acquire|Release> %ptr, %value : !spirv.ptr<i32, StorageBuffer>
return %0 : i32
}
@@ -42,15 +42,15 @@ func.func @atomic_and(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i3
//===----------------------------------------------------------------------===//
func.func @atomic_compare_exchange(%ptr: !spirv.ptr<i32, Workgroup>, %value: i32, %comparator: i32) -> i32 {
// CHECK: spirv.AtomicCompareExchange "Workgroup" "Release" "Acquire" %{{.*}}, %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%0 = spirv.AtomicCompareExchange "Workgroup" "Release" "Acquire" %ptr, %value, %comparator: !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicCompareExchange <Workgroup> <Release> <Acquire> %{{.*}}, %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%0 = spirv.AtomicCompareExchange <Workgroup> <Release> <Acquire> %ptr, %value, %comparator: !spirv.ptr<i32, Workgroup>
return %0: i32
}
// -----
func.func @atomic_compare_exchange(%ptr: !spirv.ptr<i32, Workgroup>, %value: i64, %comparator: i32) -> i32 {
// expected-error @+1 {{value operand must have the same type as the op result, but found 'i64' vs 'i32'}}
// expected-error @+1 {{'spirv.AtomicCompareExchange' op failed to verify that `value` type matches pointee type of `pointer`}}
%0 = "spirv.AtomicCompareExchange"(%ptr, %value, %comparator) {memory_scope = #spirv.scope<Workgroup>, equal_semantics = #spirv.memory_semantics<AcquireRelease>, unequal_semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<i32, Workgroup>, i64, i32) -> (i32)
return %0: i32
}
@@ -58,7 +58,7 @@ func.func @atomic_compare_exchange(%ptr: !spirv.ptr<i32, Workgroup>, %value: i64
// -----
func.func @atomic_compare_exchange(%ptr: !spirv.ptr<i32, Workgroup>, %value: i32, %comparator: i16) -> i32 {
// expected-error @+1 {{comparator operand must have the same type as the op result, but found 'i16' vs 'i32'}}
// expected-error @+1 {{'spirv.AtomicCompareExchange' op failed to verify that `comparator` type matches pointee type of `pointer`}}
%0 = "spirv.AtomicCompareExchange"(%ptr, %value, %comparator) {memory_scope = #spirv.scope<Workgroup>, equal_semantics = #spirv.memory_semantics<AcquireRelease>, unequal_semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<i32, Workgroup>, i32, i16) -> (i32)
return %0: i32
}
@@ -66,7 +66,7 @@ func.func @atomic_compare_exchange(%ptr: !spirv.ptr<i32, Workgroup>, %value: i32
// -----
func.func @atomic_compare_exchange(%ptr: !spirv.ptr<i64, Workgroup>, %value: i32, %comparator: i32) -> i32 {
// expected-error @+1 {{pointer operand's pointee type must have the same as the op result type, but found 'i64' vs 'i32'}}
// expected-error @+1 {{spirv.AtomicCompareExchange' op failed to verify that `result` type matches pointee type of `pointer`}}
%0 = "spirv.AtomicCompareExchange"(%ptr, %value, %comparator) {memory_scope = #spirv.scope<Workgroup>, equal_semantics = #spirv.memory_semantics<AcquireRelease>, unequal_semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<i64, Workgroup>, i32, i32) -> (i32)
return %0: i32
}
@@ -78,15 +78,15 @@ func.func @atomic_compare_exchange(%ptr: !spirv.ptr<i64, Workgroup>, %value: i32
//===----------------------------------------------------------------------===//
func.func @atomic_compare_exchange_weak(%ptr: !spirv.ptr<i32, Workgroup>, %value: i32, %comparator: i32) -> i32 {
// CHECK: spirv.AtomicCompareExchangeWeak "Workgroup" "Release" "Acquire" %{{.*}}, %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%0 = spirv.AtomicCompareExchangeWeak "Workgroup" "Release" "Acquire" %ptr, %value, %comparator: !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicCompareExchangeWeak <Workgroup> <Release> <Acquire> %{{.*}}, %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%0 = spirv.AtomicCompareExchangeWeak <Workgroup> <Release> <Acquire> %ptr, %value, %comparator: !spirv.ptr<i32, Workgroup>
return %0: i32
}
// -----
func.func @atomic_compare_exchange_weak(%ptr: !spirv.ptr<i32, Workgroup>, %value: i64, %comparator: i32) -> i32 {
// expected-error @+1 {{value operand must have the same type as the op result, but found 'i64' vs 'i32'}}
// expected-error @+1 {{'spirv.AtomicCompareExchangeWeak' op failed to verify that `value` type matches pointee type of `pointer`}}
%0 = "spirv.AtomicCompareExchangeWeak"(%ptr, %value, %comparator) {memory_scope = #spirv.scope<Workgroup>, equal_semantics = #spirv.memory_semantics<AcquireRelease>, unequal_semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<i32, Workgroup>, i64, i32) -> (i32)
return %0: i32
}
@@ -94,7 +94,7 @@ func.func @atomic_compare_exchange_weak(%ptr: !spirv.ptr<i32, Workgroup>, %value
// -----
func.func @atomic_compare_exchange_weak(%ptr: !spirv.ptr<i32, Workgroup>, %value: i32, %comparator: i16) -> i32 {
// expected-error @+1 {{comparator operand must have the same type as the op result, but found 'i16' vs 'i32'}}
// expected-error @+1 {{'spirv.AtomicCompareExchangeWeak' op failed to verify that `comparator` type matches pointee type of `pointer`}}
%0 = "spirv.AtomicCompareExchangeWeak"(%ptr, %value, %comparator) {memory_scope = #spirv.scope<Workgroup>, equal_semantics = #spirv.memory_semantics<AcquireRelease>, unequal_semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<i32, Workgroup>, i32, i16) -> (i32)
return %0: i32
}
@@ -102,7 +102,7 @@ func.func @atomic_compare_exchange_weak(%ptr: !spirv.ptr<i32, Workgroup>, %value
// -----
func.func @atomic_compare_exchange_weak(%ptr: !spirv.ptr<i64, Workgroup>, %value: i32, %comparator: i32) -> i32 {
// expected-error @+1 {{pointer operand's pointee type must have the same as the op result type, but found 'i64' vs 'i32'}}
// expected-error @+1 {{'spirv.AtomicCompareExchangeWeak' op failed to verify that `result` type matches pointee type of `pointer`}}
%0 = "spirv.AtomicCompareExchangeWeak"(%ptr, %value, %comparator) {memory_scope = #spirv.scope<Workgroup>, equal_semantics = #spirv.memory_semantics<AcquireRelease>, unequal_semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<i64, Workgroup>, i32, i32) -> (i32)
return %0: i32
}
@@ -114,15 +114,15 @@ func.func @atomic_compare_exchange_weak(%ptr: !spirv.ptr<i64, Workgroup>, %value
//===----------------------------------------------------------------------===//
func.func @atomic_exchange(%ptr: !spirv.ptr<i32, Workgroup>, %value: i32) -> i32 {
// CHECK: spirv.AtomicExchange "Workgroup" "Release" %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%0 = spirv.AtomicExchange "Workgroup" "Release" %ptr, %value: !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicExchange <Workgroup> <Release> %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%0 = spirv.AtomicExchange <Workgroup> <Release> %ptr, %value: !spirv.ptr<i32, Workgroup>
return %0: i32
}
// -----
func.func @atomic_exchange(%ptr: !spirv.ptr<i32, Workgroup>, %value: i64) -> i32 {
// expected-error @+1 {{value operand must have the same type as the op result, but found 'i64' vs 'i32'}}
// expected-error @+1 {{'spirv.AtomicExchange' op failed to verify that `value` type matches pointee type of `pointer`}}
%0 = "spirv.AtomicExchange"(%ptr, %value) {memory_scope = #spirv.scope<Workgroup>, semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<i32, Workgroup>, i64) -> (i32)
return %0: i32
}
@@ -130,7 +130,7 @@ func.func @atomic_exchange(%ptr: !spirv.ptr<i32, Workgroup>, %value: i64) -> i32
// -----
func.func @atomic_exchange(%ptr: !spirv.ptr<i64, Workgroup>, %value: i32) -> i32 {
// expected-error @+1 {{pointer operand's pointee type must have the same as the op result type, but found 'i64' vs 'i32'}}
// expected-error @+1 {{'spirv.AtomicExchange' op failed to verify that `value` type matches pointee type of `pointer`}}
%0 = "spirv.AtomicExchange"(%ptr, %value) {memory_scope = #spirv.scope<Workgroup>, semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<i64, Workgroup>, i32) -> (i32)
return %0: i32
}
@@ -142,8 +142,8 @@ func.func @atomic_exchange(%ptr: !spirv.ptr<i64, Workgroup>, %value: i32) -> i32
//===----------------------------------------------------------------------===//
func.func @atomic_iadd(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32 {
// CHECK: spirv.AtomicIAdd "Workgroup" "None" %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicIAdd "Workgroup" "None" %ptr, %value : !spirv.ptr<i32, StorageBuffer>
// CHECK: spirv.AtomicIAdd <Workgroup> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicIAdd <Workgroup> <None> %ptr, %value : !spirv.ptr<i32, StorageBuffer>
return %0 : i32
}
@@ -152,8 +152,8 @@ func.func @atomic_iadd(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i
//===----------------------------------------------------------------------===//
func.func @atomic_idecrement(%ptr : !spirv.ptr<i32, StorageBuffer>) -> i32 {
// CHECK: spirv.AtomicIDecrement "Workgroup" "None" %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicIDecrement "Workgroup" "None" %ptr : !spirv.ptr<i32, StorageBuffer>
// CHECK: spirv.AtomicIDecrement <Workgroup> <None> %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicIDecrement <Workgroup> <None> %ptr : !spirv.ptr<i32, StorageBuffer>
return %0 : i32
}
@@ -162,8 +162,8 @@ func.func @atomic_idecrement(%ptr : !spirv.ptr<i32, StorageBuffer>) -> i32 {
//===----------------------------------------------------------------------===//
func.func @atomic_iincrement(%ptr : !spirv.ptr<i32, StorageBuffer>) -> i32 {
// CHECK: spirv.AtomicIIncrement "Workgroup" "None" %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicIIncrement "Workgroup" "None" %ptr : !spirv.ptr<i32, StorageBuffer>
// CHECK: spirv.AtomicIIncrement <Workgroup> <None> %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicIIncrement <Workgroup> <None> %ptr : !spirv.ptr<i32, StorageBuffer>
return %0 : i32
}
@@ -172,8 +172,8 @@ func.func @atomic_iincrement(%ptr : !spirv.ptr<i32, StorageBuffer>) -> i32 {
//===----------------------------------------------------------------------===//
func.func @atomic_isub(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32 {
// CHECK: spirv.AtomicISub "Workgroup" "None" %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicISub "Workgroup" "None" %ptr, %value : !spirv.ptr<i32, StorageBuffer>
// CHECK: spirv.AtomicISub <Workgroup> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicISub <Workgroup> <None> %ptr, %value : !spirv.ptr<i32, StorageBuffer>
return %0 : i32
}
@@ -182,8 +182,8 @@ func.func @atomic_isub(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i
//===----------------------------------------------------------------------===//
func.func @atomic_or(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32 {
// CHECK: spirv.AtomicOr "Workgroup" "None" %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicOr "Workgroup" "None" %ptr, %value : !spirv.ptr<i32, StorageBuffer>
// CHECK: spirv.AtomicOr <Workgroup> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicOr <Workgroup> <None> %ptr, %value : !spirv.ptr<i32, StorageBuffer>
return %0 : i32
}
@@ -192,8 +192,8 @@ func.func @atomic_or(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32
//===----------------------------------------------------------------------===//
func.func @atomic_smax(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32 {
// CHECK: spirv.AtomicSMax "Workgroup" "None" %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicSMax "Workgroup" "None" %ptr, %value : !spirv.ptr<i32, StorageBuffer>
// CHECK: spirv.AtomicSMax <Workgroup> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicSMax <Workgroup> <None> %ptr, %value : !spirv.ptr<i32, StorageBuffer>
return %0 : i32
}
@@ -202,8 +202,8 @@ func.func @atomic_smax(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i
//===----------------------------------------------------------------------===//
func.func @atomic_smin(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32 {
// CHECK: spirv.AtomicSMin "Workgroup" "None" %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicSMin "Workgroup" "None" %ptr, %value : !spirv.ptr<i32, StorageBuffer>
// CHECK: spirv.AtomicSMin <Workgroup> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicSMin <Workgroup> <None> %ptr, %value : !spirv.ptr<i32, StorageBuffer>
return %0 : i32
}
@@ -212,8 +212,8 @@ func.func @atomic_smin(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i
//===----------------------------------------------------------------------===//
func.func @atomic_umax(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32 {
// CHECK: spirv.AtomicUMax "Workgroup" "None" %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicUMax "Workgroup" "None" %ptr, %value : !spirv.ptr<i32, StorageBuffer>
// CHECK: spirv.AtomicUMax <Workgroup> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicUMax <Workgroup> <None> %ptr, %value : !spirv.ptr<i32, StorageBuffer>
return %0 : i32
}
@@ -222,8 +222,8 @@ func.func @atomic_umax(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i
//===----------------------------------------------------------------------===//
func.func @atomic_umin(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32 {
// CHECK: spirv.AtomicUMin "Workgroup" "None" %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicUMin "Workgroup" "None" %ptr, %value : !spirv.ptr<i32, StorageBuffer>
// CHECK: spirv.AtomicUMin <Workgroup> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicUMin <Workgroup> <None> %ptr, %value : !spirv.ptr<i32, StorageBuffer>
return %0 : i32
}
@@ -232,8 +232,8 @@ func.func @atomic_umin(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i
//===----------------------------------------------------------------------===//
func.func @atomic_xor(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32 {
// CHECK: spirv.AtomicXor "Workgroup" "None" %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicXor "Workgroup" "None" %ptr, %value : !spirv.ptr<i32, StorageBuffer>
// CHECK: spirv.AtomicXor <Workgroup> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicXor <Workgroup> <None> %ptr, %value : !spirv.ptr<i32, StorageBuffer>
return %0 : i32
}
@@ -244,15 +244,15 @@ func.func @atomic_xor(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i3
//===----------------------------------------------------------------------===//
func.func @atomic_fadd(%ptr : !spirv.ptr<f32, StorageBuffer>, %value : f32) -> f32 {
// CHECK: spirv.EXT.AtomicFAdd "Device" "None" %{{.*}}, %{{.*}} : !spirv.ptr<f32, StorageBuffer>
%0 = spirv.EXT.AtomicFAdd "Device" "None" %ptr, %value : !spirv.ptr<f32, StorageBuffer>
// CHECK: spirv.EXT.AtomicFAdd <Device> <None> %{{.*}}, %{{.*}} : !spirv.ptr<f32, StorageBuffer>
%0 = spirv.EXT.AtomicFAdd <Device> <None> %ptr, %value : !spirv.ptr<f32, StorageBuffer>
return %0 : f32
}
// -----
func.func @atomic_fadd(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : f32) -> f32 {
// expected-error @+1 {{pointer operand must point to an float value, found 'i32'}}
// expected-error @+1 {{'spirv.EXT.AtomicFAdd' op failed to verify that `result` type matches pointee type of `pointer`}}
%0 = "spirv.EXT.AtomicFAdd"(%ptr, %value) {memory_scope = #spirv.scope<Workgroup>, semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<i32, StorageBuffer>, f32) -> (f32)
return %0 : f32
}
@@ -260,7 +260,7 @@ func.func @atomic_fadd(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : f32) -> f
// -----
func.func @atomic_fadd(%ptr : !spirv.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'}}
// expected-error @+1 {{'spirv.EXT.AtomicFAdd' op failed to verify that `result` type matches pointee type of `pointer`}}
%0 = "spirv.EXT.AtomicFAdd"(%ptr, %value) {memory_scope = #spirv.scope<Device>, semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<f32, StorageBuffer>, f64) -> (f64)
return %0 : f64
}
@@ -269,6 +269,6 @@ func.func @atomic_fadd(%ptr : !spirv.ptr<f32, StorageBuffer>, %value : f64) -> f
func.func @atomic_fadd(%ptr : !spirv.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 = spirv.EXT.AtomicFAdd "Device" "Acquire|Release" %ptr, %value : !spirv.ptr<f32, StorageBuffer>
%0 = spirv.EXT.AtomicFAdd <Device> <Acquire|Release> %ptr, %value : !spirv.ptr<f32, StorageBuffer>
return %0 : f32
}

View File

@@ -16,7 +16,7 @@ func.func @atomic_compare_exchange_weak(%ptr: !spirv.ptr<i32, Workgroup>, %value
// CHECK: max version: v1.3
// CHECK: extensions: [ ]
// CHECK: capabilities: [ [Kernel] ]
%0 = spirv.AtomicCompareExchangeWeak "Workgroup" "Release" "Acquire" %ptr, %value, %comparator: !spirv.ptr<i32, Workgroup>
%0 = spirv.AtomicCompareExchangeWeak <Workgroup> <Release> <Acquire> %ptr, %value, %comparator: !spirv.ptr<i32, Workgroup>
return %0: i32
}

View File

@@ -49,7 +49,7 @@ func.func @main() {
func.func @cmp_exchange_weak_suitable_version_capabilities(%ptr: !spirv.ptr<i32, Workgroup>, %value: i32, %comparator: i32) -> i32 attributes {
spirv.target_env = #spirv.target_env<#spirv.vce<v1.1, [Kernel, AtomicStorage], []>, #spirv.resource_limits<>>
} {
// CHECK: spirv.AtomicCompareExchangeWeak "Workgroup" "AcquireRelease|AtomicCounterMemory" "Acquire"
// CHECK: spirv.AtomicCompareExchangeWeak <Workgroup> <AcquireRelease|AtomicCounterMemory> <Acquire>
%0 = "test.convert_to_atomic_compare_exchange_weak_op"(%ptr, %value, %comparator): (!spirv.ptr<i32, Workgroup>, i32, i32) -> (i32)
return %0: i32
}

View File

@@ -206,7 +206,7 @@ spirv.module Logical GLSL450 {
// CHECK: [[STOREPTR:%.*]] = spirv.AccessChain [[ADDRESS_ARG1]]
%7 = spirv.AccessChain %3[%1] : !spirv.ptr<!spirv.struct<(i32 [0])>, StorageBuffer>, i32
// CHECK-NOT: spirv.FunctionCall
// CHECK: spirv.AtomicIAdd "Device" "AcquireRelease" [[STOREPTR]], [[VAL]]
// CHECK: spirv.AtomicIAdd <Device> <AcquireRelease> [[STOREPTR]], [[VAL]]
// CHECK: spirv.Branch
spirv.FunctionCall @atomic_add(%5, %7) : (i32, !spirv.ptr<i32, StorageBuffer>) -> ()
spirv.Branch ^bb2
@@ -217,7 +217,7 @@ spirv.module Logical GLSL450 {
spirv.Return
}
spirv.func @atomic_add(%arg0: i32, %arg1: !spirv.ptr<i32, StorageBuffer>) "None" {
%0 = spirv.AtomicIAdd "Device" "AcquireRelease" %arg1, %arg0 : !spirv.ptr<i32, StorageBuffer>
%0 = spirv.AtomicIAdd <Device> <AcquireRelease> %arg1, %arg0 : !spirv.ptr<i32, StorageBuffer>
spirv.Return
}
spirv.EntryPoint "GLCompute" @inline_into_selection_region

View File

@@ -3,41 +3,41 @@
spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {
// CHECK-LABEL: @test_int_atomics
spirv.func @test_int_atomics(%ptr: !spirv.ptr<i32, Workgroup>, %value: i32, %comparator: i32) -> i32 "None" {
// CHECK: spirv.AtomicCompareExchangeWeak "Workgroup" "Release" "Acquire" %{{.*}}, %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%0 = spirv.AtomicCompareExchangeWeak "Workgroup" "Release" "Acquire" %ptr, %value, %comparator: !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicAnd "Device" "None" %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%1 = spirv.AtomicAnd "Device" "None" %ptr, %value : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicIAdd "Workgroup" "Acquire" %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%2 = spirv.AtomicIAdd "Workgroup" "Acquire" %ptr, %value : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicIDecrement "Workgroup" "Acquire" %{{.*}} : !spirv.ptr<i32, Workgroup>
%3 = spirv.AtomicIDecrement "Workgroup" "Acquire" %ptr : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicIIncrement "Device" "Release" %{{.*}} : !spirv.ptr<i32, Workgroup>
%4 = spirv.AtomicIIncrement "Device" "Release" %ptr : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicISub "Workgroup" "Acquire" %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%5 = spirv.AtomicISub "Workgroup" "Acquire" %ptr, %value : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicOr "Workgroup" "AcquireRelease" %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%6 = spirv.AtomicOr "Workgroup" "AcquireRelease" %ptr, %value : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicSMax "Subgroup" "None" %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%7 = spirv.AtomicSMax "Subgroup" "None" %ptr, %value : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicSMin "Device" "Release" %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%8 = spirv.AtomicSMin "Device" "Release" %ptr, %value : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicUMax "Subgroup" "None" %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%9 = spirv.AtomicUMax "Subgroup" "None" %ptr, %value : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicUMin "Device" "Release" %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%10 = spirv.AtomicUMin "Device" "Release" %ptr, %value : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicXor "Workgroup" "AcquireRelease" %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%11 = spirv.AtomicXor "Workgroup" "AcquireRelease" %ptr, %value : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicCompareExchange "Workgroup" "Release" "Acquire" %{{.*}}, %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%12 = spirv.AtomicCompareExchange "Workgroup" "Release" "Acquire" %ptr, %value, %comparator: !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicExchange "Workgroup" "Release" %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%13 = spirv.AtomicExchange "Workgroup" "Release" %ptr, %value: !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicCompareExchangeWeak <Workgroup> <Release> <Acquire> %{{.*}}, %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%0 = spirv.AtomicCompareExchangeWeak <Workgroup> <Release> <Acquire> %ptr, %value, %comparator: !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicAnd <Device> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%1 = spirv.AtomicAnd <Device> <None> %ptr, %value : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicIAdd <Workgroup> <Acquire> %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%2 = spirv.AtomicIAdd <Workgroup> <Acquire> %ptr, %value : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicIDecrement <Workgroup> <Acquire> %{{.*}} : !spirv.ptr<i32, Workgroup>
%3 = spirv.AtomicIDecrement <Workgroup> <Acquire> %ptr : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicIIncrement <Device> <Release> %{{.*}} : !spirv.ptr<i32, Workgroup>
%4 = spirv.AtomicIIncrement <Device> <Release> %ptr : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicISub <Workgroup> <Acquire> %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%5 = spirv.AtomicISub <Workgroup> <Acquire> %ptr, %value : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicOr <Workgroup> <AcquireRelease> %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%6 = spirv.AtomicOr <Workgroup> <AcquireRelease> %ptr, %value : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicSMax <Subgroup> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%7 = spirv.AtomicSMax <Subgroup> <None> %ptr, %value : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicSMin <Device> <Release> %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%8 = spirv.AtomicSMin <Device> <Release> %ptr, %value : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicUMax <Subgroup> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%9 = spirv.AtomicUMax <Subgroup> <None> %ptr, %value : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicUMin <Device> <Release> %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%10 = spirv.AtomicUMin <Device> <Release> %ptr, %value : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicXor <Workgroup> <AcquireRelease> %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%11 = spirv.AtomicXor <Workgroup> <AcquireRelease> %ptr, %value : !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicCompareExchange <Workgroup> <Release> <Acquire> %{{.*}}, %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%12 = spirv.AtomicCompareExchange <Workgroup> <Release> <Acquire> %ptr, %value, %comparator: !spirv.ptr<i32, Workgroup>
// CHECK: spirv.AtomicExchange <Workgroup> <Release> %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup>
%13 = spirv.AtomicExchange <Workgroup> <Release> %ptr, %value: !spirv.ptr<i32, Workgroup>
spirv.ReturnValue %0: i32
}
// CHECK-LABEL: @test_float_atomics
spirv.func @test_float_atomics(%ptr: !spirv.ptr<f32, Workgroup>, %value: f32) -> f32 "None" {
// CHECK: spirv.EXT.AtomicFAdd "Workgroup" "Acquire" %{{.*}}, %{{.*}} : !spirv.ptr<f32, Workgroup>
%0 = spirv.EXT.AtomicFAdd "Workgroup" "Acquire" %ptr, %value : !spirv.ptr<f32, Workgroup>
// CHECK: spirv.EXT.AtomicFAdd <Workgroup> <Acquire> %{{.*}}, %{{.*}} : !spirv.ptr<f32, Workgroup>
%0 = spirv.EXT.AtomicFAdd <Workgroup> <Acquire> %ptr, %value : !spirv.ptr<f32, Workgroup>
spirv.ReturnValue %0: f32
}
}

View File

@@ -13,7 +13,7 @@ spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {
spirv.func @atomic(%ptr: !spirv.ptr<i32, Workgroup>, %value: i32, %comparator: i32) "None" {
// CHECK: loc({{".*debug.mlir"}}:16:10)
%1 = spirv.AtomicAnd "Device" "None" %ptr, %value : !spirv.ptr<i32, Workgroup>
%1 = spirv.AtomicAnd <Device> <None> %ptr, %value : !spirv.ptr<i32, Workgroup>
spirv.Return
}