[Mlir-commits] [mlir] [mlir][spirv] Add Element Binary operators to TOSA Ext Inst Set (PR #179627)

Davide Grohmann llvmlistbot at llvm.org
Wed Feb 4 01:03:16 PST 2026


https://github.com/davidegrohmann updated https://github.com/llvm/llvm-project/pull/179627

>From c4573a5532f683f6a0803cf50c3332985b56e339 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 Element Binary operators to TOSA Ext Inst
 Set

This patch introduces the following element binary operators:
* spirv.Tosa.Add
* spirv.Tosa.ArithmeticRightShift
* spirv.Tosa.BitwiseAnd
* spirv.Tosa.BitwiseOr
* spirv.Tosa.BitwiseXor
* spirv.Tosa.IntDiv
* spirv.Tosa.LogicalAnd
* spirv.Tosa.LogicalLeftShift
* spirv.Tosa.LogicalRightShift
* spirv.Tosa.LogicalOr
* spirv.Tosa.LogicalXor
* 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: I477dec54212d4201230ba63753c4138fdcb83915
---
 .../mlir/Dialect/SPIRV/IR/SPIRVTosaOps.td     | 804 ++++++++++++++++++
 .../mlir/Dialect/SPIRV/IR/SPIRVTosaTypes.td   |  11 +
 .../SPIRV/IR/tosa-ops-verification.mlir       |  93 ++
 mlir/test/Dialect/SPIRV/IR/tosa-ops.mlir      | 245 ++++++
 mlir/test/Target/SPIRV/tosa-ops.mlir          | 442 ++++++++++
 5 files changed, 1595 insertions(+)

diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaOps.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaOps.td
index 61e8ea2c9ebc8..d81985fb9a40f 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaOps.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaOps.td
@@ -863,4 +863,808 @@ def SPIRV_TosaTanhOp : SPIRV_TosaOpWithResult<"Tanh", 13, [Pure,
 }
 
 
+def SPIRV_TosaAddOp : SPIRV_TosaOpWithResult<"Add", 14, [Pure,
+  AllElementTypesMatch<["input1", "input2", "output"]>,
+  AllRanksMatch<["input1", "input2"]>]> {
+  let summary = "Addition operator.";
+
+  let description = [{
+    Elementwise Addition of input1 and input2. Axis of size 1 will be broadcast,
+    as necessary. Rank of input tensors must match.
+
+    References:
+      * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_add
+      * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_add
+
+    #### Example:
+    ```mlir
+    %0 = spirv.Tosa.Add %arg0, %arg1 : !spirv.arm.tensor<4x7x3x10xi32>, !spirv.arm.tensor<4x7x3x1xi32> -> !spirv.arm.tensor<4x7x3x10xi32>
+    %0 = spirv.Tosa.Add %arg0, %arg1 : !spirv.arm.tensor<26x37x18xf16>, !spirv.arm.tensor<1x37x18xf16> -> !spirv.arm.tensor<26x37x18xf16>
+    ```
+  }];
+
+  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)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getInput1Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput1().getType());
+    }
+    ::mlir::spirv::TensorArmType getInput2Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput2().getType());
+    }
+  }];
+}
+
+
+def SPIRV_TosaArithmeticRightShiftOp : SPIRV_TosaOpWithResult<"ArithmeticRightShift", 15, [Pure,
+  AllElementTypesMatch<["input1", "input2", "output"]>,
+  AllRanksMatch<["input1", "input2"]>]> {
+  let summary = "Arithmetic Right Shift.";
+
+  let description = [{
+    Elementwise Arithmetic Right Shift of input1 by the amount specified in
+    input2. Axis of size 1 will be broadcast, as necessary. Rank of input tensors
+    must match.
+
+    References:
+      * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_arithmetic_right_shift
+      * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_arithmetic_right_shift
+
+    #### Example:
+    ```mlir
+    %1 = spirv.Tosa.ArithmeticRightShift round = true, %arg0, %arg1 : !spirv.arm.tensor<1x47x22xi16>, !spirv.arm.tensor<49x47x22xi16> -> !spirv.arm.tensor<49x47x22xi16>
+    ```
+  }];
+
+  let arguments = (ins
+    SPIRV_BoolConstAttr: $round,
+    SPIRV_TosaInteger_TensorArm: $input1,
+    SPIRV_TosaInteger_TensorArm: $input2
+  );
+
+  let results = (outs
+    SPIRV_TosaInteger_TensorArm: $output
+  );
+
+  let assemblyFormat = [{
+    `round` `=` $round `,`
+    $input1 `,`
+    $input2
+    attr-dict `:` type(operands) `->` type(results)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getInput1Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput1().getType());
+    }
+    ::mlir::spirv::TensorArmType getInput2Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput2().getType());
+    }
+  }];
+}
+
+
+def SPIRV_TosaBitwiseAndOp : SPIRV_TosaOpWithResult<"BitwiseAnd", 16, [Pure,
+  AllElementTypesMatch<["input1", "input2", "output"]>,
+  AllRanksMatch<["input1", "input2"]>]> {
+  let summary = "Bitwise AND operator.";
+
+  let description = [{
+    Elementwise Bitwise AND of input1 and input2. Axis of size 1
+    will be broadcast as necessary. Rank of input tensors must match.
+
+    References:
+      * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_bitwise_and
+      * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_bitwise_and
+
+    #### Example:
+    ```mlir
+    %0 = spirv.Tosa.BitwiseAnd %arg0, %arg1 : !spirv.arm.tensor<4x1x7x12xi16>, !spirv.arm.tensor<4x13x7x12xi16> -> !spirv.arm.tensor<4x13x7x12xi16>
+    ```
+  }];
+
+  let arguments = (ins
+    SPIRV_TosaInteger_TensorArm: $input1,
+    SPIRV_TosaInteger_TensorArm: $input2
+  );
+
+  let results = (outs
+    SPIRV_TosaInteger_TensorArm: $output
+  );
+
+  let assemblyFormat = [{
+    $input1 `,`
+    $input2
+    attr-dict `:` type(operands) `->` type(results)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getInput1Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput1().getType());
+    }
+    ::mlir::spirv::TensorArmType getInput2Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput2().getType());
+    }
+  }];
+}
+
+
+def SPIRV_TosaBitwiseOrOp : SPIRV_TosaOpWithResult<"BitwiseOr", 17, [Pure,
+  AllElementTypesMatch<["input1", "input2", "output"]>,
+  AllRanksMatch<["input1", "input2"]>]> {
+  let summary = "Bitwise OR operator.";
+
+  let description = [{
+    Elementwise Bitwise OR of input1 and input2. Axis of size 1 will be
+    broadcast as necessary. Rank of input tensors must match.
+
+    References:
+      * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_bitwise_or
+      * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_bitwise_or
+
+    #### Example:
+    ```mlir
+    %0 = spirv.Tosa.BitwiseOr %arg0, %arg1 : !spirv.arm.tensor<11x30x23xi32>, !spirv.arm.tensor<1x30x23xi32> -> !spirv.arm.tensor<11x30x23xi32>
+    ```
+  }];
+
+  let arguments = (ins
+    SPIRV_TosaInteger_TensorArm: $input1,
+    SPIRV_TosaInteger_TensorArm: $input2
+  );
+
+  let results = (outs
+    SPIRV_TosaInteger_TensorArm: $output
+  );
+
+  let assemblyFormat = [{
+    $input1 `,`
+    $input2
+    attr-dict `:` type(operands) `->` type(results)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getInput1Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput1().getType());
+    }
+    ::mlir::spirv::TensorArmType getInput2Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput2().getType());
+    }
+  }];
+}
+
+
+def SPIRV_TosaBitwiseXorOp : SPIRV_TosaOpWithResult<"BitwiseXor", 18, [Pure,
+  AllElementTypesMatch<["input1", "input2", "output"]>,
+  AllRanksMatch<["input1", "input2"]>]> {
+  let summary = "Bitwise XOR operator.";
+
+  let description = [{
+    Elementwise Bitwise XOR of input1 and input2. Axis of size 1 will be
+    broadcast as necessary. Rank of input tensors must match.
+
+    References:
+      * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_bitwise_xor
+      * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_bitwise_xor
+
+    #### Example:
+    ```mlir
+    %0 = spirv.Tosa.BitwiseXor %arg0, %arg1 : !spirv.arm.tensor<4x8x13x9xi16>, !spirv.arm.tensor<4x8x1x9xi16> -> !spirv.arm.tensor<4x8x13x9xi16>
+    ```
+  }];
+
+  let arguments = (ins
+    SPIRV_TosaInteger_TensorArm: $input1,
+    SPIRV_TosaInteger_TensorArm: $input2
+  );
+
+  let results = (outs
+    SPIRV_TosaInteger_TensorArm: $output
+  );
+
+  let assemblyFormat = [{
+    $input1 `,`
+    $input2
+    attr-dict `:` type(operands) `->` type(results)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getInput1Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput1().getType());
+    }
+    ::mlir::spirv::TensorArmType getInput2Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput2().getType());
+    }
+  }];
+}
+
+
+def SPIRV_TosaIntDivOp : SPIRV_TosaOpWithResult<"IntDiv", 19, [Pure]> {
+  let summary = "Integer Divide operator.";
+
+  let description = [{
+    Elementwise Integer Divide of input1 by input2. Axis of size 1 will be
+    broadcast as necessary. Rank of input tensors must match.
+
+    The result of the divide is truncated towards zero. Expected use is for
+    operations on non-scaled integers. Floating point divide should use
+    `spirv.Tosa.Reciprocal` and `spirv.Tosa.Mul`. Quantized integer divide
+    should use `spirv.Tosa.Table`(for $ 1/x $) and `spirv.Tosa.Mul`.
+
+    References:
+      * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_intdiv
+      * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_intdiv
+
+    #### Example:
+    ```mlir
+    %0 = spirv.Tosa.IntDiv %arg0, %arg1 : !spirv.arm.tensor<1x65533x1xi32>, !spirv.arm.tensor<2x65533x1xi32> -> !spirv.arm.tensor<2x65533x1xi32>
+    ```
+  }];
+
+  let arguments = (ins
+    SPIRV_Int32_TensorArm: $input1,
+    SPIRV_Int32_TensorArm: $input2
+  );
+
+  let results = (outs
+    SPIRV_Int32_TensorArm: $output
+  );
+
+  let assemblyFormat = [{
+    $input1 `,`
+    $input2
+    attr-dict `:` type(operands) `->` type(results)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getInput1Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput1().getType());
+    }
+    ::mlir::spirv::TensorArmType getInput2Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput2().getType());
+    }
+  }];
+}
+
+
+def SPIRV_TosaLogicalAndOp : SPIRV_TosaOpWithResult<"LogicalAnd", 20, [Pure]> {
+  let summary = "Logical AND operator.";
+
+  let description = [{
+    Elementwise Logical AND of input1 and input2. Axis of size 1 will be
+    broadcast, as necessary. Rank of input tensors must match.
+
+    References:
+      * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_logical_and
+      * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_logical_and
+
+    #### Example:
+    ```mlir
+    %0 = spirv.Tosa.LogicalAnd %arg0, %arg1 : !spirv.arm.tensor<2x1x7x11xi1>, !spirv.arm.tensor<2x4x7x11xi1> -> !spirv.arm.tensor<2x4x7x11xi1>
+    ```
+  }];
+
+  let arguments = (ins
+    SPIRV_Bool_TensorArm: $input1,
+    SPIRV_Bool_TensorArm: $input2
+  );
+
+  let results = (outs
+    SPIRV_Bool_TensorArm: $output
+  );
+
+  let assemblyFormat = [{
+    $input1 `,`
+    $input2
+    attr-dict `:` type(operands) `->` type(results)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getInput1Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput1().getType());
+    }
+    ::mlir::spirv::TensorArmType getInput2Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput2().getType());
+    }
+  }];
+}
+
+
+def SPIRV_TosaLogicalLeftShiftOp : SPIRV_TosaOpWithResult<"LogicalLeftShift", 21, [Pure,
+  AllElementTypesMatch<["input1", "input2", "output"]>,
+  AllRanksMatch<["input1", "input2"]>]> {
+  let summary = "Logical Left Shift operator.";
+
+  let description = [{
+    Elementwise Logical Left Shift of input1 by the amount specified in input2.
+    Axis of size 1 will be broadcast, as necessary.
+    Rank of input tensors must match.
+
+    References:
+      * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_logical_left_shift
+      * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_logical_left_shift
+
+    #### Example:
+    ```mlir
+    %0 = spirv.Tosa.LogicalLeftShift %arg0, %arg1 : !spirv.arm.tensor<7x1x11x4xi8>, !spirv.arm.tensor<7x8x11x4xi8> -> !spirv.arm.tensor<7x8x11x4xi8>
+    ```
+  }];
+
+  let arguments = (ins
+    SPIRV_TosaInteger_TensorArm: $input1,
+    SPIRV_TosaInteger_TensorArm: $input2
+  );
+
+  let results = (outs
+    SPIRV_TosaInteger_TensorArm: $output
+  );
+
+  let assemblyFormat = [{
+    $input1 `,`
+    $input2
+    attr-dict `:` type(operands) `->` type(results)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getInput1Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput1().getType());
+    }
+    ::mlir::spirv::TensorArmType getInput2Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput2().getType());
+    }
+  }];
+}
+
+
+def SPIRV_TosaLogicalRightShiftOp : SPIRV_TosaOpWithResult<"LogicalRightShift", 22, [Pure,
+  AllElementTypesMatch<["input1", "input2", "output"]>,
+  AllRanksMatch<["input1", "input2"]>]> {
+  let summary = "Logical Right Shift operator.";
+
+  let description = [{
+    Elementwise Logical Right Shift of input1 by the amount specified in input2.
+    Axis of size 1 will be broadcast, as necessary. Rank of input tensors must
+    match.
+
+    References:
+      * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_logical_right_shift
+      * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_logical_right_shift
+
+    #### Example:
+    ```mlir
+    %0 = spirv.Tosa.LogicalRightShift %arg0, %arg1 : !spirv.arm.tensor<6x13x1x19xi8>, !spirv.arm.tensor<6x13x6x19xi8> -> !spirv.arm.tensor<6x13x6x19xi8>
+    ```
+  }];
+
+  let arguments = (ins
+    SPIRV_TosaInteger_TensorArm: $input1,
+    SPIRV_TosaInteger_TensorArm: $input2
+  );
+
+  let results = (outs
+    SPIRV_TosaInteger_TensorArm: $output
+  );
+
+  let assemblyFormat = [{
+    $input1 `,`
+    $input2
+    attr-dict `:` type(operands) `->` type(results)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getInput1Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput1().getType());
+    }
+    ::mlir::spirv::TensorArmType getInput2Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput2().getType());
+    }
+  }];
+}
+
+
+def SPIRV_TosaLogicalOrOp : SPIRV_TosaOpWithResult<"LogicalOr", 23, [Pure]> {
+  let summary = "Logical OR operator.";
+
+  let description = [{
+    Elementwise logical OR of input1 and input2. Axis of size 1 will be
+    broadcast as necessary. Rank of input tensors must match.
+
+    References:
+      * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_logical_or
+      * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_logical_or
+
+    #### Example:
+    ```mlir
+    %0 = spirv.Tosa.LogicalOr %arg0, %arg1 : !spirv.arm.tensor<3x6x12x5xi1>, !spirv.arm.tensor<3x6x1x5xi1> -> !spirv.arm.tensor<3x6x12x5xi1>
+    ```
+  }];
+
+  let arguments = (ins
+    SPIRV_Bool_TensorArm: $input1,
+    SPIRV_Bool_TensorArm: $input2
+  );
+
+  let results = (outs
+    SPIRV_Bool_TensorArm: $output
+  );
+
+  let assemblyFormat = [{
+    $input1 `,`
+    $input2
+    attr-dict `:` type(operands) `->` type(results)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getInput1Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput1().getType());
+    }
+    ::mlir::spirv::TensorArmType getInput2Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput2().getType());
+    }
+  }];
+}
+
+
+def SPIRV_TosaLogicalXorOp : SPIRV_TosaOpWithResult<"LogicalXor", 24, [Pure]> {
+  let summary = "Logical XOR operator.";
+
+  let description = [{
+    Elementwise logical XOR of input1 and input2. Axis of size 1 will be
+    broadcast as necessary. Rank of input tensors must match.
+
+    References:
+      * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_logical_xor
+      * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_logical_xor
+
+    #### Example:
+    ```mlir
+    %0 = spirv.Tosa.LogicalXor %arg0, %arg1 : !spirv.arm.tensor<11x4x9x12xi1>, !spirv.arm.tensor<11x4x9x1xi1> -> !spirv.arm.tensor<11x4x9x12xi1>
+    ```
+  }];
+
+  let arguments = (ins
+    SPIRV_Bool_TensorArm: $input1,
+    SPIRV_Bool_TensorArm: $input2
+  );
+
+  let results = (outs
+    SPIRV_Bool_TensorArm: $output
+  );
+
+  let assemblyFormat = [{
+    $input1 `,`
+    $input2
+    attr-dict `:` type(operands) `->` type(results)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getInput1Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput1().getType());
+    }
+    ::mlir::spirv::TensorArmType getInput2Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput2().getType());
+    }
+  }];
+}
+
+
+def SPIRV_TosaMaximumOp : SPIRV_TosaOpWithResult<"Maximum", 25, [Pure,
+  AllElementTypesMatch<["input1", "input2", "output"]>,
+  AllRanksMatch<["input1", "input2"]>,
+  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.
+
+    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)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getInput1Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput1().getType());
+    }
+    ::mlir::spirv::TensorArmType getInput2Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput2().getType());
+    }
+  }];
+}
+
+
+def SPIRV_TosaMinimumOp : SPIRV_TosaOpWithResult<"Minimum", 26, [Pure,
+  AllElementTypesMatch<["input1", "input2", "output"]>,
+  AllRanksMatch<["input1", "input2"]>,
+  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.
+
+    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)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getInput1Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput1().getType());
+    }
+    ::mlir::spirv::TensorArmType getInput2Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput2().getType());
+    }
+  }];
+}
+
+
+def SPIRV_TosaMulOp : SPIRV_TosaOpWithResult<"Mul", 27, [Pure,
+  AllElementTypesMatch<["input1", "input2"]>,
+  AllRanksMatch<["input1", "input2"]>,
+  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.
+
+    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)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getInput1Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput1().getType());
+    }
+    ::mlir::spirv::TensorArmType getInput2Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput2().getType());
+    }
+  }];
+}
+
+
+def SPIRV_TosaPowOp : SPIRV_TosaOpWithResult<"Pow", 28, [Pure,
+  AllElementTypesMatch<["input1", "input2", "output"]>,
+  AllRanksMatch<["input1", "input2"]>]> {
+  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.
+
+    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)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getInput1Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput1().getType());
+    }
+    ::mlir::spirv::TensorArmType getInput2Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput2().getType());
+    }
+  }];
+}
+
+
+def SPIRV_TosaSubOp : SPIRV_TosaOpWithResult<"Sub", 29, [Pure,
+  AllElementTypesMatch<["input1", "input2", "output"]>,
+  AllRanksMatch<["input1", "input2"]>,
+  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.
+
+    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)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getInput1Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput1().getType());
+    }
+    ::mlir::spirv::TensorArmType getInput2Type() {
+      return cast<::mlir::spirv::TensorArmType>(getInput2().getType());
+    }
+  }];
+}
+
+
+def SPIRV_TosaTableOp : SPIRV_TosaOpWithResult<"Table", 30, [Pure,
+  AllElementTypesMatch<["input1", "table"]>,
+  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]. 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 5fe3bc53618f4..ff3d23f77b380 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaTypes.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaTypes.td
@@ -39,13 +39,17 @@ 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]>;
 def SPIRV_TosaNumerical_TensorArm5D : TensorArmRankOf<[SPIRV_TosaNumerical], [5]>;
 
 def SPIRV_TosaNumerical_TensorArm : TensorArmRankOf<[SPIRV_TosaNumerical], [1, 2, 3, 4, 5, 6]>;
+def SPIRV_TosaInteger_TensorArm : TensorArmRankOf<[SPIRV_TosaInteger], [1, 2, 3, 4, 5, 6]>;
 def SPIRV_TosaFloat_TensorArm : TensorArmRankOf<[SPIRV_TosaFloat], [1, 2, 3, 4, 5, 6]>;
+def SPIRV_Bool_TensorArm : TensorArmRankOf<[SPIRV_Bool], [1, 2, 3, 4, 5, 6]>;
+def SPIRV_Int32_TensorArm : TensorArmRankOf<[SPIRV_Int32], [1, 2, 3, 4, 5, 6]>;
 def SPIRV_Int32_TensorArmUpTo5D : TensorArmRankOf<[SPIRV_Int32], [1, 2, 3, 4, 5]>;
 
 class Is1DTensorArmOfLength<list<int> allowedLengths> :
@@ -67,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
@@ -114,5 +120,10 @@ class TypeImpliesAccType<string input, Type type, list<string> allowedAccTypes>:
   PredOpTrait<"acc_type must be one in [" # !interleave(allowedAccTypes, ",") # "] when type has value " # type.summary,
   Implies<ElementTypeIsPred<input, type>, [AccTypeIn<allowedAccTypes>]>>;
 
+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 dd18a3a2ae788..9d6ae12e0ec3b 100644
--- a/mlir/test/Dialect/SPIRV/IR/tosa-ops-verification.mlir
+++ b/mlir/test/Dialect/SPIRV/IR/tosa-ops-verification.mlir
@@ -431,3 +431,96 @@ spirv.ARM.Graph @clamp_max_val_different_element_type_wrt_input_output(%arg0: !s
   %3 = spirv.Tosa.Clamp min_val = -102 : i8, max_val = -100 : i16, nan_mode = <Propagate>, %arg0 : !spirv.arm.tensor<27x44x55xi8> -> !spirv.arm.tensor<27x44x55xi8>
   spirv.ARM.GraphOutputs %3 : !spirv.arm.tensor<27x44x55xi8>
 }
+
+//===----------------------------------------------------------------------===//
+// 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} 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<6x10x6x6xi16>, %arg1: !spirv.arm.tensor<1x10x6x6xi32>) -> (!spirv.arm.tensor<6x10x6x6xi32>) {
+  // expected-error @+1 {{op failed to verify that all of {input1, input2, output} have same element type}}
+  %0 = spirv.Tosa.Sub %arg0, %arg1 : !spirv.arm.tensor<6x10x6x6xi16>, !spirv.arm.tensor<1x10x6x6xi32> -> !spirv.arm.tensor<6x10x6x6xi32>
+  spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xi32>
+}
+
+spirv.ARM.Graph @sub_element_type_must_be_i32_for_integers(%arg0: !spirv.arm.tensor<6x10x6x6xi8>, %arg1: !spirv.arm.tensor<1x10x6x6xi8>) -> (!spirv.arm.tensor<6x10x6x6xi8>) {
+  // 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<1x10x6x6xi8> -> !spirv.arm.tensor<6x10x6x6xi8>
+  spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x10x6x6xi8>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Mul
+//===----------------------------------------------------------------------===//
+
+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.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_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 {{p 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 a9f7bc2b8ef7d..6977c6510c390 100644
--- a/mlir/test/Dialect/SPIRV/IR/tosa-ops.mlir
+++ b/mlir/test/Dialect/SPIRV/IR/tosa-ops.mlir
@@ -284,3 +284,248 @@ spirv.ARM.Graph @tanh_fp(%arg0: !spirv.arm.tensor<46x50x36xf16>) -> (!spirv.arm.
   // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<46x50x36xf16>
   spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<46x50x36xf16>
 }
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Add - PRO-INT
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @add_int(%arg0: !spirv.arm.tensor<4x7x3x10xi32>, %arg1: !spirv.arm.tensor<4x7x3x1xi32>) -> (!spirv.arm.tensor<4x7x3x10xi32>) {
+  // CHECK: {{%.*}} = spirv.Tosa.Add %arg0, %arg1 : !spirv.arm.tensor<4x7x3x10xi32>, !spirv.arm.tensor<4x7x3x1xi32> -> !spirv.arm.tensor<4x7x3x10xi32>
+  %0 = spirv.Tosa.Add %arg0, %arg1 : !spirv.arm.tensor<4x7x3x10xi32>, !spirv.arm.tensor<4x7x3x1xi32> -> !spirv.arm.tensor<4x7x3x10xi32>
+  // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<4x7x3x10xi32>
+  spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<4x7x3x10xi32>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Add - PRO-FP
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @add_fp(%arg0: !spirv.arm.tensor<26x37x18xf16>, %arg1: !spirv.arm.tensor<1x37x18xf16>) -> (!spirv.arm.tensor<26x37x18xf16>) {
+  // CHECK: {{%.*}} = spirv.Tosa.Add %arg0, %arg1 : !spirv.arm.tensor<26x37x18xf16>, !spirv.arm.tensor<1x37x18xf16> -> !spirv.arm.tensor<26x37x18xf16>
+  %0 = spirv.Tosa.Add %arg0, %arg1 : !spirv.arm.tensor<26x37x18xf16>, !spirv.arm.tensor<1x37x18xf16> -> !spirv.arm.tensor<26x37x18xf16>
+  // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<26x37x18xf16>
+  spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<26x37x18xf16>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.ArithmeticRightShift - PRO-INT
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @arithmeticrightshift_int(%arg0: !spirv.arm.tensor<1x47x22xi16>, %arg1: !spirv.arm.tensor<49x47x22xi16>) -> (!spirv.arm.tensor<49x47x22xi16>) {
+  // CHECK: {{%.*}} = spirv.Tosa.ArithmeticRightShift round = true, %arg0, %arg1 : !spirv.arm.tensor<1x47x22xi16>, !spirv.arm.tensor<49x47x22xi16> -> !spirv.arm.tensor<49x47x22xi16>
+  %1 = spirv.Tosa.ArithmeticRightShift round = true, %arg0, %arg1 : !spirv.arm.tensor<1x47x22xi16>, !spirv.arm.tensor<49x47x22xi16> -> !spirv.arm.tensor<49x47x22xi16>
+  // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<49x47x22xi16>
+  spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<49x47x22xi16>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.BitwiseAnd - PRO-INT
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @bitwiseand_int(%arg0: !spirv.arm.tensor<4x1x7x12xi16>, %arg1: !spirv.arm.tensor<4x13x7x12xi16>) -> (!spirv.arm.tensor<4x13x7x12xi16>) {
+  // CHECK: {{%.*}} = spirv.Tosa.BitwiseAnd %arg0, %arg1 : !spirv.arm.tensor<4x1x7x12xi16>, !spirv.arm.tensor<4x13x7x12xi16> -> !spirv.arm.tensor<4x13x7x12xi16>
+  %0 = spirv.Tosa.BitwiseAnd %arg0, %arg1 : !spirv.arm.tensor<4x1x7x12xi16>, !spirv.arm.tensor<4x13x7x12xi16> -> !spirv.arm.tensor<4x13x7x12xi16>
+  // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<4x13x7x12xi16>
+  spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<4x13x7x12xi16>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.BitwiseOr - PRO-INT
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @bitwiseor_int(%arg0: !spirv.arm.tensor<11x30x23xi32>, %arg1: !spirv.arm.tensor<1x30x23xi32>) -> (!spirv.arm.tensor<11x30x23xi32>) {
+  // CHECK: {{%.*}} = spirv.Tosa.BitwiseOr %arg0, %arg1 : !spirv.arm.tensor<11x30x23xi32>, !spirv.arm.tensor<1x30x23xi32> -> !spirv.arm.tensor<11x30x23xi32>
+  %0 = spirv.Tosa.BitwiseOr %arg0, %arg1 : !spirv.arm.tensor<11x30x23xi32>, !spirv.arm.tensor<1x30x23xi32> -> !spirv.arm.tensor<11x30x23xi32>
+  // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<11x30x23xi32>
+  spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<11x30x23xi32>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.BitwiseXor - PRO-INT
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @bitwisexor_int(%arg0: !spirv.arm.tensor<4x8x13x9xi16>, %arg1: !spirv.arm.tensor<4x8x1x9xi16>) -> (!spirv.arm.tensor<4x8x13x9xi16>) {
+  // CHECK: {{%.*}} = spirv.Tosa.BitwiseXor %arg0, %arg1 : !spirv.arm.tensor<4x8x13x9xi16>, !spirv.arm.tensor<4x8x1x9xi16> -> !spirv.arm.tensor<4x8x13x9xi16>
+  %0 = spirv.Tosa.BitwiseXor %arg0, %arg1 : !spirv.arm.tensor<4x8x13x9xi16>, !spirv.arm.tensor<4x8x1x9xi16> -> !spirv.arm.tensor<4x8x13x9xi16>
+  // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<4x8x13x9xi16>
+  spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<4x8x13x9xi16>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.IntDiv - PRO-INT or PRO-FP
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @intdiv_any(%arg0: !spirv.arm.tensor<1x65533x1xi32>, %arg1: !spirv.arm.tensor<2x65533x1xi32>) -> (!spirv.arm.tensor<2x65533x1xi32>) {
+  // CHECK: {{%.*}} = spirv.Tosa.IntDiv %arg0, %arg1 : !spirv.arm.tensor<1x65533x1xi32>, !spirv.arm.tensor<2x65533x1xi32> -> !spirv.arm.tensor<2x65533x1xi32>
+  %0 = spirv.Tosa.IntDiv %arg0, %arg1 : !spirv.arm.tensor<1x65533x1xi32>, !spirv.arm.tensor<2x65533x1xi32> -> !spirv.arm.tensor<2x65533x1xi32>
+  // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<2x65533x1xi32>
+  spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<2x65533x1xi32>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.LogicalAnd - PRO-INT or PRO-FP
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @logicaland_any(%arg0: !spirv.arm.tensor<2x1x7x11xi1>, %arg1: !spirv.arm.tensor<2x4x7x11xi1>) -> (!spirv.arm.tensor<2x4x7x11xi1>) {
+  // CHECK: {{%.*}} = spirv.Tosa.LogicalAnd %arg0, %arg1 : !spirv.arm.tensor<2x1x7x11xi1>, !spirv.arm.tensor<2x4x7x11xi1> -> !spirv.arm.tensor<2x4x7x11xi1>
+  %0 = spirv.Tosa.LogicalAnd %arg0, %arg1 : !spirv.arm.tensor<2x1x7x11xi1>, !spirv.arm.tensor<2x4x7x11xi1> -> !spirv.arm.tensor<2x4x7x11xi1>
+  // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<2x4x7x11xi1>
+  spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<2x4x7x11xi1>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.LogicalLeftShift - PRO-INT or PRO-FP
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @logicalleftshift_any(%arg0: !spirv.arm.tensor<7x1x11x4xi8>, %arg1: !spirv.arm.tensor<7x8x11x4xi8>) -> (!spirv.arm.tensor<7x8x11x4xi8>) {
+  // CHECK: {{%.*}} = spirv.Tosa.LogicalLeftShift %arg0, %arg1 : !spirv.arm.tensor<7x1x11x4xi8>, !spirv.arm.tensor<7x8x11x4xi8> -> !spirv.arm.tensor<7x8x11x4xi8>
+  %0 = spirv.Tosa.LogicalLeftShift %arg0, %arg1 : !spirv.arm.tensor<7x1x11x4xi8>, !spirv.arm.tensor<7x8x11x4xi8> -> !spirv.arm.tensor<7x8x11x4xi8>
+  // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<7x8x11x4xi8>
+  spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<7x8x11x4xi8>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.LogicalRightShift - PRO-INT or PRO-FP
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @logicalrightshift_any(%arg0: !spirv.arm.tensor<6x13x1x19xi8>, %arg1: !spirv.arm.tensor<6x13x6x19xi8>) -> (!spirv.arm.tensor<6x13x6x19xi8>) {
+  // CHECK: {{%.*}} = spirv.Tosa.LogicalRightShift %arg0, %arg1 : !spirv.arm.tensor<6x13x1x19xi8>, !spirv.arm.tensor<6x13x6x19xi8> -> !spirv.arm.tensor<6x13x6x19xi8>
+  %0 = spirv.Tosa.LogicalRightShift %arg0, %arg1 : !spirv.arm.tensor<6x13x1x19xi8>, !spirv.arm.tensor<6x13x6x19xi8> -> !spirv.arm.tensor<6x13x6x19xi8>
+  // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<6x13x6x19xi8>
+  spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x13x6x19xi8>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.LogicalOr - PRO-INT or PRO-FP
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @logicalor_any(%arg0: !spirv.arm.tensor<3x6x12x5xi1>, %arg1: !spirv.arm.tensor<3x6x1x5xi1>) -> (!spirv.arm.tensor<3x6x12x5xi1>) {
+  // CHECK: {{%.*}} = spirv.Tosa.LogicalOr %arg0, %arg1 : !spirv.arm.tensor<3x6x12x5xi1>, !spirv.arm.tensor<3x6x1x5xi1> -> !spirv.arm.tensor<3x6x12x5xi1>
+  %0 = spirv.Tosa.LogicalOr %arg0, %arg1 : !spirv.arm.tensor<3x6x12x5xi1>, !spirv.arm.tensor<3x6x1x5xi1> -> !spirv.arm.tensor<3x6x12x5xi1>
+  // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<3x6x12x5xi1>
+  spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<3x6x12x5xi1>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.LogicalXor - PRO-INT or PRO-FP
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @logicalxor_any(%arg0: !spirv.arm.tensor<11x4x9x12xi1>, %arg1: !spirv.arm.tensor<11x4x9x1xi1>) -> (!spirv.arm.tensor<11x4x9x12xi1>) {
+  // CHECK: {{%.*}} = spirv.Tosa.LogicalXor %arg0, %arg1 : !spirv.arm.tensor<11x4x9x12xi1>, !spirv.arm.tensor<11x4x9x1xi1> -> !spirv.arm.tensor<11x4x9x12xi1>
+  %0 = spirv.Tosa.LogicalXor %arg0, %arg1 : !spirv.arm.tensor<11x4x9x12xi1>, !spirv.arm.tensor<11x4x9x1xi1> -> !spirv.arm.tensor<11x4x9x12xi1>
+  // 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 9f2ff1c31cbc5..723674d0b15ba 100644
--- a/mlir/test/Target/SPIRV/tosa-ops.mlir
+++ b/mlir/test/Target/SPIRV/tosa-ops.mlir
@@ -491,3 +491,445 @@ spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader
     spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<46x50x36xf16>
   }
 }
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Add - 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 @add_int_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<4x7x3x10xi32>, UniformConstant>
+  spirv.GlobalVariable @add_int_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<4x7x3x1xi32>, UniformConstant>
+  spirv.GlobalVariable @add_int_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<4x7x3x10xi32>, UniformConstant>
+  spirv.ARM.GraphEntryPoint @add_int, @add_int_arg_0, @add_int_arg_1, @add_int_res_0
+  spirv.ARM.Graph @add_int(%arg0: !spirv.arm.tensor<4x7x3x10xi32>, %arg1: !spirv.arm.tensor<4x7x3x1xi32>) -> (!spirv.arm.tensor<4x7x3x10xi32>) {
+    // CHECK: {{%.*}} = spirv.Tosa.Add %arg0, %arg1 : !spirv.arm.tensor<4x7x3x10xi32>, !spirv.arm.tensor<4x7x3x1xi32> -> !spirv.arm.tensor<4x7x3x10xi32>
+    %0 = spirv.Tosa.Add %arg0, %arg1 : !spirv.arm.tensor<4x7x3x10xi32>, !spirv.arm.tensor<4x7x3x1xi32> -> !spirv.arm.tensor<4x7x3x10xi32>
+    // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<4x7x3x10xi32>
+    spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<4x7x3x10xi32>
+  }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.Add - 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 @add_fp_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<26x37x18xf16>, UniformConstant>
+  spirv.GlobalVariable @add_fp_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<1x37x18xf16>, UniformConstant>
+  spirv.GlobalVariable @add_fp_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<26x37x18xf16>, UniformConstant>
+  spirv.ARM.GraphEntryPoint @add_fp, @add_fp_arg_0, @add_fp_arg_1, @add_fp_res_0
+  spirv.ARM.Graph @add_fp(%arg0: !spirv.arm.tensor<26x37x18xf16>, %arg1: !spirv.arm.tensor<1x37x18xf16>) -> (!spirv.arm.tensor<26x37x18xf16>) {
+    // CHECK: {{%.*}} = spirv.Tosa.Add %arg0, %arg1 : !spirv.arm.tensor<26x37x18xf16>, !spirv.arm.tensor<1x37x18xf16> -> !spirv.arm.tensor<26x37x18xf16>
+    %0 = spirv.Tosa.Add %arg0, %arg1 : !spirv.arm.tensor<26x37x18xf16>, !spirv.arm.tensor<1x37x18xf16> -> !spirv.arm.tensor<26x37x18xf16>
+    // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<26x37x18xf16>
+    spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<26x37x18xf16>
+  }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.ArithmeticRightShift - 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 @arithmeticrightshift_int_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<1x47x22xi16>, UniformConstant>
+  spirv.GlobalVariable @arithmeticrightshift_int_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<49x47x22xi16>, UniformConstant>
+  spirv.GlobalVariable @arithmeticrightshift_int_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<49x47x22xi16>, UniformConstant>
+  spirv.ARM.GraphEntryPoint @arithmeticrightshift_int, @arithmeticrightshift_int_arg_0, @arithmeticrightshift_int_arg_1, @arithmeticrightshift_int_res_0
+  spirv.ARM.Graph @arithmeticrightshift_int(%arg0: !spirv.arm.tensor<1x47x22xi16>, %arg1: !spirv.arm.tensor<49x47x22xi16>) -> (!spirv.arm.tensor<49x47x22xi16>) {
+    // CHECK: {{%.*}} = spirv.Tosa.ArithmeticRightShift round = true, %arg0, %arg1 : !spirv.arm.tensor<1x47x22xi16>, !spirv.arm.tensor<49x47x22xi16> -> !spirv.arm.tensor<49x47x22xi16>
+    %1 = spirv.Tosa.ArithmeticRightShift round = true, %arg0, %arg1 : !spirv.arm.tensor<1x47x22xi16>, !spirv.arm.tensor<49x47x22xi16> -> !spirv.arm.tensor<49x47x22xi16>
+    // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<49x47x22xi16>
+    spirv.ARM.GraphOutputs %1 : !spirv.arm.tensor<49x47x22xi16>
+  }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.BitwiseAnd - 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 @bitwiseand_int_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<4x1x7x12xi16>, UniformConstant>
+  spirv.GlobalVariable @bitwiseand_int_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<4x13x7x12xi16>, UniformConstant>
+  spirv.GlobalVariable @bitwiseand_int_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<4x13x7x12xi16>, UniformConstant>
+  spirv.ARM.GraphEntryPoint @bitwiseand_int, @bitwiseand_int_arg_0, @bitwiseand_int_arg_1, @bitwiseand_int_res_0
+  spirv.ARM.Graph @bitwiseand_int(%arg0: !spirv.arm.tensor<4x1x7x12xi16>, %arg1: !spirv.arm.tensor<4x13x7x12xi16>) -> (!spirv.arm.tensor<4x13x7x12xi16>) {
+    // CHECK: {{%.*}} = spirv.Tosa.BitwiseAnd %arg0, %arg1 : !spirv.arm.tensor<4x1x7x12xi16>, !spirv.arm.tensor<4x13x7x12xi16> -> !spirv.arm.tensor<4x13x7x12xi16>
+    %0 = spirv.Tosa.BitwiseAnd %arg0, %arg1 : !spirv.arm.tensor<4x1x7x12xi16>, !spirv.arm.tensor<4x13x7x12xi16> -> !spirv.arm.tensor<4x13x7x12xi16>
+    // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<4x13x7x12xi16>
+    spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<4x13x7x12xi16>
+  }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.BitwiseOr - 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 @bitwiseor_int_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<11x30x23xi32>, UniformConstant>
+  spirv.GlobalVariable @bitwiseor_int_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<1x30x23xi32>, UniformConstant>
+  spirv.GlobalVariable @bitwiseor_int_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<11x30x23xi32>, UniformConstant>
+  spirv.ARM.GraphEntryPoint @bitwiseor_int, @bitwiseor_int_arg_0, @bitwiseor_int_arg_1, @bitwiseor_int_res_0
+  spirv.ARM.Graph @bitwiseor_int(%arg0: !spirv.arm.tensor<11x30x23xi32>, %arg1: !spirv.arm.tensor<1x30x23xi32>) -> (!spirv.arm.tensor<11x30x23xi32>) {
+    // CHECK: {{%.*}} = spirv.Tosa.BitwiseOr %arg0, %arg1 : !spirv.arm.tensor<11x30x23xi32>, !spirv.arm.tensor<1x30x23xi32> -> !spirv.arm.tensor<11x30x23xi32>
+    %0 = spirv.Tosa.BitwiseOr %arg0, %arg1 : !spirv.arm.tensor<11x30x23xi32>, !spirv.arm.tensor<1x30x23xi32> -> !spirv.arm.tensor<11x30x23xi32>
+    // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<11x30x23xi32>
+    spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<11x30x23xi32>
+  }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.BitwiseXor - 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 @bitwisexor_int_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<4x8x13x9xi16>, UniformConstant>
+  spirv.GlobalVariable @bitwisexor_int_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<4x8x1x9xi16>, UniformConstant>
+  spirv.GlobalVariable @bitwisexor_int_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<4x8x13x9xi16>, UniformConstant>
+  spirv.ARM.GraphEntryPoint @bitwisexor_int, @bitwisexor_int_arg_0, @bitwisexor_int_arg_1, @bitwisexor_int_res_0
+  spirv.ARM.Graph @bitwisexor_int(%arg0: !spirv.arm.tensor<4x8x13x9xi16>, %arg1: !spirv.arm.tensor<4x8x1x9xi16>) -> (!spirv.arm.tensor<4x8x13x9xi16>) {
+    // CHECK: {{%.*}} = spirv.Tosa.BitwiseXor %arg0, %arg1 : !spirv.arm.tensor<4x8x13x9xi16>, !spirv.arm.tensor<4x8x1x9xi16> -> !spirv.arm.tensor<4x8x13x9xi16>
+    %0 = spirv.Tosa.BitwiseXor %arg0, %arg1 : !spirv.arm.tensor<4x8x13x9xi16>, !spirv.arm.tensor<4x8x1x9xi16> -> !spirv.arm.tensor<4x8x13x9xi16>
+    // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<4x8x13x9xi16>
+    spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<4x8x13x9xi16>
+  }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.IntDiv - PRO-INT or 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 @intdiv_any_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<1x65533x1xi32>, UniformConstant>
+  spirv.GlobalVariable @intdiv_any_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<2x65533x1xi32>, UniformConstant>
+  spirv.GlobalVariable @intdiv_any_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<2x65533x1xi32>, UniformConstant>
+  spirv.ARM.GraphEntryPoint @intdiv_any, @intdiv_any_arg_0, @intdiv_any_arg_1, @intdiv_any_res_0
+  spirv.ARM.Graph @intdiv_any(%arg0: !spirv.arm.tensor<1x65533x1xi32>, %arg1: !spirv.arm.tensor<2x65533x1xi32>) -> (!spirv.arm.tensor<2x65533x1xi32>) {
+    // CHECK: {{%.*}} = spirv.Tosa.IntDiv %arg0, %arg1 : !spirv.arm.tensor<1x65533x1xi32>, !spirv.arm.tensor<2x65533x1xi32> -> !spirv.arm.tensor<2x65533x1xi32>
+    %0 = spirv.Tosa.IntDiv %arg0, %arg1 : !spirv.arm.tensor<1x65533x1xi32>, !spirv.arm.tensor<2x65533x1xi32> -> !spirv.arm.tensor<2x65533x1xi32>
+    // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<2x65533x1xi32>
+    spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<2x65533x1xi32>
+  }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.LogicalAnd - PRO-INT or 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 @logicaland_any_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<2x1x7x11xi1>, UniformConstant>
+  spirv.GlobalVariable @logicaland_any_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<2x4x7x11xi1>, UniformConstant>
+  spirv.GlobalVariable @logicaland_any_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<2x4x7x11xi1>, UniformConstant>
+  spirv.ARM.GraphEntryPoint @logicaland_any, @logicaland_any_arg_0, @logicaland_any_arg_1, @logicaland_any_res_0
+  spirv.ARM.Graph @logicaland_any(%arg0: !spirv.arm.tensor<2x1x7x11xi1>, %arg1: !spirv.arm.tensor<2x4x7x11xi1>) -> (!spirv.arm.tensor<2x4x7x11xi1>) {
+    // CHECK: {{%.*}} = spirv.Tosa.LogicalAnd %arg0, %arg1 : !spirv.arm.tensor<2x1x7x11xi1>, !spirv.arm.tensor<2x4x7x11xi1> -> !spirv.arm.tensor<2x4x7x11xi1>
+    %0 = spirv.Tosa.LogicalAnd %arg0, %arg1 : !spirv.arm.tensor<2x1x7x11xi1>, !spirv.arm.tensor<2x4x7x11xi1> -> !spirv.arm.tensor<2x4x7x11xi1>
+    // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<2x4x7x11xi1>
+    spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<2x4x7x11xi1>
+  }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.LogicalLeftShift - PRO-INT or 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 @logicalleftshift_any_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<7x1x11x4xi8>, UniformConstant>
+  spirv.GlobalVariable @logicalleftshift_any_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<7x8x11x4xi8>, UniformConstant>
+  spirv.GlobalVariable @logicalleftshift_any_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<7x8x11x4xi8>, UniformConstant>
+  spirv.ARM.GraphEntryPoint @logicalleftshift_any, @logicalleftshift_any_arg_0, @logicalleftshift_any_arg_1, @logicalleftshift_any_res_0
+  spirv.ARM.Graph @logicalleftshift_any(%arg0: !spirv.arm.tensor<7x1x11x4xi8>, %arg1: !spirv.arm.tensor<7x8x11x4xi8>) -> (!spirv.arm.tensor<7x8x11x4xi8>) {
+    // CHECK: {{%.*}} = spirv.Tosa.LogicalLeftShift %arg0, %arg1 : !spirv.arm.tensor<7x1x11x4xi8>, !spirv.arm.tensor<7x8x11x4xi8> -> !spirv.arm.tensor<7x8x11x4xi8>
+    %0 = spirv.Tosa.LogicalLeftShift %arg0, %arg1 : !spirv.arm.tensor<7x1x11x4xi8>, !spirv.arm.tensor<7x8x11x4xi8> -> !spirv.arm.tensor<7x8x11x4xi8>
+    // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<7x8x11x4xi8>
+    spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<7x8x11x4xi8>
+  }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.LogicalRightShift - PRO-INT or 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 @logicalrightshift_any_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<6x13x1x19xi8>, UniformConstant>
+  spirv.GlobalVariable @logicalrightshift_any_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<6x13x6x19xi8>, UniformConstant>
+  spirv.GlobalVariable @logicalrightshift_any_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<6x13x6x19xi8>, UniformConstant>
+  spirv.ARM.GraphEntryPoint @logicalrightshift_any, @logicalrightshift_any_arg_0, @logicalrightshift_any_arg_1, @logicalrightshift_any_res_0
+  spirv.ARM.Graph @logicalrightshift_any(%arg0: !spirv.arm.tensor<6x13x1x19xi8>, %arg1: !spirv.arm.tensor<6x13x6x19xi8>) -> (!spirv.arm.tensor<6x13x6x19xi8>) {
+    // CHECK: {{%.*}} = spirv.Tosa.LogicalRightShift %arg0, %arg1 : !spirv.arm.tensor<6x13x1x19xi8>, !spirv.arm.tensor<6x13x6x19xi8> -> !spirv.arm.tensor<6x13x6x19xi8>
+    %0 = spirv.Tosa.LogicalRightShift %arg0, %arg1 : !spirv.arm.tensor<6x13x1x19xi8>, !spirv.arm.tensor<6x13x6x19xi8> -> !spirv.arm.tensor<6x13x6x19xi8>
+    // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<6x13x6x19xi8>
+    spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<6x13x6x19xi8>
+  }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.LogicalOr - PRO-INT or 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 @logicalor_any_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<3x6x12x5xi1>, UniformConstant>
+  spirv.GlobalVariable @logicalor_any_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<3x6x1x5xi1>, UniformConstant>
+  spirv.GlobalVariable @logicalor_any_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<3x6x12x5xi1>, UniformConstant>
+  spirv.ARM.GraphEntryPoint @logicalor_any, @logicalor_any_arg_0, @logicalor_any_arg_1, @logicalor_any_res_0
+  spirv.ARM.Graph @logicalor_any(%arg0: !spirv.arm.tensor<3x6x12x5xi1>, %arg1: !spirv.arm.tensor<3x6x1x5xi1>) -> (!spirv.arm.tensor<3x6x12x5xi1>) {
+    // CHECK: {{%.*}} = spirv.Tosa.LogicalOr %arg0, %arg1 : !spirv.arm.tensor<3x6x12x5xi1>, !spirv.arm.tensor<3x6x1x5xi1> -> !spirv.arm.tensor<3x6x12x5xi1>
+    %0 = spirv.Tosa.LogicalOr %arg0, %arg1 : !spirv.arm.tensor<3x6x12x5xi1>, !spirv.arm.tensor<3x6x1x5xi1> -> !spirv.arm.tensor<3x6x12x5xi1>
+    // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<3x6x12x5xi1>
+    spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<3x6x12x5xi1>
+  }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.LogicalXor - PRO-INT or 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 @logicalxor_any_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<11x4x9x12xi1>, UniformConstant>
+  spirv.GlobalVariable @logicalxor_any_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<11x4x9x1xi1>, UniformConstant>
+  spirv.GlobalVariable @logicalxor_any_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<11x4x9x12xi1>, UniformConstant>
+  spirv.ARM.GraphEntryPoint @logicalxor_any, @logicalxor_any_arg_0, @logicalxor_any_arg_1, @logicalxor_any_res_0
+  spirv.ARM.Graph @logicalxor_any(%arg0: !spirv.arm.tensor<11x4x9x12xi1>, %arg1: !spirv.arm.tensor<11x4x9x1xi1>) -> (!spirv.arm.tensor<11x4x9x12xi1>) {
+    // CHECK: {{%.*}} = spirv.Tosa.LogicalXor %arg0, %arg1 : !spirv.arm.tensor<11x4x9x12xi1>, !spirv.arm.tensor<11x4x9x1xi1> -> !spirv.arm.tensor<11x4x9x12xi1>
+    %0 = spirv.Tosa.LogicalXor %arg0, %arg1 : !spirv.arm.tensor<11x4x9x12xi1>, !spirv.arm.tensor<11x4x9x1xi1> -> !spirv.arm.tensor<11x4x9x12xi1>
+    // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<11x4x9x12xi1>
+    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