[Mlir-commits] [mlir] [mlir][spirv] Add last 6 Element Binary operators to TOSA Ext Inst Set (PR #184121)
Davide Grohmann
llvmlistbot at llvm.org
Wed Mar 4 01:34:55 PST 2026
https://github.com/davidegrohmann updated https://github.com/llvm/llvm-project/pull/184121
>From 63f2a4744273d64dbfd8d4343b9c6013cada701b Mon Sep 17 00:00:00 2001
From: Davide Grohmann <davide.grohmann at arm.com>
Date: Wed, 28 Jan 2026 13:39:57 +0100
Subject: [PATCH] [mlir][spirv] Add last 6 Element Binary operators to TOSA Ext
Inst Set
This patch introduces the following element binary operators:
* spirv.Tosa.Maximum
* spirv.Tosa.Minimum
* spirv.Tosa.Mul
* spirv.Tosa.Pow
* spirv.Tosa.Sub
* spirv.Tosa.Table
Also dialect and serialization round-trip tests have been added.
Signed-off-by: Davide Grohmann <davide.grohmann at arm.com>
Change-Id: I30417ddded46fcb991c98a390acadca33bcac128
---
.../mlir/Dialect/SPIRV/IR/SPIRVTosaOps.td | 280 ++++++++++++++++-
.../mlir/Dialect/SPIRV/IR/SPIRVTosaTypes.td | 7 +
.../SPIRV/IR/tosa-ops-verification.mlir | 297 +++++++++++++++++-
mlir/test/Dialect/SPIRV/IR/tosa-ops.mlir | 113 +++++++
mlir/test/Target/SPIRV/tosa-ops.mlir | 202 ++++++++++++
5 files changed, 893 insertions(+), 6 deletions(-)
diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaOps.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaOps.td
index 5cb44beeefcfe..cfc2f7b941308 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaOps.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaOps.td
@@ -127,6 +127,7 @@ def SPIRV_TosaArgMaxOp : SPIRV_TosaOpWithResult<"ArgMax", 0, [Pure,
Returns the index with the largest value across the given axis of the
input tensor. If multiple locations have equal values, returns the first
match along the search axis.
+ NAN Propagation Mode is ignored for inputs using integer element types.
References:
* https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_argmax
@@ -275,7 +276,6 @@ def SPIRV_TosaConv2DOp : SPIRV_TosaConvolutionOp<"Conv2D", 2> {
$weight_zp
attr-dict `:` type(operands) `->` type(results)
}];
-
}
@@ -329,7 +329,6 @@ def SPIRV_TosaConv3DOp : SPIRV_TosaConvolutionOp<"Conv3D", 3> {
$weight_zp
attr-dict `:` type(operands) `->` type(results)
}];
-
}
@@ -384,7 +383,6 @@ def SPIRV_TosaDepthwiseConv2DOp : SPIRV_TosaConvolutionOp<"DepthwiseConv2D", 4>
$weight_zp
attr-dict `:` type(operands) `->` type(results)
}];
-
}
@@ -502,6 +500,7 @@ def SPIRV_TosaMaxPool2DOp : SPIRV_TosaOpWithResult<"MaxPool2D", 7, [Pure,
Performs a max pooling over the given input tensor. A sliding window of
size given by <kernel size> is passed over the input tensor, with the
maximum value being placed in the output tensor.
+ NAN Propagation Mode is ignored for inputs using integer element types.
References:
* https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_max_pool2d
@@ -640,7 +639,6 @@ def SPIRV_TosaTransposeConv2DOp : SPIRV_TosaConvolutionOp<"TransposeConv2D", 9>
$weight_zp
attr-dict `:` type(operands) `->` type(results)
}];
-
}
@@ -655,6 +653,7 @@ def SPIRV_TosaClampOp : SPIRV_TosaOpWithResult<"Clamp", 10, [Pure,
input type.
No zero point subtraction is done to the values, thus to clamp to the zero
point value, the zero point itself should be supplied as the minimum value.
+ NAN Propagation Mode is ignored for inputs using integer element types.
References:
* https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_clamp
@@ -820,7 +819,7 @@ def SPIRV_TosaAddOp : SPIRV_TosaElementwiseBinaryOp<"Add", 14, [NoMemoryEffect]>
let description = [{
Elementwise Addition of input1 and input2. Axis of size 1 will be broadcast,
as necessary. Rank of input tensors must match. The behavior is undefined if
- the addition overflows or underflows the signed integer range.
+ the integer addition overflows or underflows the signed integer range.
References:
* https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_add
@@ -1204,4 +1203,275 @@ def SPIRV_TosaLogicalXorOp : SPIRV_TosaElementwiseBinaryOp<"LogicalXor", 24, [Pu
}];
}
+
+def SPIRV_TosaMaximumOp : SPIRV_TosaElementwiseBinaryOp<"Maximum", 25, [Pure,
+ TypeConstraintImplicationOn<"input1", AnyInteger, "input1", [I32]>,
+ TypeConstraintImplicationOn<"input2", AnyInteger, "input2", [I32]>,
+ TypeConstraintImplicationOn<"output", AnyInteger, "output", [I32]>]> {
+ let summary = "Maximum.";
+
+ let description = [{
+ Elementwise maximum of input1 and input2. Axis of size 1 will be broadcast,
+ as necessary. Rank of input tensors must match. Integer element types are
+ always interpreted as signed.
+ NAN Propagation Mode is ignored for inputs using integer element types.
+
+ References:
+ * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_maximum
+ * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_maximum
+
+ #### Example:
+ ```mlir
+ %1 = spirv.Tosa.Maximum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<1x2x65533x1xi32>, !spirv.arm.tensor<1x2x65533x2xi32> -> !spirv.arm.tensor<1x2x65533x2xi32>
+ %1 = spirv.Tosa.Maximum nan_mode = <Ignore>, %arg0, %arg1 : !spirv.arm.tensor<1x12x14x7xf16>, !spirv.arm.tensor<11x12x14x7xf16> -> !spirv.arm.tensor<11x12x14x7xf16>
+ ```
+ }];
+
+ let arguments = (ins
+ SPIRV_TosaExtNaNPropagationModeAttr: $nan_mode,
+ SPIRV_TosaNumerical_TensorArm: $input1,
+ SPIRV_TosaNumerical_TensorArm: $input2
+ );
+
+ let results = (outs
+ SPIRV_TosaNumerical_TensorArm: $output
+ );
+
+ let assemblyFormat = [{
+ `nan_mode` `=` $nan_mode `,`
+ $input1 `,`
+ $input2
+ attr-dict `:` type(operands) `->` type(results)
+ }];
+}
+
+
+def SPIRV_TosaMinimumOp : SPIRV_TosaElementwiseBinaryOp<"Minimum", 26, [Pure,
+ TypeConstraintImplicationOn<"input1", AnyInteger, "input1", [I32]>,
+ TypeConstraintImplicationOn<"input2", AnyInteger, "input2", [I32]>,
+ TypeConstraintImplicationOn<"output", AnyInteger, "output", [I32]>]> {
+ let summary = "Minimum.";
+
+ let description = [{
+ Elementwise minimum of input1 and input2. Axis of size 1 will be broadcast,
+ as necessary. Rank of input tensors must match. Integer element types are
+ always interpreted as signed.
+ NAN Propagation Mode is ignored for inputs using integer element types.
+
+ References:
+ * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_minimum
+ * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_minimum
+
+ #### Example:
+ ```mlir
+ %1 = spirv.Tosa.Minimum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<15x2x10x11xi32>, !spirv.arm.tensor<15x1x10x11xi32> -> !spirv.arm.tensor<15x2x10x11xi32>
+ %1 = spirv.Tosa.Minimum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<1x65531x2x1xf32>, !spirv.arm.tensor<1x1x2x1xf32> -> !spirv.arm.tensor<1x65531x2x1xf32>
+ ```
+ }];
+
+ let arguments = (ins
+ SPIRV_TosaExtNaNPropagationModeAttr: $nan_mode,
+ SPIRV_TosaNumerical_TensorArm: $input1,
+ SPIRV_TosaNumerical_TensorArm: $input2
+ );
+
+ let results = (outs
+ SPIRV_TosaNumerical_TensorArm: $output
+ );
+
+ let assemblyFormat = [{
+ `nan_mode` `=` $nan_mode `,`
+ $input1 `,`
+ $input2
+ attr-dict `:` type(operands) `->` type(results)
+ }];
+}
+
+
+def SPIRV_TosaMulOp : SPIRV_TosaBinaryOp<"Mul", 27, [NoMemoryEffect,
+ AllElementTypesMatch<["input1", "input2"]>,
+ AllRanksMatch<["input1", "input2", "output"]>,
+ TypeConstraintImplicationOn<"input1", F16, "output", [F16]>,
+ TypeConstraintImplicationOn<"input1", F32, "output", [F32]>,
+ TypeConstraintImplicationOn<"input1", BF16, "output", [BF16]>,
+ TypeConstraintImplicationOn<"input1", AnyInteger, "output", [I32]>]> {
+ let summary = "Multiplication operator.";
+
+ let description = [{
+ Elementwise Multiplication (Hadamard product) of input1 and input2.
+ Axis of size 1 will be broadcast, as necessary. Rank of input tensors must
+ match. The shift value is used to right shift the result (rounded up) and
+ it is used only if input element type is i32 and it must be zero for the
+ other element types. The behavior is undefined if the integer
+ multiplication overflows or underflows the signed integer range or the
+ shift value exceeds the bit-width of i32.
+
+ References:
+ * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_mul
+ * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_mul
+
+ #### Example:
+ ```mlir
+ %1 = spirv.Tosa.Mul %arg0, %arg1, %0 : !spirv.arm.tensor<34x21x39xi32>, !spirv.arm.tensor<34x21x1xi32>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<34x21x39xi32>
+ %1 = spirv.Tosa.Mul %arg0, %arg1, %0 : !spirv.arm.tensor<57x1x55xf16>, !spirv.arm.tensor<57x37x55xf16>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<57x37x55xf16>
+ ```
+ }];
+
+ let arguments = (ins
+ SPIRV_TosaNumerical_TensorArm: $input1,
+ SPIRV_TosaNumerical_TensorArm: $input2,
+ SPIRV_Int8_1DTensorArmOfLength1: $shift
+ );
+
+ let results = (outs
+ SPIRV_TosaNumerical_TensorArm: $output
+ );
+
+ let assemblyFormat = [{
+ $input1 `,`
+ $input2 `,`
+ $shift
+ attr-dict `:` type(operands) `->` type(results)
+ }];
+}
+
+
+def SPIRV_TosaPowOp : SPIRV_TosaElementwiseBinaryOp<"Pow", 28, [NoMemoryEffect]> {
+ let summary = "Power opertor.";
+
+ let description = [{
+ Elementwise input1 value raised to the Power of input2.
+ Axis of size 1 will be broadcast, as necessary. Rank of input tensors must
+ match. The behavior is undefined if the the input1 value is negative, or
+ both input values are zero or negative, or both input values are NAN or
+ infinite.
+
+ References:
+ * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_pow
+ * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_pow
+
+ #### Example:
+ ```mlir
+ %0 = spirv.Tosa.Pow %arg0, %arg1 : !spirv.arm.tensor<1x52x53xf16>, !spirv.arm.tensor<44x52x53xf16> -> !spirv.arm.tensor<44x52x53xf16>
+ ```
+ }];
+
+ let arguments = (ins
+ SPIRV_TosaFloat_TensorArm: $input1,
+ SPIRV_TosaFloat_TensorArm: $input2
+ );
+
+ let results = (outs
+ SPIRV_TosaFloat_TensorArm: $output
+ );
+
+ let assemblyFormat = [{
+ $input1 `,`
+ $input2
+ attr-dict `:` type(operands) `->` type(results)
+ }];
+}
+
+
+def SPIRV_TosaSubOp : SPIRV_TosaElementwiseBinaryOp<"Sub", 29, [NoMemoryEffect,
+ TypeConstraintImplicationOn<"input1", AnyInteger, "input1", [I32]>,
+ TypeConstraintImplicationOn<"input2", AnyInteger, "input2", [I32]>,
+ TypeConstraintImplicationOn<"output", AnyInteger, "output", [I32]>]> {
+ let summary = "Subtraction operator.";
+
+ let description = [{
+ Elementwise Subtraction of input1 and input2. Axis of size 1 will be
+ broadcast as necessary. Rank of input tensors must match. The behavior
+ is undefined if the integer subtraction overflows or underflows the
+ signed integer range.
+
+ References:
+ * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_sub
+ * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_sub
+
+ #### Example:
+ ```mlir
+ %0 = spirv.Tosa.Sub %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi32>, !spirv.arm.tensor<1x10x6x6xi32> -> !spirv.arm.tensor<6x10x6x6xi32>
+ %0 = spirv.Tosa.Sub %arg0, %arg1 : !spirv.arm.tensor<1x10x13x12xf16>, !spirv.arm.tensor<6x10x13x12xf16> -> !spirv.arm.tensor<6x10x13x12xf16>
+ ```
+ }];
+
+ let arguments = (ins
+ SPIRV_TosaNumerical_TensorArm: $input1,
+ SPIRV_TosaNumerical_TensorArm: $input2
+ );
+
+ let results = (outs
+ SPIRV_TosaNumerical_TensorArm: $output
+ );
+
+ let assemblyFormat = [{
+ $input1 `,`
+ $input2
+ attr-dict `:` type(operands) `->` type(results)
+ }];
+}
+
+
+def SPIRV_TosaTableOp : SPIRV_TosaOpWithResult<"Table", 30, [NoMemoryEffect,
+ AllElementTypesMatch<["input1", "table"]>,
+ AllShapesMatch<["input1", "output"]>,
+ TypeConstraintImplicationOn<"input1", I8, "output", [I8]>,
+ TypeConstraintImplicationOn<"input1", I16, "output", [I32]>,
+ TableSizeConstraint<"input1", I8, 256>,
+ TableSizeConstraint<"input1", I16, 513>]> {
+ let summary = "Table lookup operator.";
+
+ let description = [{
+ Table lookup operation. For int8_t, perform a 256 entry table lookup
+ returning an int8_t value. For int16_t tables, the int16_t input is treated
+ as a fixed-point 9.7 value. The most significant 9 bits are used to index
+ into the table. The fractional 7 bits are used to interpolate based on
+ table[index] and table[index+1]. The behavior is undefined if during the
+ interpolation step, the integer subtraction table[index+1] - table[index]
+ overflows or underflows the signed int16 range.
+
+ For int16_t inputs, this operator returns a 16.7 interpolated value in an
+ int32_t. This value can then be input to the `spirv.Tosa.Rescale` operator
+ to scale to the required output data type. Note that int16_t table has 513
+ values to handle table[index+1] when index=511.
+
+ An int16_t to int16_t table lookup can be constructed as follows:
+ * Use the table operator to produce a fixed point 16.7 interpolated result
+ * Use `spirv.Tosa.Rescale` (in_t=int32_t, out_t=int16_t, scale=1<<14, shift=21)
+ to scale the output to int16_t range (or alternate scale as required)
+
+ References:
+ * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_table
+ * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_table
+
+ #### Example:
+ ```mlir
+ %1 = spirv.Tosa.Table %arg0, %0 : !spirv.arm.tensor<3x2x15x7xi8>, !spirv.arm.tensor<256xi8> -> !spirv.arm.tensor<3x2x15x7xi8>
+ ```
+ }];
+
+ let arguments = (ins
+ SPIRV_TosaInteger_TensorArm: $input1,
+ SPIRV_TosaInteger_TensorArm1D: $table
+ );
+
+ let results = (outs
+ SPIRV_TosaInteger_TensorArm: $output
+ );
+
+ let assemblyFormat = [{
+ $input1 `,`
+ $table
+ attr-dict `:` type(operands) `->` type(results)
+ }];
+
+ let extraClassDeclaration = extraBaseClassDeclaration#[{
+ ::mlir::spirv::TensorArmType getInput1Type() {
+ return cast<::mlir::spirv::TensorArmType>(getInput1().getType());
+ }
+ }];
+}
+
+
#endif // MLIR_DIALECT_SPIRV_IR_TOSA_OPS
diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaTypes.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaTypes.td
index 126f47dd44f5f..89d242781f5f7 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaTypes.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaTypes.td
@@ -39,6 +39,7 @@ class TensorArmRankOf<list<Type> allowedTypes, list<int> ranks>
!interleave(!foreach(rank, ranks, rank # "D"), "/") # " tensorArm">;
def SPIRV_Float32_TensorArm3D: TensorArmRankOf<[SPIRV_Float32], [3]>;
+def SPIRV_TosaInteger_TensorArm1D : TensorArmRankOf<[SPIRV_TosaInteger], [1]>;
def SPIRV_TosaNumerical_TensorArm1D : TensorArmRankOf<[SPIRV_TosaNumerical], [1]>;
def SPIRV_TosaNumerical_TensorArm3D : TensorArmRankOf<[SPIRV_TosaNumerical], [3]>;
def SPIRV_TosaNumerical_TensorArm4D : TensorArmRankOf<[SPIRV_TosaNumerical], [4]>;
@@ -70,8 +71,10 @@ def SPIRV_DenseElementAttrsWithTensorArmType : AttrConstraint<
def SPIRV_Int32_1DTensorArmOfLength2Attr : ConfinedAttr<RankedI32ElementsAttr<[2]>, [SPIRV_DenseElementAttrsWithTensorArmType]>;
def SPIRV_Int32_1DTensorArmOfLength3Attr : ConfinedAttr<RankedI32ElementsAttr<[3]>, [SPIRV_DenseElementAttrsWithTensorArmType]>;
def SPIRV_Int32_1DTensorArmOfLength4Attr : ConfinedAttr<RankedI32ElementsAttr<[4]>, [SPIRV_DenseElementAttrsWithTensorArmType]>;
+def SPIRV_Int32_1DTensorArmOfLength5Attr : ConfinedAttr<RankedI32ElementsAttr<[5]>, [SPIRV_DenseElementAttrsWithTensorArmType]>;
def SPIRV_Int32_1DTensorArmOfLength6Attr : ConfinedAttr<RankedI32ElementsAttr<[6]>, [SPIRV_DenseElementAttrsWithTensorArmType]>;
+def SPIRV_Int8_1DTensorArmOfLength1 : SPIRV_1DTensorArmOfLengthAndType<[1], [SPIRV_Int8]>;
def SPIRV_TosaNumerical_1DTensorArmOfLength1 : SPIRV_1DTensorArmOfLengthAndType<[1], [SPIRV_TosaNumerical]>;
// Struct type
@@ -130,5 +133,9 @@ class MatchBroadcastableShapes<string input1, string input2, string output>:
"})">]>
>;
+class TableSizeConstraint<string input, Type type, int size>:
+ PredOpTrait<"table must have size " # size # " if " # input # " has element type " # type.summary,
+ Implies<ElementTypeIsPred<input, type>, [CPred<"::llvm::cast<::mlir::ShapedType>(getTable().getType()).getShape()[0] == " # size>]>
+ >;
#endif // MLIR_DIALECT_SPIRV_IR_TOSA_TYPES
diff --git a/mlir/test/Dialect/SPIRV/IR/tosa-ops-verification.mlir b/mlir/test/Dialect/SPIRV/IR/tosa-ops-verification.mlir
index ce224ef9ad6f6..d13dad7b1dd41 100644
--- a/mlir/test/Dialect/SPIRV/IR/tosa-ops-verification.mlir
+++ b/mlir/test/Dialect/SPIRV/IR/tosa-ops-verification.mlir
@@ -809,7 +809,6 @@ spirv.ARM.Graph @logicalleftshift_output_shape_does_not_match_broadcast_shape(%a
spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<1x10x6x6xi32>
}
-
//===----------------------------------------------------------------------===//
// spirv.TOSA.LogicalRightShift
//===----------------------------------------------------------------------===//
@@ -911,3 +910,299 @@ spirv.ARM.Graph @logicalxor_output_shape_does_not_match_broadcast_shape(%arg0: !
%0 = spirv.Tosa.LogicalXor %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi1>, !spirv.arm.tensor<1x10x6x6xi1> -> !spirv.arm.tensor<1x10x6x6xi1>
spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<1x10x6x6xi1>
}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Maximum
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @maximum_input_ranks_not_matching(%arg0: !spirv.arm.tensor<6x10x6xi32>, %arg1: !spirv.arm.tensor<1x10x6x6xi32>) -> (!spirv.arm.tensor<6x10x6x6xi32>) {
+ // expected-error @+1 {{op failed to verify that all of {input1, input2, output} have same rank}}
+ %0 = spirv.Tosa.Maximum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<6x10x6xi32>, !spirv.arm.tensor<1x10x6x6xi32> -> !spirv.arm.tensor<6x10x6x6xi32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xi32>
+}
+
+spirv.ARM.Graph @maximum_input_element_types_not_matching(%arg0: !spirv.arm.tensor<6x10x6x6xf16>, %arg1: !spirv.arm.tensor<1x10x6x6xf32>) -> (!spirv.arm.tensor<6x10x6x6xf16>) {
+ // expected-error @+1 {{op failed to verify that all of {input1, input2} have same element type}}
+ %0 = spirv.Tosa.Maximum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xf16>, !spirv.arm.tensor<1x10x6x6xf32> -> !spirv.arm.tensor<6x10x6x6xf16>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xf16>
+}
+
+spirv.ARM.Graph @maximum_input_output_element_types_not_matching(%arg0: !spirv.arm.tensor<6x10x6x6xf32>, %arg1: !spirv.arm.tensor<1x10x6x6xf32>) -> (!spirv.arm.tensor<6x10x6x6xf16>) {
+ // expected-error @+1 {{op failed to verify that all of {input1, output} have same element type}}
+ %0 = spirv.Tosa.Maximum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xf32>, !spirv.arm.tensor<1x10x6x6xf32> -> !spirv.arm.tensor<6x10x6x6xf16>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xf16>
+}
+
+spirv.ARM.Graph @maximum_inputs_not_broadcastable(%arg0: !spirv.arm.tensor<6x10x6x6xi32>, %arg1: !spirv.arm.tensor<2x10x6x6xi32>) -> (!spirv.arm.tensor<6x10x6x6xi32>) {
+ // expected-error @+1 {{op failed to verify that the shape of input1 and input2 are compatible for broadcasting and the broadcast shape is equal to the output shape}}
+ %0 = spirv.Tosa.Maximum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi32>, !spirv.arm.tensor<2x10x6x6xi32> -> !spirv.arm.tensor<6x10x6x6xi32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xi32>
+}
+
+spirv.ARM.Graph @maximum_output_shape_does_not_match_broadcast_shape(%arg0: !spirv.arm.tensor<6x10x6x6xi32>, %arg1: !spirv.arm.tensor<1x10x6x6xi32>) -> (!spirv.arm.tensor<1x10x6x6xi32>) {
+ // expected-error @+1 {{op failed to verify that the shape of input1 and input2 are compatible for broadcasting and the broadcast shape is equal to the output shape}}
+ %0 = spirv.Tosa.Maximum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi32>, !spirv.arm.tensor<1x10x6x6xi32> -> !spirv.arm.tensor<1x10x6x6xi32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<1x10x6x6xi32>
+}
+
+spirv.ARM.Graph @maximum_integer_input1_must_be_i32(%arg0: !spirv.arm.tensor<6x10x6x6xi8>, %arg1: !spirv.arm.tensor<1x10x6x6xi32>) -> (!spirv.arm.tensor<6x10x6x6xi32>) {
+ // expected-error @+1 {{op failed to verify that if input1 has type integer then input1 must have a type in [32-bit signless integer]}}
+ %0 = spirv.Tosa.Maximum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi8>, !spirv.arm.tensor<1x10x6x6xi32> -> !spirv.arm.tensor<6x10x6x6xi32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xi32>
+}
+
+spirv.ARM.Graph @maximum_integer_input2_must_be_i32(%arg0: !spirv.arm.tensor<6x10x6x6xi32>, %arg1: !spirv.arm.tensor<1x10x6x6xi8>) -> (!spirv.arm.tensor<6x10x6x6xi32>) {
+ // expected-error @+1 {{op failed to verify that if input2 has type integer then input2 must have a type in [32-bit signless integer]}}
+ %0 = spirv.Tosa.Maximum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi32>, !spirv.arm.tensor<1x10x6x6xi8> -> !spirv.arm.tensor<6x10x6x6xi32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xi32>
+}
+
+spirv.ARM.Graph @maximum_integer_output_must_be_i32(%arg0: !spirv.arm.tensor<6x10x6x6xi32>, %arg1: !spirv.arm.tensor<1x10x6x6xi32>) -> (!spirv.arm.tensor<6x10x6x6xi8>) {
+ // expected-error @+1 {{op failed to verify that if output has type integer then output must have a type in [32-bit signless integer]}}
+ %0 = spirv.Tosa.Maximum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi32>, !spirv.arm.tensor<1x10x6x6xi32> -> !spirv.arm.tensor<6x10x6x6xi8>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xi8>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Minimum
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @minimum_input_ranks_not_matching(%arg0: !spirv.arm.tensor<6x10x6xi32>, %arg1: !spirv.arm.tensor<1x10x6x6xi32>) -> (!spirv.arm.tensor<6x10x6x6xi32>) {
+ // expected-error @+1 {{op failed to verify that all of {input1, input2, output} have same rank}}
+ %0 = spirv.Tosa.Minimum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<6x10x6xi32>, !spirv.arm.tensor<1x10x6x6xi32> -> !spirv.arm.tensor<6x10x6x6xi32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xi32>
+}
+
+spirv.ARM.Graph @minimum_input_element_types_not_matching(%arg0: !spirv.arm.tensor<6x10x6x6xf16>, %arg1: !spirv.arm.tensor<1x10x6x6xf32>) -> (!spirv.arm.tensor<6x10x6x6xf16>) {
+ // expected-error @+1 {{op failed to verify that all of {input1, input2} have same element type}}
+ %0 = spirv.Tosa.Minimum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xf16>, !spirv.arm.tensor<1x10x6x6xf32> -> !spirv.arm.tensor<6x10x6x6xf16>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xf16>
+}
+
+spirv.ARM.Graph @minimum_input_output_element_types_not_matching(%arg0: !spirv.arm.tensor<6x10x6x6xf32>, %arg1: !spirv.arm.tensor<1x10x6x6xf32>) -> (!spirv.arm.tensor<6x10x6x6xf16>) {
+ // expected-error @+1 {{op failed to verify that all of {input1, output} have same element type}}
+ %0 = spirv.Tosa.Minimum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xf32>, !spirv.arm.tensor<1x10x6x6xf32> -> !spirv.arm.tensor<6x10x6x6xf16>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xf16>
+}
+
+spirv.ARM.Graph @minimum_inputs_not_broadcastable(%arg0: !spirv.arm.tensor<6x10x6x6xi32>, %arg1: !spirv.arm.tensor<2x10x6x6xi32>) -> (!spirv.arm.tensor<6x10x6x6xi32>) {
+ // expected-error @+1 {{op failed to verify that the shape of input1 and input2 are compatible for broadcasting and the broadcast shape is equal to the output shape}}
+ %0 = spirv.Tosa.Minimum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi32>, !spirv.arm.tensor<2x10x6x6xi32> -> !spirv.arm.tensor<6x10x6x6xi32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xi32>
+}
+
+spirv.ARM.Graph @minimum_output_shape_does_not_match_broadcast_shape(%arg0: !spirv.arm.tensor<6x10x6x6xi32>, %arg1: !spirv.arm.tensor<1x10x6x6xi32>) -> (!spirv.arm.tensor<1x10x6x6xi32>) {
+ // expected-error @+1 {{op failed to verify that the shape of input1 and input2 are compatible for broadcasting and the broadcast shape is equal to the output shape}}
+ %0 = spirv.Tosa.Minimum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi32>, !spirv.arm.tensor<1x10x6x6xi32> -> !spirv.arm.tensor<1x10x6x6xi32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<1x10x6x6xi32>
+}
+
+spirv.ARM.Graph @minimum_integer_input1_must_be_i32(%arg0: !spirv.arm.tensor<6x10x6x6xi8>, %arg1: !spirv.arm.tensor<1x10x6x6xi32>) -> (!spirv.arm.tensor<6x10x6x6xi32>) {
+ // expected-error @+1 {{op failed to verify that if input1 has type integer then input1 must have a type in [32-bit signless integer]}}
+ %0 = spirv.Tosa.Minimum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi8>, !spirv.arm.tensor<1x10x6x6xi32> -> !spirv.arm.tensor<6x10x6x6xi32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xi32>
+}
+
+spirv.ARM.Graph @minimum_integer_input2_must_be_i32(%arg0: !spirv.arm.tensor<6x10x6x6xi32>, %arg1: !spirv.arm.tensor<1x10x6x6xi8>) -> (!spirv.arm.tensor<6x10x6x6xi32>) {
+ // expected-error @+1 {{op failed to verify that if input2 has type integer then input2 must have a type in [32-bit signless integer]}}
+ %0 = spirv.Tosa.Minimum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi32>, !spirv.arm.tensor<1x10x6x6xi8> -> !spirv.arm.tensor<6x10x6x6xi32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xi32>
+}
+
+spirv.ARM.Graph @minimum_integer_output_must_be_i32(%arg0: !spirv.arm.tensor<6x10x6x6xi32>, %arg1: !spirv.arm.tensor<1x10x6x6xi32>) -> (!spirv.arm.tensor<6x10x6x6xi8>) {
+ // expected-error @+1 {{op failed to verify that if output has type integer then output must have a type in [32-bit signless integer]}}
+ %0 = spirv.Tosa.Minimum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi32>, !spirv.arm.tensor<1x10x6x6xi32> -> !spirv.arm.tensor<6x10x6x6xi8>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xi8>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Mul
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @mul_input_ranks_not_matching(%arg0: !spirv.arm.tensor<34x21xi8>, %arg1: !spirv.arm.tensor<34x21x1xi8>) -> (!spirv.arm.tensor<34x21x39xi32>) {
+ %0 = spirv.Constant dense<31> : !spirv.arm.tensor<1xi8>
+ // expected-error @+1 {{op failed to verify that all of {input1, input2, output} have same rank}}
+ %1 = spirv.Tosa.Mul %arg0, %arg1, %0 : !spirv.arm.tensor<34x21xi8>, !spirv.arm.tensor<34x21x1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<34x21x39xi32>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<34x21x39xi32>
+}
+
+spirv.ARM.Graph @mul_input_element_types_not_matching(%arg0: !spirv.arm.tensor<34x21x39xi8>, %arg1: !spirv.arm.tensor<34x21x1xi16>) -> (!spirv.arm.tensor<34x21x39xi32>) {
+ %0 = spirv.Constant dense<31> : !spirv.arm.tensor<1xi8>
+ // expected-error @+1 {{op failed to verify that all of {input1, input2} have same element type}}
+ %1 = spirv.Tosa.Mul %arg0, %arg1, %0 : !spirv.arm.tensor<34x21x39xi8>, !spirv.arm.tensor<34x21x1xi16>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<34x21x39xi32>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<34x21x39xi32>
+}
+
+spirv.ARM.Graph @mul_inputs_not_broadcastable(%arg0: !spirv.arm.tensor<34x21x39xi8>, %arg1: !spirv.arm.tensor<34x20x1xi8>) -> (!spirv.arm.tensor<34x21x39xi32>) {
+ %0 = spirv.Constant dense<31> : !spirv.arm.tensor<1xi8>
+ // expected-error @+1 {{op failed to verify that the shape of input1 and input2 are compatible for broadcasting and the broadcast shape is equal to the output shape}}
+ %1 = spirv.Tosa.Mul %arg0, %arg1, %0 : !spirv.arm.tensor<34x21x39xi8>, !spirv.arm.tensor<34x20x1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<34x21x39xi32>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<34x21x39xi32>
+}
+
+spirv.ARM.Graph @mul_output_shape_does_not_match_broadcast_shape(%arg0: !spirv.arm.tensor<34x21x39xi8>, %arg1: !spirv.arm.tensor<34x21x1xi8>) -> (!spirv.arm.tensor<34x21x1xi32>) {
+ %0 = spirv.Constant dense<31> : !spirv.arm.tensor<1xi8>
+ // expected-error @+1 {{op failed to verify that the shape of input1 and input2 are compatible for broadcasting and the broadcast shape is equal to the output shape}}
+ %1 = spirv.Tosa.Mul %arg0, %arg1, %0 : !spirv.arm.tensor<34x21x39xi8>, !spirv.arm.tensor<34x21x1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<34x21x1xi32>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<34x21x1xi32>
+}
+
+spirv.ARM.Graph @mul_ouput_must_have_i32_as_element_type(%arg0: !spirv.arm.tensor<34x21x39xi8>, %arg1: !spirv.arm.tensor<34x21x1xi8>) -> (!spirv.arm.tensor<34x21x39xi16>) {
+ %0 = spirv.Constant dense<31> : !spirv.arm.tensor<1xi8>
+ // expected-error @+1 {{op failed to verify that if input1 has type integer then output must have a type in [32-bit signless integer]}}
+ %1 = spirv.Tosa.Mul %arg0, %arg1, %0 : !spirv.arm.tensor<34x21x39xi8>, !spirv.arm.tensor<34x21x1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<34x21x39xi16>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<34x21x39xi16>
+}
+
+spirv.ARM.Graph @mul_input_with_element_type_f16_must_produce_an_output_with_element_type_f16(%arg0: !spirv.arm.tensor<57x1x55xf16>, %arg1: !spirv.arm.tensor<57x37x55xf16>) -> (!spirv.arm.tensor<57x37x55xf32>) {
+ %0 = spirv.Constant dense<0> : !spirv.arm.tensor<1xi8>
+ // expected-error @+1 {{op failed to verify that if input1 has type 16-bit float then output must have a type in [16-bit float]}}
+ %1 = spirv.Tosa.Mul %arg0, %arg1, %0 : !spirv.arm.tensor<57x1x55xf16>, !spirv.arm.tensor<57x37x55xf16>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<57x37x55xf32>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<57x37x55xf32>
+}
+
+spirv.ARM.Graph @mul_input_with_element_type_f32_must_produce_an_output_with_element_type_f32(%arg0: !spirv.arm.tensor<57x1x55xf32>, %arg1: !spirv.arm.tensor<57x37x55xf32>) -> (!spirv.arm.tensor<57x37x55xf16>) {
+ %0 = spirv.Constant dense<0> : !spirv.arm.tensor<1xi8>
+ // expected-error @+1 {{op failed to verify that if input1 has type 32-bit float then output must have a type in [32-bit float]}}
+ %1 = spirv.Tosa.Mul %arg0, %arg1, %0 : !spirv.arm.tensor<57x1x55xf32>, !spirv.arm.tensor<57x37x55xf32>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<57x37x55xf16>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<57x37x55xf16>
+}
+
+spirv.ARM.Graph @mul_input_with_element_type_bf16_must_produce_an_output_with_element_type_bf16(%arg0: !spirv.arm.tensor<57x1x55xbf16>, %arg1: !spirv.arm.tensor<57x37x55xbf16>) -> (!spirv.arm.tensor<57x37x55xf32>) {
+ %0 = spirv.Constant dense<0> : !spirv.arm.tensor<1xi8>
+ // expected-error @+1 {{op failed to verify that if input1 has type bfloat16 type then output must have a type in [bfloat16 type]}}
+ %1 = spirv.Tosa.Mul %arg0, %arg1, %0 : !spirv.arm.tensor<57x1x55xbf16>, !spirv.arm.tensor<57x37x55xbf16>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<57x37x55xf32>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<57x37x55xf32>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Pow
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @pow_input_ranks_not_matching(%arg0: !spirv.arm.tensor<52x53xf16>, %arg1: !spirv.arm.tensor<44x52x53xf16>) -> (!spirv.arm.tensor<44x52x53xf16>) {
+ // expected-error @+1 {{op failed to verify that all of {input1, input2, output} have same rank}}
+ %0 = spirv.Tosa.Pow %arg0, %arg1 : !spirv.arm.tensor<52x53xf16>, !spirv.arm.tensor<44x52x53xf16> -> !spirv.arm.tensor<44x52x53xf16>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<44x52x53xf16>
+}
+
+spirv.ARM.Graph @pow_inputs_with_non_matching_element_types(%arg0: !spirv.arm.tensor<1x52x53xf16>, %arg1: !spirv.arm.tensor<44x52x53xf32>) -> (!spirv.arm.tensor<44x52x53xf16>) {
+ // expected-error @+1 {{op failed to verify that all of {input1, input2} have same element type}}
+ %0 = spirv.Tosa.Pow %arg0, %arg1 : !spirv.arm.tensor<1x52x53xf16>, !spirv.arm.tensor<44x52x53xf32> -> !spirv.arm.tensor<44x52x53xf16>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<44x52x53xf16>
+}
+
+spirv.ARM.Graph @pow_input_output_element_types_not_matching(%arg0: !spirv.arm.tensor<1x52x53xf16>, %arg1: !spirv.arm.tensor<44x52x53xf16>) -> (!spirv.arm.tensor<44x52x53xf32>) {
+ // expected-error @+1 {{op failed to verify that all of {input1, output} have same element type}}
+ %0 = spirv.Tosa.Pow %arg0, %arg1 : !spirv.arm.tensor<1x52x53xf16>, !spirv.arm.tensor<44x52x53xf16> -> !spirv.arm.tensor<44x52x53xf32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<44x52x53xf32>
+}
+
+spirv.ARM.Graph @pow_inputs_not_broadcastable(%arg0: !spirv.arm.tensor<6x10x6x6xf32>, %arg1: !spirv.arm.tensor<2x10x6x6xf32>) -> (!spirv.arm.tensor<6x10x6x6xf32>) {
+ // expected-error @+1 {{op failed to verify that the shape of input1 and input2 are compatible for broadcasting and the broadcast shape is equal to the output shape}}
+ %0 = spirv.Tosa.Pow %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xf32>, !spirv.arm.tensor<2x10x6x6xf32> -> !spirv.arm.tensor<6x10x6x6xf32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xf32>
+}
+
+spirv.ARM.Graph @pow_output_shape_does_not_match_broadcast_shape(%arg0: !spirv.arm.tensor<6x10x6x6xf32>, %arg1: !spirv.arm.tensor<1x10x6x6xf32>) -> (!spirv.arm.tensor<1x10x6x6xf32>) {
+ // expected-error @+1 {{op failed to verify that the shape of input1 and input2 are compatible for broadcasting and the broadcast shape is equal to the output shape}}
+ %0 = spirv.Tosa.Pow %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xf32>, !spirv.arm.tensor<1x10x6x6xf32> -> !spirv.arm.tensor<1x10x6x6xf32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<1x10x6x6xf32>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Sub
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @sub_input_ranks_not_matching(%arg0: !spirv.arm.tensor<6x10x6xi32>, %arg1: !spirv.arm.tensor<1x10x6x6xi32>) -> (!spirv.arm.tensor<6x10x6x6xi32>) {
+ // expected-error @+1 {{op failed to verify that all of {input1, input2, output} have same rank}}
+ %0 = spirv.Tosa.Sub %arg0, %arg1 : !spirv.arm.tensor<6x10x6xi32>, !spirv.arm.tensor<1x10x6x6xi32> -> !spirv.arm.tensor<6x10x6x6xi32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xi32>
+}
+
+spirv.ARM.Graph @sub_input_element_types_not_matching(%arg0: !spirv.arm.tensor<6x10x6x6xf16>, %arg1: !spirv.arm.tensor<1x10x6x6xf32>) -> (!spirv.arm.tensor<6x10x6x6xf32>) {
+ // expected-error @+1 {{op failed to verify that all of {input1, output} have same element type}}
+ %0 = spirv.Tosa.Sub %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xf16>, !spirv.arm.tensor<1x10x6x6xf32> -> !spirv.arm.tensor<6x10x6x6xf32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xf32>
+}
+
+spirv.ARM.Graph @sub_input1_input2_element_types_not_matching(%arg0: !spirv.arm.tensor<6x10x6x6xf16>, %arg1: !spirv.arm.tensor<1x10x6x6xf32>) -> (!spirv.arm.tensor<6x10x6x6xf16>) {
+ // expected-error @+1 {{op failed to verify that all of {input1, input2} have same element type}}
+ %0 = spirv.Tosa.Sub %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xf16>, !spirv.arm.tensor<1x10x6x6xf32> -> !spirv.arm.tensor<6x10x6x6xf16>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xf16>
+}
+
+spirv.ARM.Graph @sub_inputs_not_broadcastable(%arg0: !spirv.arm.tensor<6x10x6x6xi32>, %arg1: !spirv.arm.tensor<2x10x6x6xi32>) -> (!spirv.arm.tensor<6x10x6x6xi32>) {
+ // expected-error @+1 {{op failed to verify that the shape of input1 and input2 are compatible for broadcasting and the broadcast shape is equal to the output shape}}
+ %0 = spirv.Tosa.Sub %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi32>, !spirv.arm.tensor<2x10x6x6xi32> -> !spirv.arm.tensor<6x10x6x6xi32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xi32>
+}
+
+spirv.ARM.Graph @sub_output_shape_does_not_match_broadcast_shape(%arg0: !spirv.arm.tensor<6x10x6x6xi32>, %arg1: !spirv.arm.tensor<1x10x6x6xi32>) -> (!spirv.arm.tensor<1x10x6x6xi32>) {
+ // expected-error @+1 {{op failed to verify that the shape of input1 and input2 are compatible for broadcasting and the broadcast shape is equal to the output shape}}
+ %0 = spirv.Tosa.Sub %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi32>, !spirv.arm.tensor<1x10x6x6xi32> -> !spirv.arm.tensor<1x10x6x6xi32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<1x10x6x6xi32>
+}
+
+spirv.ARM.Graph @sub_integer_input1_must_be_i32(%arg0: !spirv.arm.tensor<6x10x6x6xi8>, %arg1: !spirv.arm.tensor<1x10x6x6xi32>) -> (!spirv.arm.tensor<6x10x6x6xi32>) {
+ // expected-error @+1 {{op failed to verify that if input1 has type integer then input1 must have a type in [32-bit signless integer]}}
+ %0 = spirv.Tosa.Sub %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi8>, !spirv.arm.tensor<1x10x6x6xi32> -> !spirv.arm.tensor<6x10x6x6xi32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xi32>
+}
+
+spirv.ARM.Graph @sub_integer_input2_must_be_i32(%arg0: !spirv.arm.tensor<6x10x6x6xi32>, %arg1: !spirv.arm.tensor<1x10x6x6xi8>) -> (!spirv.arm.tensor<6x10x6x6xi32>) {
+ // expected-error @+1 {{op failed to verify that if input2 has type integer then input2 must have a type in [32-bit signless integer]}}
+ %0 = spirv.Tosa.Sub %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi32>, !spirv.arm.tensor<1x10x6x6xi8> -> !spirv.arm.tensor<6x10x6x6xi32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xi32>
+}
+
+spirv.ARM.Graph @sub_integer_output_must_be_i32(%arg0: !spirv.arm.tensor<6x10x6x6xi32>, %arg1: !spirv.arm.tensor<1x10x6x6xi32>) -> (!spirv.arm.tensor<6x10x6x6xi8>) {
+ // expected-error @+1 {{op failed to verify that if output has type integer then output must have a type in [32-bit signless integer]}}
+ %0 = spirv.Tosa.Sub %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi32>, !spirv.arm.tensor<1x10x6x6xi32> -> !spirv.arm.tensor<6x10x6x6xi8>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xi8>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Table
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @table_input_and_table_must_have_same_element_type(%arg0: !spirv.arm.tensor<3x2x15x7xi8>) -> (!spirv.arm.tensor<3x2x15x7xi8>) {
+ %0 = spirv.ARM.GraphConstant {graph_constant_id = 0 : i32} : !spirv.arm.tensor<256xi16>
+ // expected-error @+1 {{op failed to verify that all of {input1, table} have same element type}}
+ %1 = spirv.Tosa.Table %arg0, %0 : !spirv.arm.tensor<3x2x15x7xi8>, !spirv.arm.tensor<256xi16> -> !spirv.arm.tensor<3x2x15x7xi8>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<3x2x15x7xi8>
+}
+
+spirv.ARM.Graph @table_input_output_shapes_must_match(%arg0: !spirv.arm.tensor<3x2x15x7xi8>) -> (!spirv.arm.tensor<3x2x15x6xi8>) {
+ %0 = spirv.ARM.GraphConstant {graph_constant_id = 0 : i32} : !spirv.arm.tensor<256xi8>
+ // expected-error @+1 {{op failed to verify that all of {input1, output} have same shape}}
+ %1 = spirv.Tosa.Table %arg0, %0 : !spirv.arm.tensor<3x2x15x7xi8>, !spirv.arm.tensor<256xi8> -> !spirv.arm.tensor<3x2x15x6xi8>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<3x2x15x6xi8>
+}
+
+spirv.ARM.Graph @table_input_with_element_type_i8_requires_a_table_of_size_256(%arg0: !spirv.arm.tensor<3x2x15x7xi8>) -> (!spirv.arm.tensor<3x2x15x7xi8>) {
+ %0 = spirv.ARM.GraphConstant {graph_constant_id = 0 : i32} : !spirv.arm.tensor<513xi8>
+ // expected-error @+1 {{op failed to verify that table must have size 256 if input1 has element type 8-bit signless integer}}
+ %1 = spirv.Tosa.Table %arg0, %0 : !spirv.arm.tensor<3x2x15x7xi8>, !spirv.arm.tensor<513xi8> -> !spirv.arm.tensor<3x2x15x7xi8>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<3x2x15x7xi8>
+}
+
+spirv.ARM.Graph @table_input_with_element_type_i16_requires_a_table_of_size_513(%arg0: !spirv.arm.tensor<3x2x15x7xi16>) -> (!spirv.arm.tensor<3x2x15x7xi32>) {
+ %0 = spirv.ARM.GraphConstant {graph_constant_id = 0 : i32} : !spirv.arm.tensor<256xi16>
+ // expected-error @+1 {{op failed to verify that table must have size 513 if input1 has element type 16-bit signless integer}}
+ %1 = spirv.Tosa.Table %arg0, %0 : !spirv.arm.tensor<3x2x15x7xi16>, !spirv.arm.tensor<256xi16> -> !spirv.arm.tensor<3x2x15x7xi32>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<3x2x15x7xi32>
+}
+
+spirv.ARM.Graph @table_input_with_element_type_i8_requires_an_output_with_element_type_i8(%arg0: !spirv.arm.tensor<3x2x15x7xi8>) -> (!spirv.arm.tensor<3x2x15x7xi16>) {
+ %0 = spirv.ARM.GraphConstant {graph_constant_id = 0 : i32} : !spirv.arm.tensor<256xi8>
+ // expected-error @+1 {{op failed to verify that if input1 has type 8-bit signless integer then output must have a type in [8-bit signless integer]}}
+ %1 = spirv.Tosa.Table %arg0, %0 : !spirv.arm.tensor<3x2x15x7xi8>, !spirv.arm.tensor<256xi8> -> !spirv.arm.tensor<3x2x15x7xi16>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<3x2x15x7xi16>
+}
+
+spirv.ARM.Graph @table_input_with_element_type_i16_requires_an_output_with_element_type_i32(%arg0: !spirv.arm.tensor<3x2x15x7xi16>) -> (!spirv.arm.tensor<3x2x15x7xi16>) {
+ %0 = spirv.ARM.GraphConstant {graph_constant_id = 0 : i32} : !spirv.arm.tensor<513xi16>
+ // expected-error @+1 {{op failed to verify that if input1 has type 16-bit signless integer then output must have a type in [32-bit signless integer]}}
+ %1 = spirv.Tosa.Table %arg0, %0 : !spirv.arm.tensor<3x2x15x7xi16>, !spirv.arm.tensor<513xi16> -> !spirv.arm.tensor<3x2x15x7xi16>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<3x2x15x7xi16>
+}
diff --git a/mlir/test/Dialect/SPIRV/IR/tosa-ops.mlir b/mlir/test/Dialect/SPIRV/IR/tosa-ops.mlir
index faf27c180af8e..6977c6510c390 100644
--- a/mlir/test/Dialect/SPIRV/IR/tosa-ops.mlir
+++ b/mlir/test/Dialect/SPIRV/IR/tosa-ops.mlir
@@ -416,3 +416,116 @@ spirv.ARM.Graph @logicalxor_any(%arg0: !spirv.arm.tensor<11x4x9x12xi1>, %arg1: !
// CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<11x4x9x12xi1>
spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<11x4x9x12xi1>
}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Maximum - PRO-INT
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @maximum_int(%arg0: !spirv.arm.tensor<1x2x65533x1xi32>, %arg1: !spirv.arm.tensor<1x2x65533x2xi32>) -> (!spirv.arm.tensor<1x2x65533x2xi32>) {
+ // CHECK: {{%.*}} = spirv.Tosa.Maximum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<1x2x65533x1xi32>, !spirv.arm.tensor<1x2x65533x2xi32> -> !spirv.arm.tensor<1x2x65533x2xi32>
+ %1 = spirv.Tosa.Maximum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<1x2x65533x1xi32>, !spirv.arm.tensor<1x2x65533x2xi32> -> !spirv.arm.tensor<1x2x65533x2xi32>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<1x2x65533x2xi32>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<1x2x65533x2xi32>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Maximum - PRO-FP
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @maximum_fp(%arg0: !spirv.arm.tensor<1x12x14x7xf16>, %arg1: !spirv.arm.tensor<11x12x14x7xf16>) -> (!spirv.arm.tensor<11x12x14x7xf16>) {
+ // CHECK: {{%.*}} = spirv.Tosa.Maximum nan_mode = <Ignore>, %arg0, %arg1 : !spirv.arm.tensor<1x12x14x7xf16>, !spirv.arm.tensor<11x12x14x7xf16> -> !spirv.arm.tensor<11x12x14x7xf16>
+ %1 = spirv.Tosa.Maximum nan_mode = <Ignore>, %arg0, %arg1 : !spirv.arm.tensor<1x12x14x7xf16>, !spirv.arm.tensor<11x12x14x7xf16> -> !spirv.arm.tensor<11x12x14x7xf16>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<11x12x14x7xf16>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<11x12x14x7xf16>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Minimum - PRO-INT
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @minimum_int(%arg0: !spirv.arm.tensor<15x2x10x11xi32>, %arg1: !spirv.arm.tensor<15x1x10x11xi32>) -> (!spirv.arm.tensor<15x2x10x11xi32>) {
+ // CHECK: {{%.*}} = spirv.Tosa.Minimum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<15x2x10x11xi32>, !spirv.arm.tensor<15x1x10x11xi32> -> !spirv.arm.tensor<15x2x10x11xi32>
+ %1 = spirv.Tosa.Minimum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<15x2x10x11xi32>, !spirv.arm.tensor<15x1x10x11xi32> -> !spirv.arm.tensor<15x2x10x11xi32>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<15x2x10x11xi32>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<15x2x10x11xi32>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Minimum - PRO-FP
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @minimum_fp(%arg0: !spirv.arm.tensor<1x65531x2x1xf32>, %arg1: !spirv.arm.tensor<1x1x2x1xf32>) -> (!spirv.arm.tensor<1x65531x2x1xf32>) {
+ // CHECK: {{%.*}} = spirv.Tosa.Minimum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<1x65531x2x1xf32>, !spirv.arm.tensor<1x1x2x1xf32> -> !spirv.arm.tensor<1x65531x2x1xf32>
+ %1 = spirv.Tosa.Minimum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<1x65531x2x1xf32>, !spirv.arm.tensor<1x1x2x1xf32> -> !spirv.arm.tensor<1x65531x2x1xf32>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<1x65531x2x1xf32>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<1x65531x2x1xf32>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Mul - PRO-INT
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @mul_int(%arg0: !spirv.arm.tensor<34x21x39xi32>, %arg1: !spirv.arm.tensor<34x21x1xi32>) -> (!spirv.arm.tensor<34x21x39xi32>) {
+ %0 = spirv.Constant dense<31> : !spirv.arm.tensor<1xi8>
+ // CHECK: {{%.*}} = spirv.Tosa.Mul %arg0, %arg1, {{%.*}} : !spirv.arm.tensor<34x21x39xi32>, !spirv.arm.tensor<34x21x1xi32>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<34x21x39xi32>
+ %1 = spirv.Tosa.Mul %arg0, %arg1, %0 : !spirv.arm.tensor<34x21x39xi32>, !spirv.arm.tensor<34x21x1xi32>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<34x21x39xi32>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<34x21x39xi32>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<34x21x39xi32>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Mul - PRO-FP
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @mul_fp(%arg0: !spirv.arm.tensor<57x1x55xf16>, %arg1: !spirv.arm.tensor<57x37x55xf16>) -> (!spirv.arm.tensor<57x37x55xf16>) {
+ %0 = spirv.Constant dense<0> : !spirv.arm.tensor<1xi8>
+ // CHECK: {{%.*}} = spirv.Tosa.Mul %arg0, %arg1, {{%.*}} : !spirv.arm.tensor<57x1x55xf16>, !spirv.arm.tensor<57x37x55xf16>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<57x37x55xf16>
+ %1 = spirv.Tosa.Mul %arg0, %arg1, %0 : !spirv.arm.tensor<57x1x55xf16>, !spirv.arm.tensor<57x37x55xf16>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<57x37x55xf16>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<57x37x55xf16>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<57x37x55xf16>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Pow - PRO-FP
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @pow_fp(%arg0: !spirv.arm.tensor<1x52x53xf16>, %arg1: !spirv.arm.tensor<44x52x53xf16>) -> (!spirv.arm.tensor<44x52x53xf16>) {
+ // CHECK: {{%.*}} = spirv.Tosa.Pow %arg0, %arg1 : !spirv.arm.tensor<1x52x53xf16>, !spirv.arm.tensor<44x52x53xf16> -> !spirv.arm.tensor<44x52x53xf16>
+ %0 = spirv.Tosa.Pow %arg0, %arg1 : !spirv.arm.tensor<1x52x53xf16>, !spirv.arm.tensor<44x52x53xf16> -> !spirv.arm.tensor<44x52x53xf16>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<44x52x53xf16>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<44x52x53xf16>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Sub - PRO-INT
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @sub_int(%arg0: !spirv.arm.tensor<6x10x6x6xi32>, %arg1: !spirv.arm.tensor<1x10x6x6xi32>) -> (!spirv.arm.tensor<6x10x6x6xi32>) {
+ // CHECK: {{%.*}} = spirv.Tosa.Sub %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi32>, !spirv.arm.tensor<1x10x6x6xi32> -> !spirv.arm.tensor<6x10x6x6xi32>
+ %0 = spirv.Tosa.Sub %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi32>, !spirv.arm.tensor<1x10x6x6xi32> -> !spirv.arm.tensor<6x10x6x6xi32>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<6x10x6x6xi32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xi32>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Sub - PRO-FP
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @sub_fp(%arg0: !spirv.arm.tensor<1x10x13x12xf16>, %arg1: !spirv.arm.tensor<6x10x13x12xf16>) -> (!spirv.arm.tensor<6x10x13x12xf16>) {
+ // CHECK: {{%.*}} = spirv.Tosa.Sub %arg0, %arg1 : !spirv.arm.tensor<1x10x13x12xf16>, !spirv.arm.tensor<6x10x13x12xf16> -> !spirv.arm.tensor<6x10x13x12xf16>
+ %0 = spirv.Tosa.Sub %arg0, %arg1 : !spirv.arm.tensor<1x10x13x12xf16>, !spirv.arm.tensor<6x10x13x12xf16> -> !spirv.arm.tensor<6x10x13x12xf16>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<6x10x13x12xf16>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x13x12xf16>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Table - PRO-INT
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @table_int(%arg0: !spirv.arm.tensor<3x2x15x7xi8>) -> (!spirv.arm.tensor<3x2x15x7xi8>) {
+ %0 = spirv.ARM.GraphConstant {graph_constant_id = 0 : i32} : !spirv.arm.tensor<256xi8>
+ // CHECK: {{%.*}} = spirv.Tosa.Table %arg0, {{%.*}} : !spirv.arm.tensor<3x2x15x7xi8>, !spirv.arm.tensor<256xi8> -> !spirv.arm.tensor<3x2x15x7xi8>
+ %1 = spirv.Tosa.Table %arg0, %0 : !spirv.arm.tensor<3x2x15x7xi8>, !spirv.arm.tensor<256xi8> -> !spirv.arm.tensor<3x2x15x7xi8>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<3x2x15x7xi8>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<3x2x15x7xi8>
+}
diff --git a/mlir/test/Target/SPIRV/tosa-ops.mlir b/mlir/test/Target/SPIRV/tosa-ops.mlir
index bbff6c6b0fa15..723674d0b15ba 100644
--- a/mlir/test/Target/SPIRV/tosa-ops.mlir
+++ b/mlir/test/Target/SPIRV/tosa-ops.mlir
@@ -731,3 +731,205 @@ spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader
spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<11x4x9x12xi1>
}
}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Maximum - PRO-INT
+//===----------------------------------------------------------------------===//
+
+// CHECK: spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Int16, Int64, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]>
+spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Int16, Int64, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]> {
+ spirv.GlobalVariable @maximum_int_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<1x2x65533x1xi32>, UniformConstant>
+ spirv.GlobalVariable @maximum_int_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<1x2x65533x2xi32>, UniformConstant>
+ spirv.GlobalVariable @maximum_int_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<1x2x65533x2xi32>, UniformConstant>
+ spirv.ARM.GraphEntryPoint @maximum_int, @maximum_int_arg_0, @maximum_int_arg_1, @maximum_int_res_0
+ spirv.ARM.Graph @maximum_int(%arg0: !spirv.arm.tensor<1x2x65533x1xi32>, %arg1: !spirv.arm.tensor<1x2x65533x2xi32>) -> (!spirv.arm.tensor<1x2x65533x2xi32>) {
+ // CHECK: {{%.*}} = spirv.Tosa.Maximum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<1x2x65533x1xi32>, !spirv.arm.tensor<1x2x65533x2xi32> -> !spirv.arm.tensor<1x2x65533x2xi32>
+ %1 = spirv.Tosa.Maximum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<1x2x65533x1xi32>, !spirv.arm.tensor<1x2x65533x2xi32> -> !spirv.arm.tensor<1x2x65533x2xi32>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<1x2x65533x2xi32>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<1x2x65533x2xi32>
+ }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Maximum - PRO-FP
+//===----------------------------------------------------------------------===//
+
+// CHECK: spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Int16, Int64, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]>
+spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Int16, Int64, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]> {
+ spirv.GlobalVariable @maximum_fp_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<1x12x14x7xf16>, UniformConstant>
+ spirv.GlobalVariable @maximum_fp_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<11x12x14x7xf16>, UniformConstant>
+ spirv.GlobalVariable @maximum_fp_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<11x12x14x7xf16>, UniformConstant>
+ spirv.ARM.GraphEntryPoint @maximum_fp, @maximum_fp_arg_0, @maximum_fp_arg_1, @maximum_fp_res_0
+ spirv.ARM.Graph @maximum_fp(%arg0: !spirv.arm.tensor<1x12x14x7xf16>, %arg1: !spirv.arm.tensor<11x12x14x7xf16>) -> (!spirv.arm.tensor<11x12x14x7xf16>) {
+ // CHECK: {{%.*}} = spirv.Tosa.Maximum nan_mode = <Ignore>, %arg0, %arg1 : !spirv.arm.tensor<1x12x14x7xf16>, !spirv.arm.tensor<11x12x14x7xf16> -> !spirv.arm.tensor<11x12x14x7xf16>
+ %1 = spirv.Tosa.Maximum nan_mode = <Ignore>, %arg0, %arg1 : !spirv.arm.tensor<1x12x14x7xf16>, !spirv.arm.tensor<11x12x14x7xf16> -> !spirv.arm.tensor<11x12x14x7xf16>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<11x12x14x7xf16>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<11x12x14x7xf16>
+ }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Minimum - PRO-INT
+//===----------------------------------------------------------------------===//
+
+// CHECK: spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Int16, Int64, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]>
+spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Int16, Int64, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]> {
+ spirv.GlobalVariable @minimum_int_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<15x2x10x11xi32>, UniformConstant>
+ spirv.GlobalVariable @minimum_int_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<15x1x10x11xi32>, UniformConstant>
+ spirv.GlobalVariable @minimum_int_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<15x2x10x11xi32>, UniformConstant>
+ spirv.ARM.GraphEntryPoint @minimum_int, @minimum_int_arg_0, @minimum_int_arg_1, @minimum_int_res_0
+ spirv.ARM.Graph @minimum_int(%arg0: !spirv.arm.tensor<15x2x10x11xi32>, %arg1: !spirv.arm.tensor<15x1x10x11xi32>) -> (!spirv.arm.tensor<15x2x10x11xi32>) {
+ // CHECK: {{%.*}} = spirv.Tosa.Minimum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<15x2x10x11xi32>, !spirv.arm.tensor<15x1x10x11xi32> -> !spirv.arm.tensor<15x2x10x11xi32>
+ %1 = spirv.Tosa.Minimum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<15x2x10x11xi32>, !spirv.arm.tensor<15x1x10x11xi32> -> !spirv.arm.tensor<15x2x10x11xi32>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<15x2x10x11xi32>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<15x2x10x11xi32>
+ }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Minimum - PRO-FP
+//===----------------------------------------------------------------------===//
+
+// CHECK: spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Int16, Int64, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]>
+spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Int16, Int64, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]> {
+ spirv.GlobalVariable @minimum_fp_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<1x65531x2x1xf32>, UniformConstant>
+ spirv.GlobalVariable @minimum_fp_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<1x1x2x1xf32>, UniformConstant>
+ spirv.GlobalVariable @minimum_fp_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<1x65531x2x1xf32>, UniformConstant>
+ spirv.ARM.GraphEntryPoint @minimum_fp, @minimum_fp_arg_0, @minimum_fp_arg_1, @minimum_fp_res_0
+ spirv.ARM.Graph @minimum_fp(%arg0: !spirv.arm.tensor<1x65531x2x1xf32>, %arg1: !spirv.arm.tensor<1x1x2x1xf32>) -> (!spirv.arm.tensor<1x65531x2x1xf32>) {
+ // CHECK: {{%.*}} = spirv.Tosa.Minimum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<1x65531x2x1xf32>, !spirv.arm.tensor<1x1x2x1xf32> -> !spirv.arm.tensor<1x65531x2x1xf32>
+ %1 = spirv.Tosa.Minimum nan_mode = <Propagate>, %arg0, %arg1 : !spirv.arm.tensor<1x65531x2x1xf32>, !spirv.arm.tensor<1x1x2x1xf32> -> !spirv.arm.tensor<1x65531x2x1xf32>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<1x65531x2x1xf32>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<1x65531x2x1xf32>
+ }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Mul - PRO-INT
+//===----------------------------------------------------------------------===//
+
+// CHECK: spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Int16, Int64, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]>
+spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Int16, Int64, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]> {
+ spirv.GlobalVariable @mul_int_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<34x21x39xi32>, UniformConstant>
+ spirv.GlobalVariable @mul_int_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<34x21x1xi32>, UniformConstant>
+ spirv.GlobalVariable @mul_int_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<34x21x39xi32>, UniformConstant>
+ spirv.ARM.GraphEntryPoint @mul_int, @mul_int_arg_0, @mul_int_arg_1, @mul_int_res_0
+ spirv.ARM.Graph @mul_int(%arg0: !spirv.arm.tensor<34x21x39xi32>, %arg1: !spirv.arm.tensor<34x21x1xi32>) -> (!spirv.arm.tensor<34x21x39xi32>) {
+ %0 = spirv.Constant dense<31> : !spirv.arm.tensor<1xi8>
+ // CHECK: {{%.*}} = spirv.Tosa.Mul %arg0, %arg1, {{%.*}} : !spirv.arm.tensor<34x21x39xi32>, !spirv.arm.tensor<34x21x1xi32>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<34x21x39xi32>
+ %1 = spirv.Tosa.Mul %arg0, %arg1, %0 : !spirv.arm.tensor<34x21x39xi32>, !spirv.arm.tensor<34x21x1xi32>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<34x21x39xi32>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<34x21x39xi32>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<34x21x39xi32>
+ }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Mul - PRO-FP
+//===----------------------------------------------------------------------===//
+
+// CHECK: spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Int16, Int64, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]>
+spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Int16, Int64, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]> {
+ spirv.GlobalVariable @mul_fp_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<57x1x55xf16>, UniformConstant>
+ spirv.GlobalVariable @mul_fp_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<57x37x55xf16>, UniformConstant>
+ spirv.GlobalVariable @mul_fp_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<57x37x55xf16>, UniformConstant>
+ spirv.ARM.GraphEntryPoint @mul_fp, @mul_fp_arg_0, @mul_fp_arg_1, @mul_fp_res_0
+ spirv.ARM.Graph @mul_fp(%arg0: !spirv.arm.tensor<57x1x55xf16>, %arg1: !spirv.arm.tensor<57x37x55xf16>) -> (!spirv.arm.tensor<57x37x55xf16>) {
+ %0 = spirv.Constant dense<0> : !spirv.arm.tensor<1xi8>
+ // CHECK: {{%.*}} = spirv.Tosa.Mul %arg0, %arg1, {{%.*}} : !spirv.arm.tensor<57x1x55xf16>, !spirv.arm.tensor<57x37x55xf16>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<57x37x55xf16>
+ %1 = spirv.Tosa.Mul %arg0, %arg1, %0 : !spirv.arm.tensor<57x1x55xf16>, !spirv.arm.tensor<57x37x55xf16>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<57x37x55xf16>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<57x37x55xf16>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<57x37x55xf16>
+ }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Pow - PRO-FP
+//===----------------------------------------------------------------------===//
+
+// CHECK: spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Int16, Int64, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]>
+spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Int16, Int64, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]> {
+ spirv.GlobalVariable @pow_fp_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<1x52x53xf16>, UniformConstant>
+ spirv.GlobalVariable @pow_fp_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<44x52x53xf16>, UniformConstant>
+ spirv.GlobalVariable @pow_fp_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<44x52x53xf16>, UniformConstant>
+ spirv.ARM.GraphEntryPoint @pow_fp, @pow_fp_arg_0, @pow_fp_arg_1, @pow_fp_res_0
+ spirv.ARM.Graph @pow_fp(%arg0: !spirv.arm.tensor<1x52x53xf16>, %arg1: !spirv.arm.tensor<44x52x53xf16>) -> (!spirv.arm.tensor<44x52x53xf16>) {
+ // CHECK: {{%.*}} = spirv.Tosa.Pow %arg0, %arg1 : !spirv.arm.tensor<1x52x53xf16>, !spirv.arm.tensor<44x52x53xf16> -> !spirv.arm.tensor<44x52x53xf16>
+ %0 = spirv.Tosa.Pow %arg0, %arg1 : !spirv.arm.tensor<1x52x53xf16>, !spirv.arm.tensor<44x52x53xf16> -> !spirv.arm.tensor<44x52x53xf16>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<44x52x53xf16>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<44x52x53xf16>
+ }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Sub - PRO-INT
+//===----------------------------------------------------------------------===//
+
+// CHECK: spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Int16, Int64, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]>
+spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Int16, Int64, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]> {
+ spirv.GlobalVariable @sub_int_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<6x10x6x6xi32>, UniformConstant>
+ spirv.GlobalVariable @sub_int_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<1x10x6x6xi32>, UniformConstant>
+ spirv.GlobalVariable @sub_int_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<6x10x6x6xi32>, UniformConstant>
+ spirv.ARM.GraphEntryPoint @sub_int, @sub_int_arg_0, @sub_int_arg_1, @sub_int_res_0
+ spirv.ARM.Graph @sub_int(%arg0: !spirv.arm.tensor<6x10x6x6xi32>, %arg1: !spirv.arm.tensor<1x10x6x6xi32>) -> (!spirv.arm.tensor<6x10x6x6xi32>) {
+ // CHECK: {{%.*}} = spirv.Tosa.Sub %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi32>, !spirv.arm.tensor<1x10x6x6xi32> -> !spirv.arm.tensor<6x10x6x6xi32>
+ %0 = spirv.Tosa.Sub %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi32>, !spirv.arm.tensor<1x10x6x6xi32> -> !spirv.arm.tensor<6x10x6x6xi32>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<6x10x6x6xi32>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xi32>
+ }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Sub - PRO-FP
+//===----------------------------------------------------------------------===//
+
+// CHECK: spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Int16, Int64, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]>
+spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Int16, Int64, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]> {
+ spirv.GlobalVariable @sub_fp_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<1x10x13x12xf16>, UniformConstant>
+ spirv.GlobalVariable @sub_fp_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<6x10x13x12xf16>, UniformConstant>
+ spirv.GlobalVariable @sub_fp_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<6x10x13x12xf16>, UniformConstant>
+ spirv.ARM.GraphEntryPoint @sub_fp, @sub_fp_arg_0, @sub_fp_arg_1, @sub_fp_res_0
+ spirv.ARM.Graph @sub_fp(%arg0: !spirv.arm.tensor<1x10x13x12xf16>, %arg1: !spirv.arm.tensor<6x10x13x12xf16>) -> (!spirv.arm.tensor<6x10x13x12xf16>) {
+ // CHECK: {{%.*}} = spirv.Tosa.Sub %arg0, %arg1 : !spirv.arm.tensor<1x10x13x12xf16>, !spirv.arm.tensor<6x10x13x12xf16> -> !spirv.arm.tensor<6x10x13x12xf16>
+ %0 = spirv.Tosa.Sub %arg0, %arg1 : !spirv.arm.tensor<1x10x13x12xf16>, !spirv.arm.tensor<6x10x13x12xf16> -> !spirv.arm.tensor<6x10x13x12xf16>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<6x10x13x12xf16>
+ spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x13x12xf16>
+ }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Table - PRO-INT
+//===----------------------------------------------------------------------===//
+
+// CHECK: spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Int16, Int64, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]>
+spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader, Int8, Int16, Int64, Float16, TensorsARM, GraphARM], [SPV_ARM_tensors, SPV_ARM_graph, SPV_KHR_vulkan_memory_model]> {
+ spirv.GlobalVariable @table_int_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<3x2x15x7xi8>, UniformConstant>
+ spirv.GlobalVariable @table_int_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<3x2x15x7xi8>, UniformConstant>
+ spirv.ARM.GraphEntryPoint @table_int, @table_int_arg_0, @table_int_res_0
+ spirv.ARM.Graph @table_int(%arg0: !spirv.arm.tensor<3x2x15x7xi8>) -> (!spirv.arm.tensor<3x2x15x7xi8>) {
+ %0 = spirv.ARM.GraphConstant {graph_constant_id = 0 : i32} : !spirv.arm.tensor<256xi8>
+ // CHECK: {{%.*}} = spirv.Tosa.Table %arg0, {{%.*}} : !spirv.arm.tensor<3x2x15x7xi8>, !spirv.arm.tensor<256xi8> -> !spirv.arm.tensor<3x2x15x7xi8>
+ %1 = spirv.Tosa.Table %arg0, %0 : !spirv.arm.tensor<3x2x15x7xi8>, !spirv.arm.tensor<256xi8> -> !spirv.arm.tensor<3x2x15x7xi8>
+ // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<3x2x15x7xi8>
+ spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<3x2x15x7xi8>
+ }
+}
More information about the Mlir-commits
mailing list