mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 12:26:52 +08:00
[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:
@@ -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>
|
||||
```
|
||||
}];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
// -----
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user