def SPV_OC_OpFUnordLessThanEqual : I32EnumAttrCase<"OpFUnordLessThanEqual", 189>;
def SPV_OC_OpFOrdGreaterThanEqual : I32EnumAttrCase<"OpFOrdGreaterThanEqual", 190>;
def SPV_OC_OpFUnordGreaterThanEqual : I32EnumAttrCase<"OpFUnordGreaterThanEqual", 191>;
+def SPV_OC_OpBitwiseOr : I32EnumAttrCase<"OpBitwiseOr", 197>;
+def SPV_OC_OpBitwiseXor : I32EnumAttrCase<"OpBitwiseXor", 198>;
+def SPV_OC_OpBitwiseAnd : I32EnumAttrCase<"OpBitwiseAnd", 199>;
def SPV_OC_OpControlBarrier : I32EnumAttrCase<"OpControlBarrier", 224>;
def SPV_OC_OpMemoryBarrier : I32EnumAttrCase<"OpMemoryBarrier", 225>;
def SPV_OC_OpLoopMerge : I32EnumAttrCase<"OpLoopMerge", 246>;
SPV_OC_OpFOrdGreaterThan, SPV_OC_OpFUnordGreaterThan,
SPV_OC_OpFOrdLessThanEqual, SPV_OC_OpFUnordLessThanEqual,
SPV_OC_OpFOrdGreaterThanEqual, SPV_OC_OpFUnordGreaterThanEqual,
+ SPV_OC_OpBitwiseOr, SPV_OC_OpBitwiseXor, SPV_OC_OpBitwiseAnd,
SPV_OC_OpControlBarrier, SPV_OC_OpMemoryBarrier, SPV_OC_OpLoopMerge,
SPV_OC_OpSelectionMerge, SPV_OC_OpLabel, SPV_OC_OpBranch,
SPV_OC_OpBranchConditional, SPV_OC_OpReturn, SPV_OC_OpReturnValue,
--- /dev/null
+//===-- SPIRVBitOps.td - MLIR SPIR-V Bit 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 bit ops for the SPIR-V dialect. It corresponds
+// to "3.32.13. Bit Instructions" of the SPIR-V specification.
+//
+//===----------------------------------------------------------------------===//
+
+#ifdef SPIRV_BIT_OPS
+#else
+#define SPIRV_BIT_OPS
+
+#ifdef SPIRV_BASE
+#else
+include "mlir/SPIRV/SPIRVBase.td"
+#endif // SPIRV_BASE
+
+class SPV_BitBinaryOp<string mnemonic, list<OpTrait> traits = []> :
+ // All the operands type used in bit instructions are SPV_Integer.
+ SPV_BinaryOp<mnemonic, SPV_Integer, SPV_Integer,
+ !listconcat(traits,
+ [NoSideEffect, SameOperandsAndResultType])>;
+
+// -----
+
+def SPV_BitwiseOrOp : SPV_BitBinaryOp<"BitwiseOr", [Commutative]> {
+ let summary = [{
+ Result is 1 if either Operand 1 or Operand 2 is 1. Result is 0 if both
+ Operand 1 and Operand 2 are 0.
+ }];
+
+ let description = [{
+ Results are computed per component, and within each component, per bit.
+
+ Result Type must be a scalar or vector of integer type. The type of
+ Operand 1 and Operand 2 must be a scalar or vector of integer type.
+ They must have the same number of components as Result Type. They must
+ have the same component width as Result Type.
+
+ ### Custom assembly form
+
+ ``` {.ebnf}
+ integer-scalar-vector-type ::= integer-type |
+ `vector<` integer-literal `x` integer-type `>`
+ bitwise-or-op ::= ssa-id `=` `spv.BitwiseOr` ssa-use, ssa-use
+ `:` integer-scalar-vector-type
+ ```
+
+ For example:
+
+ ```
+ %2 = spv.BitwiseOr %0, %1 : i32
+ %2 = spv.BitwiseOr %0, %1 : vector<4xi32>
+ ```
+ }];
+}
+
+// -----
+
+def SPV_BitwiseXorOp : SPV_BitBinaryOp<"BitwiseXor", [Commutative]> {
+ let summary = [{
+ Result is 1 if exactly one of Operand 1 or Operand 2 is 1. Result is 0
+ if Operand 1 and Operand 2 have the same value.
+ }];
+
+ let description = [{
+ Results are computed per component, and within each component, per bit.
+
+ Result Type must be a scalar or vector of integer type. The type of
+ Operand 1 and Operand 2 must be a scalar or vector of integer type.
+ They must have the same number of components as Result Type. They must
+ have the same component width as Result Type.
+
+ ### Custom assembly form
+
+ ``` {.ebnf}
+ integer-scalar-vector-type ::= integer-type |
+ `vector<` integer-literal `x` integer-type `>`
+ bitwise-xor-op ::= ssa-id `=` `spv.BitwiseXor` ssa-use, ssa-use
+ `:` integer-scalar-vector-type
+ ```
+
+ For example:
+
+ ```
+ %2 = spv.BitwiseXor %0, %1 : i32
+ %2 = spv.BitwiseXor %0, %1 : vector<4xi32>
+ ```
+ }];
+}
+
+// -----
+
+def SPV_BitwiseAndOp : SPV_BitBinaryOp<"BitwiseAnd", [Commutative]> {
+ let summary = [{
+ Result is 1 if both Operand 1 and Operand 2 are 1. Result is 0 if either
+ Operand 1 or Operand 2 are 0.
+ }];
+
+ let description = [{
+ Results are computed per component, and within each component, per bit.
+
+ Result Type must be a scalar or vector of integer type. The type of
+ Operand 1 and Operand 2 must be a scalar or vector of integer type.
+ They must have the same number of components as Result Type. They must
+ have the same component width as Result Type.
+
+ ### Custom assembly form
+
+ ``` {.ebnf}
+ integer-scalar-vector-type ::= integer-type |
+ `vector<` integer-literal `x` integer-type `>`
+ bitwise-and-op ::= ssa-id `=` `spv.BitwiseAnd` ssa-use, ssa-use
+ `:` integer-scalar-vector-type
+ ```
+
+ For example:
+
+ ```
+ %2 = spv.BitwiseAnd %0, %1 : i32
+ %2 = spv.BitwiseAnd %0, %1 : vector<4xi32>
+ ```
+ }];
+}
+
+#endif // SPIRV_BIT_OPS
--- /dev/null
+// RUN: mlir-opt -split-input-file -verify-diagnostics %s | FileCheck %s
+
+//===----------------------------------------------------------------------===//
+// spv.BitwiseOr
+//===----------------------------------------------------------------------===//
+
+func @bitwise_or_scalar(%arg: i32) -> i32 {
+ // CHECK: spv.BitwiseOr
+ %0 = spv.BitwiseOr %arg, %arg : i32
+ return %0 : i32
+}
+
+func @bitwise_or_vector(%arg: vector<4xi32>) -> vector<4xi32> {
+ // CHECK: spv.BitwiseOr
+ %0 = spv.BitwiseOr %arg, %arg : vector<4xi32>
+ return %0 : vector<4xi32>
+}
+
+// -----
+
+func @bitwise_or_float(%arg0: f16, %arg1: f16) -> f16 {
+ // expected-error @+1 {{operand #0 must be 8/16/32/64-bit integer or vector of 8/16/32/64-bit integer values of length 2/3/4}}
+ %0 = spv.BitwiseOr %arg0, %arg1 : f16
+ return %0 : f16
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spv.BitwiseXor
+//===----------------------------------------------------------------------===//
+
+func @bitwise_xor_scalar(%arg: i32) -> i32 {
+ // CHECK: spv.BitwiseXor
+ %0 = spv.BitwiseXor %arg, %arg : i32
+ return %0 : i32
+}
+
+func @bitwise_xor_vector(%arg: vector<4xi32>) -> vector<4xi32> {
+ // CHECK: spv.BitwiseXor
+ %0 = spv.BitwiseXor %arg, %arg : vector<4xi32>
+ return %0 : vector<4xi32>
+}
+
+// -----
+
+func @bitwise_xor_float(%arg0: f16, %arg1: f16) -> f16 {
+ // expected-error @+1 {{operand #0 must be 8/16/32/64-bit integer or vector of 8/16/32/64-bit integer values of length 2/3/4}}
+ %0 = spv.BitwiseXor %arg0, %arg1 : f16
+ return %0 : f16
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spv.BitwiseAnd
+//===----------------------------------------------------------------------===//
+
+func @bitwise_and_scalar(%arg: i32) -> i32 {
+ // CHECK: spv.BitwiseAnd
+ %0 = spv.BitwiseAnd %arg, %arg : i32
+ return %0 : i32
+}
+
+func @bitwise_and_vector(%arg: vector<4xi32>) -> vector<4xi32> {
+ // CHECK: spv.BitwiseAnd
+ %0 = spv.BitwiseAnd %arg, %arg : vector<4xi32>
+ return %0 : vector<4xi32>
+}
+
+// -----
+
+func @bitwise_and_float(%arg0: f16, %arg1: f16) -> f16 {
+ // expected-error @+1 {{operand #0 must be 8/16/32/64-bit integer or vector of 8/16/32/64-bit integer values of length 2/3/4}}
+ %0 = spv.BitwiseAnd %arg0, %arg1 : f16
+ return %0 : f16
+}