Add spv.AtomicCompareExchangeWeak

PiperOrigin-RevId: 283997917
This commit is contained in:
Lei Zhang 2019-12-05 10:05:54 -08:00 committed by A. Unique TensorFlower
parent 780f0c043a
commit 037044b0ae
6 changed files with 325 additions and 126 deletions

View File

@ -0,0 +1,74 @@
//===-- SPIRVAtomicOps.td - MLIR SPIR-V Atomic Ops ---------*- tablegen -*-===//
//
// Copyright 2019 The MLIR Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// =============================================================================
//
// This file contains atomic ops for the SPIR-V dialect. It corresponds to
// "3.32.18. Atomic Instructions" of the SPIR-V specification.
//
//===----------------------------------------------------------------------===//
#ifndef SPIRV_ATOMIC_OPS
#define SPIRV_ATOMIC_OPS
// -----
def SPV_AtomicCompareExchangeWeakOp : SPV_Op<"AtomicCompareExchangeWeak", []> {
let summary = "Deprecated (use OpAtomicCompareExchange).";
let description = [{
Has the same semantics as OpAtomicCompareExchange.
Memory must be a valid memory Scope.
### Custom assembly form
``` {.ebnf}
scope ::= `"CrossDevice"` | `"Device"` | `"Workgroup"` | ...
memory-semantics ::= `"None"` | `"Acquire"` | "Release"` | ...
atomic-compare-exchange-weak-op ::=
`spv.AtomicCompareExchangeWeak` scope memory-semantics memory-semantics
ssa-use `,` ssa-use `,` ssa-use
`:` spv-pointer-type
```
For example:
```
%0 = spv.AtomicCompareExchangeWeak "Workgroup" "Acquire" "None"
%pointer, %value, %comparator
: !spv.ptr<i32, WorkGroup>
```
}];
let arguments = (ins
SPV_AnyPtr:$pointer,
SPV_ScopeAttr:$memory_scope,
SPV_MemorySemanticsAttr:$equal_semantics,
SPV_MemorySemanticsAttr:$unequal_semantics,
SPV_Integer:$value,
SPV_Integer:$comparator
);
let results = (outs
SPV_Integer:$result
);
}
// -----
#endif // SPIRV_ATOMIC_OPS

View File

@ -1031,128 +1031,129 @@ class SPV_OpCode<string name, int val> {
// Begin opcode section. Generated from SPIR-V spec; DO NOT MODIFY!
def SPV_OC_OpNop : I32EnumAttrCase<"OpNop", 0>;
def SPV_OC_OpUndef : I32EnumAttrCase<"OpUndef", 1>;
def SPV_OC_OpSourceContinued : I32EnumAttrCase<"OpSourceContinued", 2>;
def SPV_OC_OpSource : I32EnumAttrCase<"OpSource", 3>;
def SPV_OC_OpSourceExtension : I32EnumAttrCase<"OpSourceExtension", 4>;
def SPV_OC_OpName : I32EnumAttrCase<"OpName", 5>;
def SPV_OC_OpMemberName : I32EnumAttrCase<"OpMemberName", 6>;
def SPV_OC_OpString : I32EnumAttrCase<"OpString", 7>;
def SPV_OC_OpExtension : I32EnumAttrCase<"OpExtension", 10>;
def SPV_OC_OpExtInstImport : I32EnumAttrCase<"OpExtInstImport", 11>;
def SPV_OC_OpExtInst : I32EnumAttrCase<"OpExtInst", 12>;
def SPV_OC_OpMemoryModel : I32EnumAttrCase<"OpMemoryModel", 14>;
def SPV_OC_OpEntryPoint : I32EnumAttrCase<"OpEntryPoint", 15>;
def SPV_OC_OpExecutionMode : I32EnumAttrCase<"OpExecutionMode", 16>;
def SPV_OC_OpCapability : I32EnumAttrCase<"OpCapability", 17>;
def SPV_OC_OpTypeVoid : I32EnumAttrCase<"OpTypeVoid", 19>;
def SPV_OC_OpTypeBool : I32EnumAttrCase<"OpTypeBool", 20>;
def SPV_OC_OpTypeInt : I32EnumAttrCase<"OpTypeInt", 21>;
def SPV_OC_OpTypeFloat : I32EnumAttrCase<"OpTypeFloat", 22>;
def SPV_OC_OpTypeVector : I32EnumAttrCase<"OpTypeVector", 23>;
def SPV_OC_OpTypeArray : I32EnumAttrCase<"OpTypeArray", 28>;
def SPV_OC_OpTypeRuntimeArray : I32EnumAttrCase<"OpTypeRuntimeArray", 29>;
def SPV_OC_OpTypeStruct : I32EnumAttrCase<"OpTypeStruct", 30>;
def SPV_OC_OpTypePointer : I32EnumAttrCase<"OpTypePointer", 32>;
def SPV_OC_OpTypeFunction : I32EnumAttrCase<"OpTypeFunction", 33>;
def SPV_OC_OpConstantTrue : I32EnumAttrCase<"OpConstantTrue", 41>;
def SPV_OC_OpConstantFalse : I32EnumAttrCase<"OpConstantFalse", 42>;
def SPV_OC_OpConstant : I32EnumAttrCase<"OpConstant", 43>;
def SPV_OC_OpConstantComposite : I32EnumAttrCase<"OpConstantComposite", 44>;
def SPV_OC_OpConstantNull : I32EnumAttrCase<"OpConstantNull", 46>;
def SPV_OC_OpSpecConstantTrue : I32EnumAttrCase<"OpSpecConstantTrue", 48>;
def SPV_OC_OpSpecConstantFalse : I32EnumAttrCase<"OpSpecConstantFalse", 49>;
def SPV_OC_OpSpecConstant : I32EnumAttrCase<"OpSpecConstant", 50>;
def SPV_OC_OpSpecConstantComposite : I32EnumAttrCase<"OpSpecConstantComposite", 51>;
def SPV_OC_OpFunction : I32EnumAttrCase<"OpFunction", 54>;
def SPV_OC_OpFunctionParameter : I32EnumAttrCase<"OpFunctionParameter", 55>;
def SPV_OC_OpFunctionEnd : I32EnumAttrCase<"OpFunctionEnd", 56>;
def SPV_OC_OpFunctionCall : I32EnumAttrCase<"OpFunctionCall", 57>;
def SPV_OC_OpVariable : I32EnumAttrCase<"OpVariable", 59>;
def SPV_OC_OpLoad : I32EnumAttrCase<"OpLoad", 61>;
def SPV_OC_OpStore : I32EnumAttrCase<"OpStore", 62>;
def SPV_OC_OpAccessChain : I32EnumAttrCase<"OpAccessChain", 65>;
def SPV_OC_OpDecorate : I32EnumAttrCase<"OpDecorate", 71>;
def SPV_OC_OpMemberDecorate : I32EnumAttrCase<"OpMemberDecorate", 72>;
def SPV_OC_OpCompositeExtract : I32EnumAttrCase<"OpCompositeExtract", 81>;
def SPV_OC_OpConvertFToU : I32EnumAttrCase<"OpConvertFToU", 109>;
def SPV_OC_OpConvertFToS : I32EnumAttrCase<"OpConvertFToS", 110>;
def SPV_OC_OpConvertSToF : I32EnumAttrCase<"OpConvertSToF", 111>;
def SPV_OC_OpConvertUToF : I32EnumAttrCase<"OpConvertUToF", 112>;
def SPV_OC_OpUConvert : I32EnumAttrCase<"OpUConvert", 113>;
def SPV_OC_OpSConvert : I32EnumAttrCase<"OpSConvert", 114>;
def SPV_OC_OpFConvert : I32EnumAttrCase<"OpFConvert", 115>;
def SPV_OC_OpBitcast : I32EnumAttrCase<"OpBitcast", 124>;
def SPV_OC_OpFNegate : I32EnumAttrCase<"OpFNegate", 127>;
def SPV_OC_OpIAdd : I32EnumAttrCase<"OpIAdd", 128>;
def SPV_OC_OpFAdd : I32EnumAttrCase<"OpFAdd", 129>;
def SPV_OC_OpISub : I32EnumAttrCase<"OpISub", 130>;
def SPV_OC_OpFSub : I32EnumAttrCase<"OpFSub", 131>;
def SPV_OC_OpIMul : I32EnumAttrCase<"OpIMul", 132>;
def SPV_OC_OpFMul : I32EnumAttrCase<"OpFMul", 133>;
def SPV_OC_OpUDiv : I32EnumAttrCase<"OpUDiv", 134>;
def SPV_OC_OpSDiv : I32EnumAttrCase<"OpSDiv", 135>;
def SPV_OC_OpFDiv : I32EnumAttrCase<"OpFDiv", 136>;
def SPV_OC_OpUMod : I32EnumAttrCase<"OpUMod", 137>;
def SPV_OC_OpSRem : I32EnumAttrCase<"OpSRem", 138>;
def SPV_OC_OpSMod : I32EnumAttrCase<"OpSMod", 139>;
def SPV_OC_OpFRem : I32EnumAttrCase<"OpFRem", 140>;
def SPV_OC_OpFMod : I32EnumAttrCase<"OpFMod", 141>;
def SPV_OC_OpLogicalEqual : I32EnumAttrCase<"OpLogicalEqual", 164>;
def SPV_OC_OpLogicalNotEqual : I32EnumAttrCase<"OpLogicalNotEqual", 165>;
def SPV_OC_OpLogicalOr : I32EnumAttrCase<"OpLogicalOr", 166>;
def SPV_OC_OpLogicalAnd : I32EnumAttrCase<"OpLogicalAnd", 167>;
def SPV_OC_OpLogicalNot : I32EnumAttrCase<"OpLogicalNot", 168>;
def SPV_OC_OpSelect : I32EnumAttrCase<"OpSelect", 169>;
def SPV_OC_OpIEqual : I32EnumAttrCase<"OpIEqual", 170>;
def SPV_OC_OpINotEqual : I32EnumAttrCase<"OpINotEqual", 171>;
def SPV_OC_OpUGreaterThan : I32EnumAttrCase<"OpUGreaterThan", 172>;
def SPV_OC_OpSGreaterThan : I32EnumAttrCase<"OpSGreaterThan", 173>;
def SPV_OC_OpUGreaterThanEqual : I32EnumAttrCase<"OpUGreaterThanEqual", 174>;
def SPV_OC_OpSGreaterThanEqual : I32EnumAttrCase<"OpSGreaterThanEqual", 175>;
def SPV_OC_OpULessThan : I32EnumAttrCase<"OpULessThan", 176>;
def SPV_OC_OpSLessThan : I32EnumAttrCase<"OpSLessThan", 177>;
def SPV_OC_OpULessThanEqual : I32EnumAttrCase<"OpULessThanEqual", 178>;
def SPV_OC_OpSLessThanEqual : I32EnumAttrCase<"OpSLessThanEqual", 179>;
def SPV_OC_OpFOrdEqual : I32EnumAttrCase<"OpFOrdEqual", 180>;
def SPV_OC_OpFUnordEqual : I32EnumAttrCase<"OpFUnordEqual", 181>;
def SPV_OC_OpFOrdNotEqual : I32EnumAttrCase<"OpFOrdNotEqual", 182>;
def SPV_OC_OpFUnordNotEqual : I32EnumAttrCase<"OpFUnordNotEqual", 183>;
def SPV_OC_OpFOrdLessThan : I32EnumAttrCase<"OpFOrdLessThan", 184>;
def SPV_OC_OpFUnordLessThan : I32EnumAttrCase<"OpFUnordLessThan", 185>;
def SPV_OC_OpFOrdGreaterThan : I32EnumAttrCase<"OpFOrdGreaterThan", 186>;
def SPV_OC_OpFUnordGreaterThan : I32EnumAttrCase<"OpFUnordGreaterThan", 187>;
def SPV_OC_OpFOrdLessThanEqual : I32EnumAttrCase<"OpFOrdLessThanEqual", 188>;
def SPV_OC_OpFUnordLessThanEqual : I32EnumAttrCase<"OpFUnordLessThanEqual", 189>;
def SPV_OC_OpFOrdGreaterThanEqual : I32EnumAttrCase<"OpFOrdGreaterThanEqual", 190>;
def SPV_OC_OpFUnordGreaterThanEqual : I32EnumAttrCase<"OpFUnordGreaterThanEqual", 191>;
def SPV_OC_OpShiftRightLogical : I32EnumAttrCase<"OpShiftRightLogical", 194>;
def SPV_OC_OpShiftRightArithmetic : I32EnumAttrCase<"OpShiftRightArithmetic", 195>;
def SPV_OC_OpShiftLeftLogical : I32EnumAttrCase<"OpShiftLeftLogical", 196>;
def SPV_OC_OpBitwiseOr : I32EnumAttrCase<"OpBitwiseOr", 197>;
def SPV_OC_OpBitwiseXor : I32EnumAttrCase<"OpBitwiseXor", 198>;
def SPV_OC_OpBitwiseAnd : I32EnumAttrCase<"OpBitwiseAnd", 199>;
def SPV_OC_OpNot : I32EnumAttrCase<"OpNot", 200>;
def SPV_OC_OpBitFieldInsert : I32EnumAttrCase<"OpBitFieldInsert", 201>;
def SPV_OC_OpBitFieldSExtract : I32EnumAttrCase<"OpBitFieldSExtract", 202>;
def SPV_OC_OpBitFieldUExtract : I32EnumAttrCase<"OpBitFieldUExtract", 203>;
def SPV_OC_OpBitReverse : I32EnumAttrCase<"OpBitReverse", 204>;
def SPV_OC_OpBitCount : I32EnumAttrCase<"OpBitCount", 205>;
def SPV_OC_OpControlBarrier : I32EnumAttrCase<"OpControlBarrier", 224>;
def SPV_OC_OpMemoryBarrier : I32EnumAttrCase<"OpMemoryBarrier", 225>;
def SPV_OC_OpPhi : I32EnumAttrCase<"OpPhi", 245>;
def SPV_OC_OpLoopMerge : I32EnumAttrCase<"OpLoopMerge", 246>;
def SPV_OC_OpSelectionMerge : I32EnumAttrCase<"OpSelectionMerge", 247>;
def SPV_OC_OpLabel : I32EnumAttrCase<"OpLabel", 248>;
def SPV_OC_OpBranch : I32EnumAttrCase<"OpBranch", 249>;
def SPV_OC_OpBranchConditional : I32EnumAttrCase<"OpBranchConditional", 250>;
def SPV_OC_OpReturn : I32EnumAttrCase<"OpReturn", 253>;
def SPV_OC_OpReturnValue : I32EnumAttrCase<"OpReturnValue", 254>;
def SPV_OC_OpUnreachable : I32EnumAttrCase<"OpUnreachable", 255>;
def SPV_OC_OpModuleProcessed : I32EnumAttrCase<"OpModuleProcessed", 330>;
def SPV_OC_OpGroupNonUniformBallot : I32EnumAttrCase<"OpGroupNonUniformBallot", 339>;
def SPV_OC_OpSubgroupBallotKHR : I32EnumAttrCase<"OpSubgroupBallotKHR", 4421>;
def SPV_OC_OpNop : I32EnumAttrCase<"OpNop", 0>;
def SPV_OC_OpUndef : I32EnumAttrCase<"OpUndef", 1>;
def SPV_OC_OpSourceContinued : I32EnumAttrCase<"OpSourceContinued", 2>;
def SPV_OC_OpSource : I32EnumAttrCase<"OpSource", 3>;
def SPV_OC_OpSourceExtension : I32EnumAttrCase<"OpSourceExtension", 4>;
def SPV_OC_OpName : I32EnumAttrCase<"OpName", 5>;
def SPV_OC_OpMemberName : I32EnumAttrCase<"OpMemberName", 6>;
def SPV_OC_OpString : I32EnumAttrCase<"OpString", 7>;
def SPV_OC_OpExtension : I32EnumAttrCase<"OpExtension", 10>;
def SPV_OC_OpExtInstImport : I32EnumAttrCase<"OpExtInstImport", 11>;
def SPV_OC_OpExtInst : I32EnumAttrCase<"OpExtInst", 12>;
def SPV_OC_OpMemoryModel : I32EnumAttrCase<"OpMemoryModel", 14>;
def SPV_OC_OpEntryPoint : I32EnumAttrCase<"OpEntryPoint", 15>;
def SPV_OC_OpExecutionMode : I32EnumAttrCase<"OpExecutionMode", 16>;
def SPV_OC_OpCapability : I32EnumAttrCase<"OpCapability", 17>;
def SPV_OC_OpTypeVoid : I32EnumAttrCase<"OpTypeVoid", 19>;
def SPV_OC_OpTypeBool : I32EnumAttrCase<"OpTypeBool", 20>;
def SPV_OC_OpTypeInt : I32EnumAttrCase<"OpTypeInt", 21>;
def SPV_OC_OpTypeFloat : I32EnumAttrCase<"OpTypeFloat", 22>;
def SPV_OC_OpTypeVector : I32EnumAttrCase<"OpTypeVector", 23>;
def SPV_OC_OpTypeArray : I32EnumAttrCase<"OpTypeArray", 28>;
def SPV_OC_OpTypeRuntimeArray : I32EnumAttrCase<"OpTypeRuntimeArray", 29>;
def SPV_OC_OpTypeStruct : I32EnumAttrCase<"OpTypeStruct", 30>;
def SPV_OC_OpTypePointer : I32EnumAttrCase<"OpTypePointer", 32>;
def SPV_OC_OpTypeFunction : I32EnumAttrCase<"OpTypeFunction", 33>;
def SPV_OC_OpConstantTrue : I32EnumAttrCase<"OpConstantTrue", 41>;
def SPV_OC_OpConstantFalse : I32EnumAttrCase<"OpConstantFalse", 42>;
def SPV_OC_OpConstant : I32EnumAttrCase<"OpConstant", 43>;
def SPV_OC_OpConstantComposite : I32EnumAttrCase<"OpConstantComposite", 44>;
def SPV_OC_OpConstantNull : I32EnumAttrCase<"OpConstantNull", 46>;
def SPV_OC_OpSpecConstantTrue : I32EnumAttrCase<"OpSpecConstantTrue", 48>;
def SPV_OC_OpSpecConstantFalse : I32EnumAttrCase<"OpSpecConstantFalse", 49>;
def SPV_OC_OpSpecConstant : I32EnumAttrCase<"OpSpecConstant", 50>;
def SPV_OC_OpSpecConstantComposite : I32EnumAttrCase<"OpSpecConstantComposite", 51>;
def SPV_OC_OpFunction : I32EnumAttrCase<"OpFunction", 54>;
def SPV_OC_OpFunctionParameter : I32EnumAttrCase<"OpFunctionParameter", 55>;
def SPV_OC_OpFunctionEnd : I32EnumAttrCase<"OpFunctionEnd", 56>;
def SPV_OC_OpFunctionCall : I32EnumAttrCase<"OpFunctionCall", 57>;
def SPV_OC_OpVariable : I32EnumAttrCase<"OpVariable", 59>;
def SPV_OC_OpLoad : I32EnumAttrCase<"OpLoad", 61>;
def SPV_OC_OpStore : I32EnumAttrCase<"OpStore", 62>;
def SPV_OC_OpAccessChain : I32EnumAttrCase<"OpAccessChain", 65>;
def SPV_OC_OpDecorate : I32EnumAttrCase<"OpDecorate", 71>;
def SPV_OC_OpMemberDecorate : I32EnumAttrCase<"OpMemberDecorate", 72>;
def SPV_OC_OpCompositeExtract : I32EnumAttrCase<"OpCompositeExtract", 81>;
def SPV_OC_OpConvertFToU : I32EnumAttrCase<"OpConvertFToU", 109>;
def SPV_OC_OpConvertFToS : I32EnumAttrCase<"OpConvertFToS", 110>;
def SPV_OC_OpConvertSToF : I32EnumAttrCase<"OpConvertSToF", 111>;
def SPV_OC_OpConvertUToF : I32EnumAttrCase<"OpConvertUToF", 112>;
def SPV_OC_OpUConvert : I32EnumAttrCase<"OpUConvert", 113>;
def SPV_OC_OpSConvert : I32EnumAttrCase<"OpSConvert", 114>;
def SPV_OC_OpFConvert : I32EnumAttrCase<"OpFConvert", 115>;
def SPV_OC_OpBitcast : I32EnumAttrCase<"OpBitcast", 124>;
def SPV_OC_OpFNegate : I32EnumAttrCase<"OpFNegate", 127>;
def SPV_OC_OpIAdd : I32EnumAttrCase<"OpIAdd", 128>;
def SPV_OC_OpFAdd : I32EnumAttrCase<"OpFAdd", 129>;
def SPV_OC_OpISub : I32EnumAttrCase<"OpISub", 130>;
def SPV_OC_OpFSub : I32EnumAttrCase<"OpFSub", 131>;
def SPV_OC_OpIMul : I32EnumAttrCase<"OpIMul", 132>;
def SPV_OC_OpFMul : I32EnumAttrCase<"OpFMul", 133>;
def SPV_OC_OpUDiv : I32EnumAttrCase<"OpUDiv", 134>;
def SPV_OC_OpSDiv : I32EnumAttrCase<"OpSDiv", 135>;
def SPV_OC_OpFDiv : I32EnumAttrCase<"OpFDiv", 136>;
def SPV_OC_OpUMod : I32EnumAttrCase<"OpUMod", 137>;
def SPV_OC_OpSRem : I32EnumAttrCase<"OpSRem", 138>;
def SPV_OC_OpSMod : I32EnumAttrCase<"OpSMod", 139>;
def SPV_OC_OpFRem : I32EnumAttrCase<"OpFRem", 140>;
def SPV_OC_OpFMod : I32EnumAttrCase<"OpFMod", 141>;
def SPV_OC_OpLogicalEqual : I32EnumAttrCase<"OpLogicalEqual", 164>;
def SPV_OC_OpLogicalNotEqual : I32EnumAttrCase<"OpLogicalNotEqual", 165>;
def SPV_OC_OpLogicalOr : I32EnumAttrCase<"OpLogicalOr", 166>;
def SPV_OC_OpLogicalAnd : I32EnumAttrCase<"OpLogicalAnd", 167>;
def SPV_OC_OpLogicalNot : I32EnumAttrCase<"OpLogicalNot", 168>;
def SPV_OC_OpSelect : I32EnumAttrCase<"OpSelect", 169>;
def SPV_OC_OpIEqual : I32EnumAttrCase<"OpIEqual", 170>;
def SPV_OC_OpINotEqual : I32EnumAttrCase<"OpINotEqual", 171>;
def SPV_OC_OpUGreaterThan : I32EnumAttrCase<"OpUGreaterThan", 172>;
def SPV_OC_OpSGreaterThan : I32EnumAttrCase<"OpSGreaterThan", 173>;
def SPV_OC_OpUGreaterThanEqual : I32EnumAttrCase<"OpUGreaterThanEqual", 174>;
def SPV_OC_OpSGreaterThanEqual : I32EnumAttrCase<"OpSGreaterThanEqual", 175>;
def SPV_OC_OpULessThan : I32EnumAttrCase<"OpULessThan", 176>;
def SPV_OC_OpSLessThan : I32EnumAttrCase<"OpSLessThan", 177>;
def SPV_OC_OpULessThanEqual : I32EnumAttrCase<"OpULessThanEqual", 178>;
def SPV_OC_OpSLessThanEqual : I32EnumAttrCase<"OpSLessThanEqual", 179>;
def SPV_OC_OpFOrdEqual : I32EnumAttrCase<"OpFOrdEqual", 180>;
def SPV_OC_OpFUnordEqual : I32EnumAttrCase<"OpFUnordEqual", 181>;
def SPV_OC_OpFOrdNotEqual : I32EnumAttrCase<"OpFOrdNotEqual", 182>;
def SPV_OC_OpFUnordNotEqual : I32EnumAttrCase<"OpFUnordNotEqual", 183>;
def SPV_OC_OpFOrdLessThan : I32EnumAttrCase<"OpFOrdLessThan", 184>;
def SPV_OC_OpFUnordLessThan : I32EnumAttrCase<"OpFUnordLessThan", 185>;
def SPV_OC_OpFOrdGreaterThan : I32EnumAttrCase<"OpFOrdGreaterThan", 186>;
def SPV_OC_OpFUnordGreaterThan : I32EnumAttrCase<"OpFUnordGreaterThan", 187>;
def SPV_OC_OpFOrdLessThanEqual : I32EnumAttrCase<"OpFOrdLessThanEqual", 188>;
def SPV_OC_OpFUnordLessThanEqual : I32EnumAttrCase<"OpFUnordLessThanEqual", 189>;
def SPV_OC_OpFOrdGreaterThanEqual : I32EnumAttrCase<"OpFOrdGreaterThanEqual", 190>;
def SPV_OC_OpFUnordGreaterThanEqual : I32EnumAttrCase<"OpFUnordGreaterThanEqual", 191>;
def SPV_OC_OpShiftRightLogical : I32EnumAttrCase<"OpShiftRightLogical", 194>;
def SPV_OC_OpShiftRightArithmetic : I32EnumAttrCase<"OpShiftRightArithmetic", 195>;
def SPV_OC_OpShiftLeftLogical : I32EnumAttrCase<"OpShiftLeftLogical", 196>;
def SPV_OC_OpBitwiseOr : I32EnumAttrCase<"OpBitwiseOr", 197>;
def SPV_OC_OpBitwiseXor : I32EnumAttrCase<"OpBitwiseXor", 198>;
def SPV_OC_OpBitwiseAnd : I32EnumAttrCase<"OpBitwiseAnd", 199>;
def SPV_OC_OpNot : I32EnumAttrCase<"OpNot", 200>;
def SPV_OC_OpBitFieldInsert : I32EnumAttrCase<"OpBitFieldInsert", 201>;
def SPV_OC_OpBitFieldSExtract : I32EnumAttrCase<"OpBitFieldSExtract", 202>;
def SPV_OC_OpBitFieldUExtract : I32EnumAttrCase<"OpBitFieldUExtract", 203>;
def SPV_OC_OpBitReverse : I32EnumAttrCase<"OpBitReverse", 204>;
def SPV_OC_OpBitCount : I32EnumAttrCase<"OpBitCount", 205>;
def SPV_OC_OpControlBarrier : I32EnumAttrCase<"OpControlBarrier", 224>;
def SPV_OC_OpMemoryBarrier : I32EnumAttrCase<"OpMemoryBarrier", 225>;
def SPV_OC_OpAtomicCompareExchangeWeak : I32EnumAttrCase<"OpAtomicCompareExchangeWeak", 231>;
def SPV_OC_OpPhi : I32EnumAttrCase<"OpPhi", 245>;
def SPV_OC_OpLoopMerge : I32EnumAttrCase<"OpLoopMerge", 246>;
def SPV_OC_OpSelectionMerge : I32EnumAttrCase<"OpSelectionMerge", 247>;
def SPV_OC_OpLabel : I32EnumAttrCase<"OpLabel", 248>;
def SPV_OC_OpBranch : I32EnumAttrCase<"OpBranch", 249>;
def SPV_OC_OpBranchConditional : I32EnumAttrCase<"OpBranchConditional", 250>;
def SPV_OC_OpReturn : I32EnumAttrCase<"OpReturn", 253>;
def SPV_OC_OpReturnValue : I32EnumAttrCase<"OpReturnValue", 254>;
def SPV_OC_OpUnreachable : I32EnumAttrCase<"OpUnreachable", 255>;
def SPV_OC_OpModuleProcessed : I32EnumAttrCase<"OpModuleProcessed", 330>;
def SPV_OC_OpGroupNonUniformBallot : I32EnumAttrCase<"OpGroupNonUniformBallot", 339>;
def SPV_OC_OpSubgroupBallotKHR : I32EnumAttrCase<"OpSubgroupBallotKHR", 4421>;
def SPV_OpcodeAttr :
I32EnumAttr<"Opcode", "valid SPIR-V instructions", [
@ -1190,10 +1191,11 @@ def SPV_OpcodeAttr :
SPV_OC_OpBitwiseAnd, SPV_OC_OpNot, SPV_OC_OpBitFieldInsert,
SPV_OC_OpBitFieldSExtract, SPV_OC_OpBitFieldUExtract, SPV_OC_OpBitReverse,
SPV_OC_OpBitCount, SPV_OC_OpControlBarrier, SPV_OC_OpMemoryBarrier,
SPV_OC_OpPhi, SPV_OC_OpLoopMerge, SPV_OC_OpSelectionMerge, SPV_OC_OpLabel,
SPV_OC_OpBranch, SPV_OC_OpBranchConditional, SPV_OC_OpReturn,
SPV_OC_OpReturnValue, SPV_OC_OpUnreachable, SPV_OC_OpModuleProcessed,
SPV_OC_OpGroupNonUniformBallot, SPV_OC_OpSubgroupBallotKHR
SPV_OC_OpAtomicCompareExchangeWeak, SPV_OC_OpPhi, SPV_OC_OpLoopMerge,
SPV_OC_OpSelectionMerge, SPV_OC_OpLabel, SPV_OC_OpBranch,
SPV_OC_OpBranchConditional, SPV_OC_OpReturn, SPV_OC_OpReturnValue,
SPV_OC_OpUnreachable, SPV_OC_OpModuleProcessed, SPV_OC_OpGroupNonUniformBallot,
SPV_OC_OpSubgroupBallotKHR
]> {
let cppNamespace = "::mlir::spirv";
}

View File

@ -32,6 +32,7 @@
include "mlir/Dialect/SPIRV/SPIRVBase.td"
include "mlir/Dialect/SPIRV/SPIRVArithmeticOps.td"
include "mlir/Dialect/SPIRV/SPIRVAtomicOps.td"
include "mlir/Dialect/SPIRV/SPIRVBitOps.td"
include "mlir/Dialect/SPIRV/SPIRVCastOps.td"
include "mlir/Dialect/SPIRV/SPIRVControlFlowOps.td"

View File

@ -42,6 +42,7 @@ static constexpr const char kBranchWeightAttrName[] = "branch_weights";
static constexpr const char kCallee[] = "callee";
static constexpr const char kDefaultValueAttrName[] = "default_value";
static constexpr const char kExecutionScopeAttrName[] = "execution_scope";
static constexpr const char kEqualSemanticsAttrName[] = "equal_semantics";
static constexpr const char kFnNameAttrName[] = "fn";
static constexpr const char kIndicesAttrName[] = "indices";
static constexpr const char kInitializerAttrName[] = "initializer";
@ -50,6 +51,7 @@ static constexpr const char kMemoryScopeAttrName[] = "memory_scope";
static constexpr const char kSpecConstAttrName[] = "spec_const";
static constexpr const char kSpecIdAttrName[] = "spec_id";
static constexpr const char kTypeAttrName[] = "type";
static constexpr const char kUnequalSemanticsAttrName[] = "unequal_semantics";
static constexpr const char kValueAttrName[] = "value";
static constexpr const char kValuesAttrName[] = "values";
static constexpr const char kVariableAttrName[] = "variable";
@ -750,6 +752,81 @@ static LogicalResult verify(spirv::AddressOfOp addressOfOp) {
return success();
}
//===----------------------------------------------------------------------===//
// spv.AtomicCompareExchangeWeak
//===----------------------------------------------------------------------===//
static ParseResult parseAtomicCompareExchangeWeakOp(OpAsmParser &parser,
OperationState &state) {
spirv::Scope memoryScope;
spirv::MemorySemantics equalSemantics, unequalSemantics;
SmallVector<OpAsmParser::OperandType, 3> operandInfo;
Type type;
if (parseEnumAttribute(memoryScope, parser, state, kMemoryScopeAttrName) ||
parseEnumAttribute(equalSemantics, parser, state,
kEqualSemanticsAttrName) ||
parseEnumAttribute(unequalSemantics, parser, state,
kUnequalSemanticsAttrName) ||
parser.parseOperandList(operandInfo, 3))
return failure();
auto loc = parser.getCurrentLocation();
if (parser.parseColonType(type))
return failure();
auto ptrType = type.dyn_cast<spirv::PointerType>();
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);
}
static void print(spirv::AtomicCompareExchangeWeakOp atomOp,
OpAsmPrinter &printer) {
printer << spirv::AtomicCompareExchangeWeakOp::getOperationName() << " \""
<< stringifyScope(atomOp.memory_scope()) << "\" \""
<< stringifyMemorySemantics(atomOp.equal_semantics()) << "\" \""
<< stringifyMemorySemantics(atomOp.unequal_semantics()) << "\" ";
printer.printOperands(atomOp.getOperands());
printer << " : " << atomOp.pointer()->getType();
}
static LogicalResult verify(spirv::AtomicCompareExchangeWeakOp 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.value()->getType())
return atomOp.emitOpError("value operand must have the same type as the op "
"result, but found ")
<< atomOp.value()->getType() << " vs " << atomOp.getType();
if (atomOp.getType() != atomOp.comparator()->getType())
return atomOp.emitOpError(
"comparator operand must have the same type as the op "
"result, but found ")
<< atomOp.comparator()->getType() << " vs " << atomOp.getType();
Type pointeeType =
atomOp.pointer()->getType().cast<spirv::PointerType>().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(antiagainst): 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();
}
//===----------------------------------------------------------------------===//
// spv.BitcastOp
//===----------------------------------------------------------------------===//

View File

@ -0,0 +1,10 @@
// RUN: mlir-translate -test-spirv-roundtrip -split-input-file %s | FileCheck %s
spv.module "Logical" "GLSL450" {
// CHECK-LABEL: @atomic_compare_exchange_weak
func @atomic_compare_exchange_weak(%ptr: !spv.ptr<i32, Workgroup>, %value: i32, %comparator: i32) -> i32 {
// CHECK: %{{.*}} = spv.AtomicCompareExchangeWeak "Workgroup" "Release" "Acquire" %{{.*}}, %{{.*}}, %{{.*}} : !spv.ptr<i32, Workgroup>
%0 = spv.AtomicCompareExchangeWeak "Workgroup" "Release" "Acquire" %ptr, %value, %comparator: !spv.ptr<i32, Workgroup>
spv.ReturnValue %0: i32
}
}

View File

@ -0,0 +1,35 @@
// RUN: mlir-opt -split-input-file -verify-diagnostics %s | FileCheck %s
//===----------------------------------------------------------------------===//
// spv.AtomicCompareExchangeWeak
//===----------------------------------------------------------------------===//
func @atomic_compare_exchange_weak(%ptr: !spv.ptr<i32, Workgroup>, %value: i32, %comparator: i32) -> i32 {
// CHECK: %{{.*}} = spv.AtomicCompareExchangeWeak "Workgroup" "Release" "Acquire" %{{.*}}, %{{.*}}, %{{.*}} : !spv.ptr<i32, Workgroup>
%0 = spv.AtomicCompareExchangeWeak "Workgroup" "Release" "Acquire" %ptr, %value, %comparator: !spv.ptr<i32, Workgroup>
return %0: i32
}
// -----
func @atomic_compare_exchange_weak(%ptr: !spv.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'}}
%0 = "spv.AtomicCompareExchangeWeak"(%ptr, %value, %comparator) {memory_scope = 4: i32, equal_semantics = 0x4: i32, unequal_semantics = 0x2:i32} : (!spv.ptr<i32, Workgroup>, i64, i32) -> (i32)
return %0: i32
}
// -----
func @atomic_compare_exchange_weak(%ptr: !spv.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'}}
%0 = "spv.AtomicCompareExchangeWeak"(%ptr, %value, %comparator) {memory_scope = 4: i32, equal_semantics = 0x4: i32, unequal_semantics = 0x2:i32} : (!spv.ptr<i32, Workgroup>, i32, i16) -> (i32)
return %0: i32
}
// -----
func @atomic_compare_exchange_weak(%ptr: !spv.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'}}
%0 = "spv.AtomicCompareExchangeWeak"(%ptr, %value, %comparator) {memory_scope = 4: i32, equal_semantics = 0x4: i32, unequal_semantics = 0x2:i32} : (!spv.ptr<i64, Workgroup>, i32, i32) -> (i32)
return %0: i32
}