[Mlir-commits] [mlir] [mlir][spirv] Add Pooling, Fourier Transform, and MatMul operations t… (PR #177585)

Davide Grohmann llvmlistbot at llvm.org
Wed Jan 28 05:15:01 PST 2026


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

>From dab134d32f9b2bc1183fd49afb913bfe6f3c3938 Mon Sep 17 00:00:00 2001
From: Davide Grohmann <davide.grohmann at arm.com>
Date: Fri, 23 Jan 2026 14:17:46 +0100
Subject: [PATCH] [mlir][spirv] Add Pooling, Fourier Transform, and MatMul
 operations to TOSA Extended Instruction Set (001000.1)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This patch expands support for the TOSA Extended Instruction Set
(001000.1) to the SPIR-V dialect in MLIR. The TOSA extended
instruction set provides a standardized set of machine learning
operations designed to be used within spirv.ARM.Graph operations
(corresponding to OpGraphARM in SPV_ARM_graph) and typed with
!spirv.arm.tensor<...> (corresponding to OpTypeTensorARM in
SPV_ARM_tensor).

The change introduces:

* Extending dialect plumbing for import, serialization, and
  deserialization of the TOSA extended instruction set.
* The spirv.Tosa.*Pool* pooling operations, spirv.Tosa.MatMul, and
  spirv.Tosa.*FFT* (Fourier Transform) operations from TOSA extended
  instruction, each lowering to the corresponding OpExtInst.
* Verification enforcing that new convolution operations appears only
  within spirv.ARM.Graph regions, operates on !spirv.arm.tensor<...>
  types, and is well-formed according to the TOSA 001000.1
  specification.

All these operations from TOSA 001000.1 extended instructions are
introduced: [parser, printer, verifier, and round-trip tests using
MLIR’s SPIR-V serialization/deserialization infrastructure are
included.

This work aligns with Khronos SPIR-V TOSA specifications.

Specification:
https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html

Signed-off-by: Davide Grohmann <davide.grohmann at arm.com>
Change-Id: I6c8813928c0d52541bb05d03244eaf9b2f6c4128
---
 .../mlir/Dialect/SPIRV/IR/SPIRVTosaOps.td     | 393 ++++++++++++++++--
 .../mlir/Dialect/SPIRV/IR/SPIRVTosaTypes.td   |  46 ++
 mlir/include/mlir/IR/OpBase.td                |  12 +-
 mlir/lib/Dialect/SPIRV/IR/SPIRVTosaOps.cpp    | 128 ------
 .../SPIRV/IR/tosa-ops-verification.mlir       | 133 ++++--
 mlir/test/Dialect/SPIRV/IR/tosa-ops.mlir      | 104 +++++
 mlir/test/Target/SPIRV/tosa-ops.mlir          | 173 ++++++++
 7 files changed, 785 insertions(+), 204 deletions(-)

diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaOps.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaOps.td
index 1b2f6a923d01b..eda0fbe54e19c 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaOps.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaOps.td
@@ -33,10 +33,39 @@ class SPIRV_TosaOp<string mnemonic, int opcode, list<Trait> traits = []> :
     Extension<[SPV_ARM_graph]>,
     Capability<[SPIRV_C_GraphARM]>
   ];
+
+  let hasVerifier = 0;
+}
+
+class SPIRV_TosaOpWithResult<string mnemonic, int opcode, list<Trait> traits = []> :
+  SPIRV_TosaOp<mnemonic, opcode, traits> {
+
+  code extraBaseClassDeclaration = [{
+    ::mlir::spirv::TensorArmType getResultType() {
+      return cast<::mlir::spirv::TensorArmType>(getType());
+    }
+  }];
+}
+
+class SPIRV_TosaOpWithComplexResult<string mnemonic, int opcode, list<Trait> traits = []> :
+  SPIRV_TosaOp<mnemonic, opcode, traits> {
+
+  code extraBaseClassDeclaration = [{
+    ::mlir::spirv::TensorArmType getResultRealType() {
+      auto resultType = cast<StructType>(getType());
+      return cast<::mlir::spirv::TensorArmType>(resultType.getElementType(0));
+    }
+    ::mlir::spirv::TensorArmType getResultImagType() {
+      auto resultType = cast<StructType>(getType());
+      return cast<::mlir::spirv::TensorArmType>(resultType.getElementType(1));
+    }
+  }];
 }
 
 
-def SPIRV_TosaArgMaxOp : SPIRV_TosaOp<"ArgMax", 0, [Pure]> {
+def SPIRV_TosaArgMaxOp : SPIRV_TosaOpWithResult<"ArgMax", 0, [Pure,
+  OutputRankIsInputRankMinusOne<"input", "output">,
+  AxisValueLessThanRankOf<"input">]> {
   let summary = "Perform argmax on the input.";
 
   let description = [{
@@ -65,26 +94,94 @@ def SPIRV_TosaArgMaxOp : SPIRV_TosaOp<"ArgMax", 0, [Pure]> {
     SPIRV_Int32_TensorArmUpTo5D: $output
   );
 
-  let hasVerifier = 1;
-
   let assemblyFormat = [{
-    `axis` `=` $axis `,` `nan_mode` `=` $nan_mode `,`
+    `axis` `=` $axis `,`
+    `nan_mode` `=` $nan_mode `,`
     $input
     attr-dict `:` type(operands) `->` type(results)
   }];
 
-  let extraClassDeclaration = [{
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
     ::mlir::spirv::TensorArmType getInputType() {
       return cast<::mlir::spirv::TensorArmType>(getInput().getType());
     }
-    ::mlir::spirv::TensorArmType getResultType() {
-      return cast<::mlir::spirv::TensorArmType>(getType());
+  }];
+}
+
+
+def SPIRV_TosaAvgPool2DOp : SPIRV_TosaOpWithResult<"AvgPool2D", 1, [Pure,
+  TypeImpliesAccType<"input", I8, ["INT32"]>,
+  TypeImpliesAccType<"input", I16, ["INT32"]>,
+  TypeImpliesAccType<"input", F16, ["FP16", "FP32"]>,
+  TypeImpliesAccType<"input", BF16, ["FP32"]>,
+  TypeImpliesAccType<"input", F32, ["FP32"]>,
+  AllElementTypesMatch<["input", "input_zp", "output", "output_zp"]>]> {
+  let summary = "Performs average pooling on the input.";
+
+  let description = [{
+    Performs an average pooling over the given input tensor. A sliding
+    window of size given by <kernel size> is passed over the input tensor, with
+    the mean value being placed in the output tensor. When calculating the
+    average, only the number of valid input tensor values, but not padding, are
+    used to calculate the divisor.
+
+    References:
+      * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_avg_pool2d
+      * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_avg_pool2d
+
+    #### Example:
+    ```mlir
+    %6 = spirv.Tosa.AvgPool2D kernel = [3, 3], stride = [1, 2], pad = [0, 1, 0, 0], acc_type = <INT32>, %arg0, %4, %5 : !spirv.arm.tensor<1x3x65537x1xi8>, !spirv.arm.tensor<1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<1x2x32768x1xi8>
+    %6 = spirv.Tosa.AvgPool2D kernel = [2, 2], stride = [1, 1], pad = [1, 0, 0, 0], acc_type = <FP32>, %arg0, %4, %5 : !spirv.arm.tensor<1x2x65533x2xf32>, !spirv.arm.tensor<1xf32>, !spirv.arm.tensor<1xf32> -> !spirv.arm.tensor<1x2x65532x2xf32>
+    ```
+  }];
+
+  let arguments = (ins
+    SPIRV_Int32_1DTensorArmOfLength2Attr: $kernel,
+    SPIRV_Int32_1DTensorArmOfLength2Attr: $stride,
+    SPIRV_Int32_1DTensorArmOfLength4Attr: $pad,
+    SPIRV_TosaExtAccTypeAttr: $acc_type,
+    SPIRV_TosaNumerical_TensorArm4D: $input,
+    SPIRV_TosaNumerical_1DTensorArmOfLength1: $input_zp,
+    SPIRV_TosaNumerical_1DTensorArmOfLength1: $output_zp
+  );
+
+  let results = (outs
+    SPIRV_TosaNumerical_TensorArm4D: $output
+  );
+
+  let assemblyFormat = [{
+    `kernel` `=` custom<SPIRV_I32_1DArmTensor>($kernel) `,`
+    `stride` `=` custom<SPIRV_I32_1DArmTensor>($stride) `,`
+    `pad` `=` custom<SPIRV_I32_1DArmTensor>($pad) `,`
+    `acc_type` `=` $acc_type `,`
+    $input `,`
+    $input_zp `,`
+    $output_zp
+    attr-dict `:` type(operands) `->` type(results)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getInputType() {
+      return cast<::mlir::spirv::TensorArmType>(getInput().getType());
     }
   }];
 }
 
 
-def SPIRV_TosaConv2DOp : SPIRV_TosaOp<"Conv2D", 2, [Pure,
+def SPIRV_TosaConv2DOp : SPIRV_TosaOpWithResult<"Conv2D", 2, [Pure,
+  TypeConstraintImplicationOn<"input", I8, "output", [I32]>,
+  TypeConstraintImplicationOn<"input", I16, "output", [I64]>,
+  TypeConstraintImplicationOn<"input", BF16, "output", [BF16]>,
+  TypeConstraintImplicationOn<"input", F16, "output", [F16]>,
+  TypeConstraintImplicationOn<"input", F32, "output", [F32]>,
+  TypeConstraintImplicationOn<"input", AnyInteger, "input", [I8, I16]>,
+  TypeConstraintImplicationOn<"input", AnyInteger, "input", [I8, I16]>,
+  TypeImpliesAccType<"input", I8, ["INT32"]>,
+  TypeImpliesAccType<"input", I16, ["INT48"]>,
+  TypeImpliesAccType<"input", F16, ["FP16", "FP32"]>,
+  TypeImpliesAccType<"input", BF16, ["FP32"]>,
+  TypeImpliesAccType<"input", F32, ["FP32"]>,
   AllElementTypesMatch<["bias", "output"]>,
   AllElementTypesMatch<["input", "input_zp"]>,
   AllElementTypesMatch<["weight", "weight_zp"]>]> {
@@ -95,6 +192,8 @@ def SPIRV_TosaConv2DOp : SPIRV_TosaOp<"Conv2D", 2, [Pure,
     tensor. Implementations may choose to skip calculation of multiplies in
     the padding area.
 
+    Input and weight have respective zero point values provided in input_zp and weight_zp.
+
     References:
       * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_conv2d
       * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_conv2d
@@ -123,8 +222,6 @@ def SPIRV_TosaConv2DOp : SPIRV_TosaOp<"Conv2D", 2, [Pure,
     SPIRV_TosaNumerical_TensorArm4D: $output
   );
 
-  let hasVerifier = 1;
-
   let assemblyFormat = [{
     `pad` `=` custom<SPIRV_I32_1DArmTensor>($pad) `,`
     `stride` `=` custom<SPIRV_I32_1DArmTensor>($stride) `,`
@@ -139,7 +236,7 @@ def SPIRV_TosaConv2DOp : SPIRV_TosaOp<"Conv2D", 2, [Pure,
     attr-dict `:` type(operands) `->` type(results)
   }];
 
-  let extraClassDeclaration = [{
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
     ::mlir::spirv::TensorArmType getInputType() {
       return cast<::mlir::spirv::TensorArmType>(getInput().getType());
     }
@@ -149,14 +246,23 @@ def SPIRV_TosaConv2DOp : SPIRV_TosaOp<"Conv2D", 2, [Pure,
     ::mlir::spirv::TensorArmType getBiasType() {
       return cast<::mlir::spirv::TensorArmType>(getBias().getType());
     }
-    ::mlir::spirv::TensorArmType getResultType() {
-      return cast<::mlir::spirv::TensorArmType>(getType());
-    }
   }];
 }
 
 
-def SPIRV_TosaConv3DOp : SPIRV_TosaOp<"Conv3D", 3, [Pure,
+def SPIRV_TosaConv3DOp : SPIRV_TosaOpWithResult<"Conv3D", 3, [Pure,
+  TypeConstraintImplicationOn<"input", I8, "output", [I32]>,
+  TypeConstraintImplicationOn<"input", I16, "output", [I64]>,
+  TypeConstraintImplicationOn<"input", BF16, "output", [BF16]>,
+  TypeConstraintImplicationOn<"input", F16, "output", [F16]>,
+  TypeConstraintImplicationOn<"input", F32, "output", [F32]>,
+  TypeConstraintImplicationOn<"input", AnyInteger, "input", [I8, I16]>,
+  TypeConstraintImplicationOn<"input", AnyInteger, "input", [I8, I16]>,
+  TypeImpliesAccType<"input", I8, ["INT32"]>,
+  TypeImpliesAccType<"input", I16, ["INT48"]>,
+  TypeImpliesAccType<"input", F16, ["FP16", "FP32"]>,
+  TypeImpliesAccType<"input", BF16, ["FP32"]>,
+  TypeImpliesAccType<"input", F32, ["FP32"]>,
   AllElementTypesMatch<["bias", "output"]>,
   AllElementTypesMatch<["input", "input_zp"]>,
   AllElementTypesMatch<["weight", "weight_zp"]>]> {
@@ -166,6 +272,8 @@ def SPIRV_TosaConv3DOp : SPIRV_TosaOp<"Conv3D", 3, [Pure,
     Performs a 3D convolution over the given input tensor. Implementations
     may choose to skip calculation of multiplies in the padding area.
 
+    Input and weight have respective zero point values provided in input_zp and weight_zp.
+
     References:
       * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_conv3d
       * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_conv3d
@@ -194,8 +302,6 @@ def SPIRV_TosaConv3DOp : SPIRV_TosaOp<"Conv3D", 3, [Pure,
     SPIRV_TosaNumerical_TensorArm5D: $output
   );
 
-  let hasVerifier = 1;
-
   let assemblyFormat = [{
     `pad` `=` custom<SPIRV_I32_1DArmTensor>($pad) `,`
     `stride` `=` custom<SPIRV_I32_1DArmTensor>($stride) `,`
@@ -210,7 +316,7 @@ def SPIRV_TosaConv3DOp : SPIRV_TosaOp<"Conv3D", 3, [Pure,
     attr-dict `:` type(operands) `->` type(results)
   }];
 
-  let extraClassDeclaration = [{
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
     ::mlir::spirv::TensorArmType getInputType() {
       return cast<::mlir::spirv::TensorArmType>(getInput().getType());
     }
@@ -220,14 +326,23 @@ def SPIRV_TosaConv3DOp : SPIRV_TosaOp<"Conv3D", 3, [Pure,
     ::mlir::spirv::TensorArmType getBiasType() {
       return cast<::mlir::spirv::TensorArmType>(getBias().getType());
     }
-    ::mlir::spirv::TensorArmType getResultType() {
-      return cast<::mlir::spirv::TensorArmType>(getType());
-    }
   }];
 }
 
 
-def SPIRV_TosaDepthwiseConv2DOp : SPIRV_TosaOp<"DepthwiseConv2D", 4, [Pure,
+def SPIRV_TosaDepthwiseConv2DOp : SPIRV_TosaOpWithResult<"DepthwiseConv2D", 4, [Pure,
+  TypeConstraintImplicationOn<"input", I8, "output", [I32]>,
+  TypeConstraintImplicationOn<"input", I16, "output", [I64]>,
+  TypeConstraintImplicationOn<"input", BF16, "output", [BF16]>,
+  TypeConstraintImplicationOn<"input", F16, "output", [F16]>,
+  TypeConstraintImplicationOn<"input", F32, "output", [F32]>,
+  TypeConstraintImplicationOn<"input", AnyInteger, "input", [I8, I16]>,
+  TypeConstraintImplicationOn<"input", AnyInteger, "input", [I8, I16]>,
+  TypeImpliesAccType<"input", I8, ["INT32"]>,
+  TypeImpliesAccType<"input", I16, ["INT48"]>,
+  TypeImpliesAccType<"input", F16, ["FP16", "FP32"]>,
+  TypeImpliesAccType<"input", BF16, ["FP32"]>,
+  TypeImpliesAccType<"input", F32, ["FP32"]>,
   AllElementTypesMatch<["bias", "output"]>,
   AllElementTypesMatch<["input", "input_zp"]>,
   AllElementTypesMatch<["weight", "weight_zp"]>]> {
@@ -238,6 +353,8 @@ def SPIRV_TosaDepthwiseConv2DOp : SPIRV_TosaOp<"DepthwiseConv2D", 4, [Pure,
     input, using the weight tensor. Implementations may choose to skip
     calculation of multiplies in the padding area.
 
+    Input and weight have respective zero point values provided in input_zp and weight_zp.
+
     References:
       * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_depthwise_conv2d
       * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_depthwise_conv2d
@@ -266,8 +383,6 @@ def SPIRV_TosaDepthwiseConv2DOp : SPIRV_TosaOp<"DepthwiseConv2D", 4, [Pure,
     SPIRV_TosaNumerical_TensorArm4D: $output
   );
 
-  let hasVerifier = 1;
-
   let assemblyFormat = [{
     `pad` `=` custom<SPIRV_I32_1DArmTensor>($pad) `,`
     `stride` `=` custom<SPIRV_I32_1DArmTensor>($stride) `,`
@@ -282,7 +397,7 @@ def SPIRV_TosaDepthwiseConv2DOp : SPIRV_TosaOp<"DepthwiseConv2D", 4, [Pure,
     attr-dict `:` type(operands) `->` type(results)
   }];
 
-  let extraClassDeclaration = [{
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
     ::mlir::spirv::TensorArmType getInputType() {
       return cast<::mlir::spirv::TensorArmType>(getInput().getType());
     }
@@ -292,14 +407,227 @@ def SPIRV_TosaDepthwiseConv2DOp : SPIRV_TosaOp<"DepthwiseConv2D", 4, [Pure,
     ::mlir::spirv::TensorArmType getBiasType() {
       return cast<::mlir::spirv::TensorArmType>(getBias().getType());
     }
-    ::mlir::spirv::TensorArmType getResultType() {
-      return cast<::mlir::spirv::TensorArmType>(getType());
+  }];
+}
+
+
+def SPIRV_TosaFFT2DOp : SPIRV_TosaOpWithComplexResult<"FFT2D", 5, [Pure]> {
+  let summary = "Performs FFT2D operation on the input.";
+
+  let description = [{
+    Performs a batched complex 2D Fast Fourier Transform over the input. The
+    complex input values are constructed from the corresponding values in the
+    input_real and input_imag tensors. The resulting values in the output are
+    split into the output_real and output_imag tensors. No normalization is
+    applied on either the forward or inverse versions of the operation.
+
+    References:
+      * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_fft2d
+      * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_fft2d
+
+    #### Example:
+    ```mlir
+    %0 = spirv.Tosa.FFT2D inverse = true, local_bound = false, %arg0, %arg1 : !spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32> -> !spirv.struct<(!spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>)>
+    %1 = spirv.CompositeExtract %0[0 : i32] : !spirv.struct<(!spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>)>
+    %2 = spirv.CompositeExtract %0[1 : i32] : !spirv.struct<(!spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>)>
+    ```
+  }];
+
+  let arguments = (ins
+    SPIRV_BoolConstAttr: $inverse,
+    SPIRV_BoolConstAttr: $local_bound,
+    SPIRV_Float32_TensorArm3D: $input_real,
+    SPIRV_Float32_TensorArm3D: $input_imag
+  );
+
+  let results = (outs
+    SPIRV_Struct_2_Float32_TensorArm3D: $output
+  );
+
+  let assemblyFormat = [{
+    `inverse` `=` $inverse `,`
+    `local_bound` `=` $local_bound `,`
+    $input_real `,`
+    $input_imag
+    attr-dict `:` type(operands) `->` type(results)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getInputRealType() {
+      return cast<::mlir::spirv::TensorArmType>(getInputReal().getType());
+    }
+    ::mlir::spirv::TensorArmType getInputImagType() {
+      return cast<::mlir::spirv::TensorArmType>(getInputImag().getType());
     }
   }];
 }
 
 
-def SPIRV_TosaTransposeConv2DOp : SPIRV_TosaOp<"TransposeConv2D", 9, [Pure,
+def SPIRV_TosaMatMulOp : SPIRV_TosaOpWithResult<"MatMul", 6, [Pure,
+  TypeConstraintImplicationOn<"A", I8, "output", [I32]>,
+  TypeConstraintImplicationOn<"A", I16, "output", [I64]>,
+  TypeConstraintImplicationOn<"A", BF16, "output", [F32]>,
+  TypeConstraintImplicationOn<"A", F16, "output", [F16, F32]>,
+  TypeConstraintImplicationOn<"A", F32, "output", [F32]>,
+  AllElementTypesMatch<["A", "A_zp", "B", "B_zp"]>]> {
+  let summary = "Matrix Multiplication operator.";
+
+  let description = [{
+    Performs two dimensional matrix multiplications.
+    A, B are the inputs with respective zero point values in A_zp, B_zp.
+
+    References:
+      * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_matmul
+      * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_matmul
+
+    #### Example:
+    ```mlir
+    %2 = spirv.Tosa.MatMul %arg0, %arg1, %0, %1 : !spirv.arm.tensor<8x2x3xi8>, !spirv.arm.tensor<8x3x8xi8>, !spirv.arm.tensor<1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<8x2x8xi32>
+    %2 = spirv.Tosa.MatMul %arg0, %arg1, %0, %1 : !spirv.arm.tensor<15x39x50xf16>, !spirv.arm.tensor<15x50x24xf16>, !spirv.arm.tensor<1xf16>, !spirv.arm.tensor<1xf16> -> !spirv.arm.tensor<15x39x24xf16>
+    ```
+  }];
+
+  let arguments = (ins
+    SPIRV_TosaNumerical_TensorArm3D: $A,
+    SPIRV_TosaNumerical_TensorArm3D: $B,
+    SPIRV_TosaNumerical_1DTensorArmOfLength1: $A_zp,
+    SPIRV_TosaNumerical_1DTensorArmOfLength1: $B_zp
+  );
+
+  let results = (outs
+    SPIRV_TosaNumerical_TensorArm3D: $output
+  );
+
+  let assemblyFormat = [{
+    $A `,`
+    $B `,`
+    $A_zp `,`
+    $B_zp
+    attr-dict `:` type(operands) `->` type(results)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getAType() {
+      return cast<::mlir::spirv::TensorArmType>(getA().getType());
+    }
+    ::mlir::spirv::TensorArmType getBType() {
+      return cast<::mlir::spirv::TensorArmType>(getB().getType());
+    }
+  }];
+}
+
+
+def SPIRV_TosaMaxPool2DOp : SPIRV_TosaOpWithResult<"MaxPool2D", 7, [Pure,
+  AllElementTypesMatch<["input", "output"]>]> {
+  let summary = "Performs max pooling on the input.";
+
+  let description = [{
+    Performs a max pooling over the given input tensor. A sliding window of
+    size given by <kernel size> is passed over the input tensor, with the
+    maximum value being placed in the
+    output tensor.
+
+    References:
+      * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_max_pool2d
+      * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_max_pool2d
+
+    #### Example:
+    ```mlir
+    %4 = spirv.Tosa.MaxPool2D kernel = [3, 2], stride = [1, 2], pad = [1, 0, 0, 1], nan_mode = <Propagate>, %arg0 : !spirv.arm.tensor<1x3x65537x1xi8> -> !spirv.arm.tensor<1x2x32769x1xi8>
+    %4 = spirv.Tosa.MaxPool2D kernel = [3, 2], stride = [2, 2], pad = [1, 0, 1, 1], nan_mode = <Propagate>, %arg0 : !spirv.arm.tensor<1x6x65536x1xf32> -> !spirv.arm.tensor<1x3x32769x1xf32>
+    ```
+  }];
+
+  let arguments = (ins
+    SPIRV_Int32_1DTensorArmOfLength2Attr: $kernel,
+    SPIRV_Int32_1DTensorArmOfLength2Attr: $stride,
+    SPIRV_Int32_1DTensorArmOfLength4Attr: $pad,
+    SPIRV_TosaExtNaNPropagationModeAttr: $nan_mode,
+    SPIRV_TosaNumerical_TensorArm4D: $input
+  );
+
+  let results = (outs
+    SPIRV_TosaNumerical_TensorArm4D: $output
+  );
+
+  let assemblyFormat = [{
+    `kernel` `=` custom<SPIRV_I32_1DArmTensor>($kernel) `,`
+    `stride` `=` custom<SPIRV_I32_1DArmTensor>($stride) `,`
+    `pad` `=` custom<SPIRV_I32_1DArmTensor>($pad) `,`
+    `nan_mode` `=` $nan_mode `,`
+    $input
+    attr-dict `:` type(operands) `->` type(results)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getInputType() {
+      return cast<::mlir::spirv::TensorArmType>(getInput().getType());
+    }
+  }];
+}
+
+
+def SPIRV_TosaRFFT2DOp : SPIRV_TosaOpWithComplexResult<"RFFT2D", 8, [Pure]> {
+  let summary = "Performs RFFT2D operation on the input.";
+
+  let description = [{
+    Performs a batched 2D real-valued Fast Fourier Transform over the input where
+    the input tensor consists of real values producing complex valued output. The
+    complex output values will be split into the output_real and output_imag
+    tensor arguments. RFFT2D takes advantage of Hermitian symmetry to only
+    calculate the first half of the final output axis. Implementations may choose
+    to skip calculation of the imaginary values at (0,0), (0,W/2), (H/2,0), and
+    (H/2, W/2). If the calculation is skipped, the result at that location must be
+    zero.
+
+    References:
+      * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_rfft2d
+      * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_rfft2d
+
+    #### Example:
+    ```mlir
+    %0 = spirv.Tosa.RFFT2D local_bound = false, %arg0 : !spirv.arm.tensor<1x32x32xf32> -> !spirv.struct<(!spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>)>
+    %1 = spirv.CompositeExtract %0[0 : i32] : !spirv.struct<(!spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>)>
+    %2 = spirv.CompositeExtract %0[1 : i32] : !spirv.struct<(!spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>)>
+    ```
+  }];
+
+  let arguments = (ins
+    SPIRV_BoolConstAttr: $local_bound,
+    SPIRV_Float32_TensorArm3D: $input_real
+  );
+
+  let results = (outs
+    SPIRV_Struct_2_Float32_TensorArm3D: $output
+  );
+
+  let assemblyFormat = [{
+    `local_bound` `=` $local_bound `,`
+    $input_real
+    attr-dict `:` type(operands) `->` type(results)
+  }];
+
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
+    ::mlir::spirv::TensorArmType getInputRealType() {
+      return cast<::mlir::spirv::TensorArmType>(getInputReal().getType());
+    }
+  }];
+}
+
+
+def SPIRV_TosaTransposeConv2DOp : SPIRV_TosaOpWithResult<"TransposeConv2D", 9, [Pure,
+  TypeConstraintImplicationOn<"input", I8, "output", [I32]>,
+  TypeConstraintImplicationOn<"input", I16, "output", [I64]>,
+  TypeConstraintImplicationOn<"input", BF16, "output", [BF16]>,
+  TypeConstraintImplicationOn<"input", F16, "output", [F16]>,
+  TypeConstraintImplicationOn<"input", F32, "output", [F32]>,
+  TypeConstraintImplicationOn<"input", AnyInteger, "input", [I8, I16]>,
+  TypeConstraintImplicationOn<"input", AnyInteger, "input", [I8, I16]>,
+  TypeImpliesAccType<"input", I8, ["INT32"]>,
+  TypeImpliesAccType<"input", I16, ["INT48"]>,
+  TypeImpliesAccType<"input", F16, ["FP16", "FP32"]>,
+  TypeImpliesAccType<"input", BF16, ["FP32"]>,
+  TypeImpliesAccType<"input", F32, ["FP32"]>,
   AllElementTypesMatch<["bias", "output"]>,
   AllElementTypesMatch<["input", "input_zp"]>,
   AllElementTypesMatch<["weight", "weight_zp"]>]> {
@@ -310,6 +638,8 @@ def SPIRV_TosaTransposeConv2DOp : SPIRV_TosaOp<"TransposeConv2D", 9, [Pure,
     weights tensor. Implementations may choose to skip calculation of multiplies
     by zero at fractional input positions.
 
+    Input and weight have respective zero point values provided in input_zp and weight_zp.
+
     References:
       * https://github.khronos.org/SPIRV-Registry/extended/TOSA.001000.1.html#_transpose_conv2d
       * https://www.mlplatform.org/tosa/tosa_spec_1_0_1.html#_transpose_conv2d
@@ -337,8 +667,6 @@ def SPIRV_TosaTransposeConv2DOp : SPIRV_TosaOp<"TransposeConv2D", 9, [Pure,
     SPIRV_TosaNumerical_TensorArm4D: $output
   );
 
-  let hasVerifier = 1;
-
   let assemblyFormat = [{
     `out_pad` `=` custom<SPIRV_I32_1DArmTensor>($out_pad) `,`
     `stride` `=` custom<SPIRV_I32_1DArmTensor>($stride) `,`
@@ -352,7 +680,7 @@ def SPIRV_TosaTransposeConv2DOp : SPIRV_TosaOp<"TransposeConv2D", 9, [Pure,
     attr-dict `:` type(operands) `->` type(results)
   }];
 
-  let extraClassDeclaration = [{
+  let extraClassDeclaration = extraBaseClassDeclaration#[{
     ::mlir::spirv::TensorArmType getInputType() {
       return cast<::mlir::spirv::TensorArmType>(getInput().getType());
     }
@@ -362,9 +690,6 @@ def SPIRV_TosaTransposeConv2DOp : SPIRV_TosaOp<"TransposeConv2D", 9, [Pure,
     ::mlir::spirv::TensorArmType getBiasType() {
       return cast<::mlir::spirv::TensorArmType>(getBias().getType());
     }
-    ::mlir::spirv::TensorArmType getResultType() {
-      return cast<::mlir::spirv::TensorArmType>(getType());
-    }
   }];
 }
 
diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaTypes.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaTypes.td
index 7e2c37f74b437..db4ad8064fc11 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaTypes.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTosaTypes.td
@@ -37,7 +37,9 @@ class TensorArmRankOf<list<Type> allowedTypes, list<int> ranks>
       [HasAnyRankOfPred<ranks>],
       !interleave(!foreach(rank, ranks, rank # "D"), "/") # " tensorArm">;
 
+def SPIRV_Float32_TensorArm3D: TensorArmRankOf<[SPIRV_Float32], [3]>;
 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]>;
 
@@ -67,4 +69,48 @@ def SPIRV_Int32_1DTensorArmOfLength6Attr : ConfinedAttr<RankedI32ElementsAttr<[6
 
 def SPIRV_TosaNumerical_1DTensorArmOfLength1 : SPIRV_1DTensorArmOfLengthAndType<[1], [SPIRV_TosaNumerical]>;
 
+// Struct type
+
+class IsStructOfNumElementsPred<int numElements> :
+  And<[SPIRV_IsStructType,
+      CPred<[{::llvm::cast<::mlir::spirv::StructType>($_self).getNumElements()
+              == }]
+            # numElements>]>;
+
+class IsStructOfNumElementsAndType<int numElements, list<Type> allowedTypes>
+    : MixedContainerType<AnyTypeOf<allowedTypes>, IsStructOfNumElementsPred<numElements>,
+                         "::llvm::cast<::mlir::spirv::StructType>($_self).getElementTypes()",
+                         "Struct">;
+
+def SPIRV_Struct_2_Float32_TensorArm3D : IsStructOfNumElementsAndType<2, [SPIRV_Float32_TensorArm3D]>;
+
+// Op Trait constraints:
+
+class Implies<Pred left, list<Pred> right>: Or<[Neg<left>, Or<right>]>;
+
+class TypeConstraintImplicationOn<string name, Type type, string other, list<Type> allowedTypes>:
+  PredOpTrait<"if " # name # " has type " # type.summary # " then " #
+              other # " must have a type in [" #
+              !interleave(!foreach(type, allowedTypes, type.summary), ",") # "]",
+    Implies<ElementTypeIsPred<name, type>,
+    !foreach(allowedType, allowedTypes, ElementTypeIsPred<other, allowedType>)>>;
+
+class AxisValueLessThanRankOf<string input>:
+PredOpTrait<"axis attribute value should be lower than rank(" # input # ")",
+  Implies<CPred<HasRank<input>.result>, [CPred<"getAxis() < " # Rank<input>.result>]>>;
+
+class OutputRankIsInputRankMinusOne<string input, string output>:
+PredOpTrait<output # " rank must be equal to max(1, rank(" # input # "))",
+  Implies<
+      And<[CPred<HasRank<input>.result>, CPred<HasRank<input>.result>]>,
+      [CPred<"std::max(int64_t(1), " # Rank<input>.result # " - int64_t(1)) == " # Rank<output>.result>]>>;
+
+class AccTypeIn<list<string> allowedValues> :
+  CPred<"llvm::is_contained({" # !interleave(!foreach(value, allowedValues, "::mlir::spirv::TosaExtAccType::" # value), ",") # "}, getAccType())">;
+
+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>]>>;
+
+
 #endif // MLIR_DIALECT_SPIRV_IR_TOSA_TYPES
diff --git a/mlir/include/mlir/IR/OpBase.td b/mlir/include/mlir/IR/OpBase.td
index 8d7dafae0ee76..7a667d701ab71 100644
--- a/mlir/include/mlir/IR/OpBase.td
+++ b/mlir/include/mlir/IR/OpBase.td
@@ -488,6 +488,10 @@ class PromisedTypeInterface<TypeInterface interface> : TypeConstraint<
 
 // TODO: Improve the autogenerated error messages.
 
+
+class HasRank<string name> :
+    StrFunc<"::llvm::cast<::mlir::ShapedType>($" # name # ".getType()).hasRank()">;
+
 class Rank<string name> :
     StrFunc<"::llvm::cast<::mlir::ShapedType>($" # name # ".getType()).getRank()">;
 
@@ -626,10 +630,10 @@ class InputMatchesTypes<list<string> inputArgs, list<Type> allowedTypes> :
 // Checks that inputArgs match one of the allowed type combinations.
 // Each combination in allowedCombinations must have the same number of types
 // as there are inputArgs.
-class InputAddressIsCombinationOf<list<string> inputArgs, 
+class InputAddressIsCombinationOf<list<string> inputArgs,
                                   list<list<Type>> allowedCombinations,
                                   string description = ""> :
-    PredOpTrait<!if(!empty(description), 
+    PredOpTrait<!if(!empty(description),
                     "operands {" # !interleave(inputArgs, ", ") # "} match one of the allowed type combinations",
                     description),
                 Or<!foreach(combination, allowedCombinations,
@@ -640,14 +644,14 @@ class InputAddressIsCombinationOf<list<string> inputArgs,
                                   ]>))>> {
     assert !gt(!size(allowedCombinations), 0),
            "allowedCombinations must not be empty";
-    
+
     // Validate that each combination has the same number of types as inputArgs
     defvar inputArgSize = !size(inputArgs);
     defvar validSizes = !foldl(1, allowedCombinations, acc, combination,
                               !and(acc, !eq(inputArgSize, !size(combination))));
     assert validSizes,
            "each combination in allowedCombinations must have the same length as inputArgs";
-    
+
     list<string> inputArgList = inputArgs;
     list<list<Type>> allowedCombinationList = allowedCombinations;
 }
diff --git a/mlir/lib/Dialect/SPIRV/IR/SPIRVTosaOps.cpp b/mlir/lib/Dialect/SPIRV/IR/SPIRVTosaOps.cpp
index 1d3e1084d5a9e..5116fef6201df 100644
--- a/mlir/lib/Dialect/SPIRV/IR/SPIRVTosaOps.cpp
+++ b/mlir/lib/Dialect/SPIRV/IR/SPIRVTosaOps.cpp
@@ -15,134 +15,6 @@
 
 namespace mlir::spirv {
 
-//===----------------------------------------------------------------------===//
-// TOSA Operator Verifiers.
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-LogicalResult verifyConvOp(Operation *op, Type inputETy, Type resultETy,
-                           TosaExtAccType accType) {
-  if (inputETy.isInteger() && !inputETy.isInteger(8) &&
-      !inputETy.isInteger(16)) {
-    return op->emitOpError(
-        "input element type can only be of width 8 or 16 when integer type");
-  }
-
-  if (inputETy.isInteger(8) && !resultETy.isInteger(32)) {
-    return op->emitOpError("expect result type to be i32, got ") << resultETy;
-  }
-
-  if (inputETy.isInteger(16) && !resultETy.isInteger(64)) {
-    return op->emitOpError("expect result type to be i64, got ") << resultETy;
-  }
-
-  if (inputETy.isF16() && !resultETy.isF16()) {
-    return op->emitOpError("expect result type to be f16, got ") << resultETy;
-  }
-
-  if (inputETy.isF32() && !resultETy.isF32()) {
-    return op->emitOpError("expect result type to be f32, got ") << resultETy;
-  }
-
-  if (inputETy.isInteger(8) && accType != TosaExtAccType::INT32) {
-    return op->emitOpError("accumulator type for i8 tensorARM is not i32");
-  }
-
-  if (inputETy.isInteger(16) && accType != TosaExtAccType::INT48) {
-    return op->emitOpError("accumulator type for i16 tensorARM is not i48");
-  }
-
-  if (inputETy.isF16() &&
-      !llvm::is_contained({TosaExtAccType::FP16, TosaExtAccType::FP32},
-                          accType)) {
-    return op->emitOpError(
-        "accumulator type for f16 tensorARM is not f16 or f32");
-  }
-
-  if (inputETy.isBF16() && accType != TosaExtAccType::FP32) {
-    return op->emitOpError("accumulator type for bf16 tensorARM is not f32");
-  }
-
-  if (inputETy.isF32() && accType != TosaExtAccType::FP32) {
-    return op->emitOpError("accumulator type for f32 tensorARM is not f32");
-  }
-
-  return success();
-}
-
-} // namespace
-
-//===----------------------------------------------------------------------===//
-// spirv.TosaArgmaxOp
-//===----------------------------------------------------------------------===//
-
-LogicalResult TosaArgMaxOp::verify() {
-  ShapedType inputTy = getInputType();
-  ShapedType resultTy = getResultType();
-
-  if (inputTy.hasRank() && resultTy.hasRank() &&
-      resultTy.getRank() !=
-          (inputTy.getRank() > 1 ? inputTy.getRank() - 1 : 1)) {
-    return emitOpError(
-               "result rank must be max of 1 and (input rank - 1), got ")
-           << resultTy.getRank();
-  }
-
-  const uint32_t axis = getAxis();
-  if (inputTy.hasRank() && axis >= inputTy.getRank()) {
-    return emitOpError(
-               "specified axis is greater than the rank of input, got axis = ")
-           << axis << " and input rank = " << inputTy.getRank();
-  }
-
-  return success();
-}
-
-//===----------------------------------------------------------------------===//
-// spirv.TosaConv2DOp
-//===----------------------------------------------------------------------===//
-
-LogicalResult TosaConv2DOp::verify() {
-  Type inputETy = getInputType().getElementType();
-  Type resultETy = getResultType().getElementType();
-  TosaExtAccType accType = getAccType();
-  return verifyConvOp(this->getOperation(), inputETy, resultETy, accType);
-}
-
-//===----------------------------------------------------------------------===//
-// spirv.TosaConv3DOp
-//===----------------------------------------------------------------------===//
-
-LogicalResult TosaConv3DOp::verify() {
-  Type inputETy = getInputType().getElementType();
-  Type resultETy = getResultType().getElementType();
-  TosaExtAccType accType = getAccType();
-  return verifyConvOp(this->getOperation(), inputETy, resultETy, accType);
-}
-
-//===----------------------------------------------------------------------===//
-// SPIRV Tosa DepthwiseConv2D Ops:
-//===----------------------------------------------------------------------===//
-
-LogicalResult TosaDepthwiseConv2DOp::verify() {
-  Type inputETy = getInputType().getElementType();
-  Type resultETy = getResultType().getElementType();
-  TosaExtAccType accType = getAccType();
-  return verifyConvOp(this->getOperation(), inputETy, resultETy, accType);
-}
-
-//===----------------------------------------------------------------------===//
-// SPIRV Tosa TransposeConv2D Ops:
-//===----------------------------------------------------------------------===//
-
-LogicalResult TosaTransposeConv2DOp::verify() {
-  Type inputETy = getInputType().getElementType();
-  Type resultETy = getResultType().getElementType();
-  TosaExtAccType accType = getAccType();
-  return verifyConvOp(this->getOperation(), inputETy, resultETy, accType);
-}
-
 //===----------------------------------------------------------------------===//
 // SPIRV Tosa Custom formatters
 //===----------------------------------------------------------------------===//
diff --git a/mlir/test/Dialect/SPIRV/IR/tosa-ops-verification.mlir b/mlir/test/Dialect/SPIRV/IR/tosa-ops-verification.mlir
index 2099630aff0fb..3c08470606c49 100644
--- a/mlir/test/Dialect/SPIRV/IR/tosa-ops-verification.mlir
+++ b/mlir/test/Dialect/SPIRV/IR/tosa-ops-verification.mlir
@@ -11,13 +11,13 @@ spirv.ARM.Graph @argmax_non_i32_result_element_type(%arg0: !spirv.arm.tensor<3x2
 }
 
 spirv.ARM.Graph @argmax_incorrect_output_rank(%arg0: !spirv.arm.tensor<3x28x17x17xi8>) -> (!spirv.arm.tensor<3x28xi32>) {
-  // expected-error @+1 {{op result rank must be max of 1 and (input rank - 1), got 2}}
+  // expected-error @+1 {{op failed to verify that output rank must be equal to max(1, rank(input))}}
   %2 = spirv.Tosa.ArgMax axis = 2, nan_mode = <Propagate>, %arg0 : !spirv.arm.tensor<3x28x17x17xi8> -> !spirv.arm.tensor<3x28xi32>
   spirv.ARM.GraphOutputs %2 : !spirv.arm.tensor<3x28xi32>
 }
 
 spirv.ARM.Graph @argmax_axis_value_not_in_input_rank_range(%arg0: !spirv.arm.tensor<3x28x17x17xi8>) -> (!spirv.arm.tensor<3x28x17xi32>) {
-  // expected-error @+1 {{op specified axis is greater than the rank of input, got axis = 4 and input rank = 4}}
+  // expected-error @+1 {{op failed to verify that axis attribute value should be lower than rank(input)}}
   %2 = spirv.Tosa.ArgMax axis = 4, nan_mode = <Propagate>, %arg0 : !spirv.arm.tensor<3x28x17x17xi8> -> !spirv.arm.tensor<3x28x17xi32>
   spirv.ARM.GraphOutputs %2 : !spirv.arm.tensor<3x28x17xi32>
 }
@@ -29,7 +29,7 @@ spirv.ARM.Graph @argmax_axis_value_not_in_input_rank_range(%arg0: !spirv.arm.ten
 spirv.ARM.Graph @conv2d_wrong_input_integer_element_type(%arg0: !spirv.arm.tensor<1x65535x3x1xi32>, %arg1: !spirv.arm.tensor<7x1x1x1xi32>, %arg2: !spirv.arm.tensor<1xi64>) -> (!spirv.arm.tensor<1x65536x2x7xi64>) {
   %5 = spirv.Constant dense<35> : !spirv.arm.tensor<1xi32>
   %6 = spirv.Constant dense<57> : !spirv.arm.tensor<1xi32>
-  // expected-error @+1 {{op input element type can only be of width 8 or 16 when integer type}}
+  // expected-error @+1 {{op failed to verify that if input has type integer then input must have a type in [8-bit signless integer,16-bit signless integer]}}
   %7 = spirv.Tosa.Conv2D pad = [1, 0, 0, 0], stride = [1, 2], dilation = [7, 1], acc_type = <INT32>, local_bound = false, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x65535x3x1xi32>, !spirv.arm.tensor<7x1x1x1xi32>, !spirv.arm.tensor<1xi64>, !spirv.arm.tensor<1xi32>, !spirv.arm.tensor<1xi32> -> !spirv.arm.tensor<1x65536x2x7xi64>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65536x2x7xi64>
 }
@@ -37,7 +37,7 @@ spirv.ARM.Graph @conv2d_wrong_input_integer_element_type(%arg0: !spirv.arm.tenso
 spirv.ARM.Graph @conv2d_mismatch_result_element_type_i8_input(%arg0: !spirv.arm.tensor<1x65535x3x1xi8>, %arg1: !spirv.arm.tensor<7x1x1x1xi8>, %arg2: !spirv.arm.tensor<1xi16>) -> (!spirv.arm.tensor<1x65536x2x7xi16>) {
   %5 = spirv.Constant dense<35> : !spirv.arm.tensor<1xi8>
   %6 = spirv.Constant dense<57> : !spirv.arm.tensor<1xi8>
-  // expected-error @+1 {{op expect result type to be i32, got 'i16'}}
+  // expected-error @+1 {{op failed to verify that if input has type 8-bit signless integer then output must have a type in [32-bit signless integer]}}
   %7 = spirv.Tosa.Conv2D pad = [1, 0, 0, 0], stride = [1, 2], dilation = [7, 1], acc_type = <INT32>, local_bound = false, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x65535x3x1xi8>, !spirv.arm.tensor<7x1x1x1xi8>, !spirv.arm.tensor<1xi16>, !spirv.arm.tensor<1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<1x65536x2x7xi16>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65536x2x7xi16>
 }
@@ -45,7 +45,7 @@ spirv.ARM.Graph @conv2d_mismatch_result_element_type_i8_input(%arg0: !spirv.arm.
 spirv.ARM.Graph @conv2d_mismatch_result_element_type_i16_input(%arg0: !spirv.arm.tensor<1x65535x3x1xi16>, %arg1: !spirv.arm.tensor<7x1x1x1xi16>, %arg2: !spirv.arm.tensor<1xi32>) -> (!spirv.arm.tensor<1x65536x2x7xi32>) {
   %5 = spirv.Constant dense<35> : !spirv.arm.tensor<1xi16>
   %6 = spirv.Constant dense<57> : !spirv.arm.tensor<1xi16>
-  // expected-error @+1 {{op expect result type to be i64, got 'i32'}}
+  // expected-error @+1 {{op failed to verify that if input has type 16-bit signless integer then output must have a type in [64-bit signless integer]}}
   %7 = spirv.Tosa.Conv2D pad = [1, 0, 0, 0], stride = [1, 2], dilation = [7, 1], acc_type = <INT32>, local_bound = false, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x65535x3x1xi16>, !spirv.arm.tensor<7x1x1x1xi16>, !spirv.arm.tensor<1xi32>, !spirv.arm.tensor<1xi16>, !spirv.arm.tensor<1xi16> -> !spirv.arm.tensor<1x65536x2x7xi32>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65536x2x7xi32>
 }
@@ -53,7 +53,7 @@ spirv.ARM.Graph @conv2d_mismatch_result_element_type_i16_input(%arg0: !spirv.arm
 spirv.ARM.Graph @conv2d_mismatch_result_element_type_f16_input(%arg0: !spirv.arm.tensor<1x34x18x27xf16>, %arg1: !spirv.arm.tensor<11x1x1x27xf16>, %arg2: !spirv.arm.tensor<11xf32>) -> (!spirv.arm.tensor<1x34x18x11xf32>) {
   %5 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
   %6 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
-  // expected-error @+1 {{op expect result type to be f16, got 'f32'}}
+  // expected-error @+1 {{op failed to verify that if input has type 16-bit float then output must have a type in [16-bit float]}}
   %7 = spirv.Tosa.Conv2D pad = [0, 0, 0, 0], stride = [1, 1], dilation = [1, 1], acc_type = <FP16>, local_bound = true, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x34x18x27xf16>, !spirv.arm.tensor<11x1x1x27xf16>, !spirv.arm.tensor<11xf32>, !spirv.arm.tensor<1xf16>, !spirv.arm.tensor<1xf16> -> !spirv.arm.tensor<1x34x18x11xf32>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x34x18x11xf32>
 }
@@ -61,7 +61,7 @@ spirv.ARM.Graph @conv2d_mismatch_result_element_type_f16_input(%arg0: !spirv.arm
 spirv.ARM.Graph @conv2d_mismatch_result_element_type_f32_input(%arg0: !spirv.arm.tensor<1x34x18x27xf32>, %arg1: !spirv.arm.tensor<11x1x1x27xf32>, %arg2: !spirv.arm.tensor<11xf16>) -> (!spirv.arm.tensor<1x34x18x11xf16>) {
   %5 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
   %6 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
-  // expected-error @+1 {{op expect result type to be f32, got 'f16'}}
+  // expected-error @+1 {{op failed to verify that if input has type 32-bit float then output must have a type in [32-bit float]}}
   %7 = spirv.Tosa.Conv2D pad = [0, 0, 0, 0], stride = [1, 1], dilation = [1, 1], acc_type = <FP16>, local_bound = true, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x34x18x27xf32>, !spirv.arm.tensor<11x1x1x27xf32>, !spirv.arm.tensor<11xf16>, !spirv.arm.tensor<1xf32>, !spirv.arm.tensor<1xf32> -> !spirv.arm.tensor<1x34x18x11xf16>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x34x18x11xf16>
 }
@@ -77,7 +77,7 @@ spirv.ARM.Graph @conv2d_bias_element_type_must_be_same_as_result_element_type(%a
 spirv.ARM.Graph @conv2d_accumulator_must_be_INT32_for_i8_input_element_type(%arg0: !spirv.arm.tensor<1x65535x3x1xi8>, %arg1: !spirv.arm.tensor<7x1x1x1xi8>, %arg2: !spirv.arm.tensor<1xi32>) -> (!spirv.arm.tensor<1x65536x2x7xi32>) {
   %5 = spirv.Constant dense<35> : !spirv.arm.tensor<1xi8>
   %6 = spirv.Constant dense<57> : !spirv.arm.tensor<1xi8>
-  // expected-error @+1 {{op accumulator type for i8 tensorARM is not i32}}
+  // expected-error @+1 {{op failed to verify that acc_type must be one in [INT32] when type has value 8-bit signless integer}}
   %7 = spirv.Tosa.Conv2D pad = [1, 0, 0, 0], stride = [1, 2], dilation = [7, 1], acc_type = <INT48>, local_bound = false, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x65535x3x1xi8>, !spirv.arm.tensor<7x1x1x1xi8>, !spirv.arm.tensor<1xi32>, !spirv.arm.tensor<1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<1x65536x2x7xi32>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65536x2x7xi32>
 }
@@ -85,7 +85,7 @@ spirv.ARM.Graph @conv2d_accumulator_must_be_INT32_for_i8_input_element_type(%arg
 spirv.ARM.Graph @conv2d_accumulator_must_be_INT48_for_i16_input_element_type(%arg0: !spirv.arm.tensor<1x65535x3x1xi16>, %arg1: !spirv.arm.tensor<7x1x1x1xi16>, %arg2: !spirv.arm.tensor<1xi64>) -> (!spirv.arm.tensor<1x65536x2x7xi64>) {
   %5 = spirv.Constant dense<35> : !spirv.arm.tensor<1xi16>
   %6 = spirv.Constant dense<57> : !spirv.arm.tensor<1xi16>
-  // expected-error @+1 {{op accumulator type for i16 tensorARM is not i48}}
+  // expected-error @+1 {{op failed to verify that acc_type must be one in [INT48] when type has value 16-bit signless integer}}
   %7 = spirv.Tosa.Conv2D pad = [1, 0, 0, 0], stride = [1, 2], dilation = [7, 1], acc_type = <INT32>, local_bound = false, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x65535x3x1xi16>, !spirv.arm.tensor<7x1x1x1xi16>, !spirv.arm.tensor<1xi64>, !spirv.arm.tensor<1xi16>, !spirv.arm.tensor<1xi16> -> !spirv.arm.tensor<1x65536x2x7xi64>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65536x2x7xi64>
 }
@@ -93,7 +93,7 @@ spirv.ARM.Graph @conv2d_accumulator_must_be_INT48_for_i16_input_element_type(%ar
 spirv.ARM.Graph @conv2d_accumulator_must_be_either_FP16_or_FP32_for_f16_input_element_type(%arg0: !spirv.arm.tensor<1x34x18x27xf16>, %arg1: !spirv.arm.tensor<11x1x1x27xf16>, %arg2: !spirv.arm.tensor<11xf16>) -> (!spirv.arm.tensor<1x34x18x11xf16>) {
   %5 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
   %6 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
-  // expected-error @+1 {{op accumulator type for f16 tensorARM is not f16 or f32}}
+  // expected-error @+1 {{op failed to verify that acc_type must be one in [FP16,FP32] when type has value 16-bit float}}
   %7 = spirv.Tosa.Conv2D pad = [0, 0, 0, 0], stride = [1, 1], dilation = [1, 1], acc_type = <INT32>, local_bound = true, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x34x18x27xf16>, !spirv.arm.tensor<11x1x1x27xf16>, !spirv.arm.tensor<11xf16>, !spirv.arm.tensor<1xf16>, !spirv.arm.tensor<1xf16> -> !spirv.arm.tensor<1x34x18x11xf16>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x34x18x11xf16>
 }
@@ -101,7 +101,7 @@ spirv.ARM.Graph @conv2d_accumulator_must_be_either_FP16_or_FP32_for_f16_input_el
 spirv.ARM.Graph @conv2d_accumulator_must_be_either_FP32_for_f32_input_element_type(%arg0: !spirv.arm.tensor<1x34x18x27xf32>, %arg1: !spirv.arm.tensor<11x1x1x27xf32>, %arg2: !spirv.arm.tensor<11xf32>) -> (!spirv.arm.tensor<1x34x18x11xf32>) {
   %5 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
   %6 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
-  // expected-error @+1 {{op accumulator type for f32 tensorARM is not f32}}
+  // expected-error @+1 {{op failed to verify that acc_type must be one in [FP32] when type has value 32-bit float}}
   %7 = spirv.Tosa.Conv2D pad = [0, 0, 0, 0], stride = [1, 1], dilation = [1, 1], acc_type = <FP16>, local_bound = true, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x34x18x27xf32>, !spirv.arm.tensor<11x1x1x27xf32>, !spirv.arm.tensor<11xf32>, !spirv.arm.tensor<1xf32>, !spirv.arm.tensor<1xf32> -> !spirv.arm.tensor<1x34x18x11xf32>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x34x18x11xf32>
 }
@@ -114,7 +114,7 @@ spirv.ARM.Graph @conv2d_accumulator_must_be_either_FP32_for_f32_input_element_ty
 spirv.ARM.Graph @conv3d_wrong_input_integer_element_type(%arg0: !spirv.arm.tensor<1x65535x3x1x1xi32>, %arg1: !spirv.arm.tensor<7x1x1x1x1xi32>, %arg2: !spirv.arm.tensor<1xi64>) -> (!spirv.arm.tensor<1x65536x2x7x1xi64>) {
   %5 = spirv.Constant dense<35> : !spirv.arm.tensor<1xi32>
   %6 = spirv.Constant dense<57> : !spirv.arm.tensor<1xi32>
-  // expected-error @+1 {{op input element type can only be of width 8 or 16 when integer type}}
+  // expected-error @+1 {{ op failed to verify that if input has type integer then input must have a type in [8-bit signless integer,16-bit signless integer]}}
   %7 = spirv.Tosa.Conv3D pad = [1, 0, 0, 0, 0, 0], stride = [1, 2, 3], dilation = [7, 1, 1], acc_type = <INT32>, local_bound = false, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x65535x3x1x1xi32>, !spirv.arm.tensor<7x1x1x1x1xi32>, !spirv.arm.tensor<1xi64>, !spirv.arm.tensor<1xi32>, !spirv.arm.tensor<1xi32> -> !spirv.arm.tensor<1x65536x2x7x1xi64>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65536x2x7x1xi64>
 }
@@ -122,7 +122,7 @@ spirv.ARM.Graph @conv3d_wrong_input_integer_element_type(%arg0: !spirv.arm.tenso
 spirv.ARM.Graph @conv3d_mismatch_result_element_type_i8_input(%arg0: !spirv.arm.tensor<1x65535x3x1x1xi8>, %arg1: !spirv.arm.tensor<7x1x1x1x1xi8>, %arg2: !spirv.arm.tensor<1xi16>) -> (!spirv.arm.tensor<1x65536x2x7x1xi16>) {
   %5 = spirv.Constant dense<35> : !spirv.arm.tensor<1xi8>
   %6 = spirv.Constant dense<57> : !spirv.arm.tensor<1xi8>
-  // expected-error @+1 {{op expect result type to be i32, got 'i16'}}
+  // expected-error @+1 {{op failed to verify that if input has type 8-bit signless integer then output must have a type in [32-bit signless integer]}}
   %7 = spirv.Tosa.Conv3D pad = [1, 0, 0, 0, 0, 0], stride = [1, 2, 3], dilation = [7, 1, 1], acc_type = <INT32>, local_bound = false, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x65535x3x1x1xi8>, !spirv.arm.tensor<7x1x1x1x1xi8>, !spirv.arm.tensor<1xi16>, !spirv.arm.tensor<1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<1x65536x2x7x1xi16>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65536x2x7x1xi16>
 }
@@ -130,7 +130,7 @@ spirv.ARM.Graph @conv3d_mismatch_result_element_type_i8_input(%arg0: !spirv.arm.
 spirv.ARM.Graph @conv3d_mismatch_result_element_type_i16_input(%arg0: !spirv.arm.tensor<1x65535x3x1x1xi16>, %arg1: !spirv.arm.tensor<7x1x1x1x1xi16>, %arg2: !spirv.arm.tensor<1xi32>) -> (!spirv.arm.tensor<1x65536x2x7x1xi32>) {
   %5 = spirv.Constant dense<35> : !spirv.arm.tensor<1xi16>
   %6 = spirv.Constant dense<57> : !spirv.arm.tensor<1xi16>
-  // expected-error @+1 {{op expect result type to be i64, got 'i32'}}
+  // expected-error @+1 {{op failed to verify that if input has type 16-bit signless integer then output must have a type in [64-bit signless integer]}}
   %7 = spirv.Tosa.Conv3D pad = [1, 0, 0, 0, 0, 0], stride = [1, 2, 3], dilation = [7, 1, 1], acc_type = <INT32>, local_bound = false, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x65535x3x1x1xi16>, !spirv.arm.tensor<7x1x1x1x1xi16>, !spirv.arm.tensor<1xi32>, !spirv.arm.tensor<1xi16>, !spirv.arm.tensor<1xi16> -> !spirv.arm.tensor<1x65536x2x7x1xi32>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65536x2x7x1xi32>
 }
@@ -138,7 +138,7 @@ spirv.ARM.Graph @conv3d_mismatch_result_element_type_i16_input(%arg0: !spirv.arm
 spirv.ARM.Graph @conv3d_mismatch_result_element_type_f16_input(%arg0: !spirv.arm.tensor<1x34x18x27x1xf16>, %arg1: !spirv.arm.tensor<11x1x1x27x1xf16>, %arg2: !spirv.arm.tensor<11xf32>) -> (!spirv.arm.tensor<1x34x18x11x1xf32>) {
   %5 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
   %6 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
-  // expected-error @+1 {{op expect result type to be f16, got 'f32'}}
+  // expected-error @+1 {{op failed to verify that if input has type 16-bit float then output must have a type in [16-bit float]}}
   %7 = spirv.Tosa.Conv3D pad = [0, 0, 0, 0, 0, 0], stride = [1, 1, 1], dilation = [1, 1, 1], acc_type = <FP16>, local_bound = true, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x34x18x27x1xf16>, !spirv.arm.tensor<11x1x1x27x1xf16>, !spirv.arm.tensor<11xf32>, !spirv.arm.tensor<1xf16>, !spirv.arm.tensor<1xf16> -> !spirv.arm.tensor<1x34x18x11x1xf32>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x34x18x11x1xf32>
 }
@@ -146,7 +146,7 @@ spirv.ARM.Graph @conv3d_mismatch_result_element_type_f16_input(%arg0: !spirv.arm
 spirv.ARM.Graph @conv3d_mismatch_result_element_type_f32_input(%arg0: !spirv.arm.tensor<1x34x18x27x1xf32>, %arg1: !spirv.arm.tensor<11x1x1x27x1xf32>, %arg2: !spirv.arm.tensor<11xf16>) -> (!spirv.arm.tensor<1x34x18x11x1xf16>) {
   %5 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
   %6 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
-  // expected-error @+1 {{op expect result type to be f32, got 'f16'}}
+  // expected-error @+1 {{op failed to verify that if input has type 32-bit float then output must have a type in [32-bit float]}}
   %7 = spirv.Tosa.Conv3D pad = [0, 0, 0, 0, 0, 0], stride = [1, 1, 1], dilation = [1, 1, 1], acc_type = <FP16>, local_bound = true, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x34x18x27x1xf32>, !spirv.arm.tensor<11x1x1x27x1xf32>, !spirv.arm.tensor<11xf16>, !spirv.arm.tensor<1xf32>, !spirv.arm.tensor<1xf32> -> !spirv.arm.tensor<1x34x18x11x1xf16>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x34x18x11x1xf16>
 }
@@ -162,7 +162,7 @@ spirv.ARM.Graph @conv3d_bias_element_type_must_be_same_as_result_element_type(%a
 spirv.ARM.Graph @conv3d_accumulator_must_be_INT32_for_i8_input_element_type(%arg0: !spirv.arm.tensor<1x65535x3x1x1xi8>, %arg1: !spirv.arm.tensor<7x1x1x1x1xi8>, %arg2: !spirv.arm.tensor<1xi32>) -> (!spirv.arm.tensor<1x65536x2x7x1xi32>) {
   %5 = spirv.Constant dense<35> : !spirv.arm.tensor<1xi8>
   %6 = spirv.Constant dense<57> : !spirv.arm.tensor<1xi8>
-  // expected-error @+1 {{op accumulator type for i8 tensorARM is not i32}}
+  // expected-error @+1 {{op failed to verify that acc_type must be one in [INT32] when type has value 8-bit signless integer}}
   %7 = spirv.Tosa.Conv3D pad = [1, 0, 0, 0, 0, 0], stride = [1, 2, 3], dilation = [7, 1, 1], acc_type = <INT48>, local_bound = false, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x65535x3x1x1xi8>, !spirv.arm.tensor<7x1x1x1x1xi8>, !spirv.arm.tensor<1xi32>, !spirv.arm.tensor<1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<1x65536x2x7x1xi32>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65536x2x7x1xi32>
 }
@@ -170,7 +170,7 @@ spirv.ARM.Graph @conv3d_accumulator_must_be_INT32_for_i8_input_element_type(%arg
 spirv.ARM.Graph @conv3d_accumulator_must_be_INT48_for_i16_input_element_type(%arg0: !spirv.arm.tensor<1x65535x3x1x1xi16>, %arg1: !spirv.arm.tensor<7x1x1x1x1xi16>, %arg2: !spirv.arm.tensor<1xi64>) -> (!spirv.arm.tensor<1x65536x2x7x1xi64>) {
   %5 = spirv.Constant dense<35> : !spirv.arm.tensor<1xi16>
   %6 = spirv.Constant dense<57> : !spirv.arm.tensor<1xi16>
-  // expected-error @+1 {{op accumulator type for i16 tensorARM is not i48}}
+  // expected-error @+1 {{op failed to verify that acc_type must be one in [INT48] when type has value 16-bit signless integer}}
   %7 = spirv.Tosa.Conv3D pad = [1, 0, 0, 0, 0, 0], stride = [1, 2, 3], dilation = [7, 1, 1], acc_type = <INT32>, local_bound = false, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x65535x3x1x1xi16>, !spirv.arm.tensor<7x1x1x1x1xi16>, !spirv.arm.tensor<1xi64>, !spirv.arm.tensor<1xi16>, !spirv.arm.tensor<1xi16> -> !spirv.arm.tensor<1x65536x2x7x1xi64>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65536x2x7x1xi64>
 }
@@ -178,7 +178,7 @@ spirv.ARM.Graph @conv3d_accumulator_must_be_INT48_for_i16_input_element_type(%ar
 spirv.ARM.Graph @conv3d_accumulator_must_be_either_FP16_or_FP32_for_f16_input_element_type(%arg0: !spirv.arm.tensor<1x34x18x27x1xf16>, %arg1: !spirv.arm.tensor<11x1x1x27x1xf16>, %arg2: !spirv.arm.tensor<11xf16>) -> (!spirv.arm.tensor<1x34x18x11x1xf16>) {
   %5 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
   %6 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
-  // expected-error @+1 {{op accumulator type for f16 tensorARM is not f16 or f32}}
+  // expected-error @+1 {{op failed to verify that acc_type must be one in [FP16,FP32] when type has value 16-bit float}}
   %7 = spirv.Tosa.Conv3D pad = [0, 0, 0, 0, 0, 0], stride = [1, 1, 1], dilation = [1, 1, 1], acc_type = <INT32>, local_bound = true, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x34x18x27x1xf16>, !spirv.arm.tensor<11x1x1x27x1xf16>, !spirv.arm.tensor<11xf16>, !spirv.arm.tensor<1xf16>, !spirv.arm.tensor<1xf16> -> !spirv.arm.tensor<1x34x18x11x1xf16>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x34x18x11x1xf16>
 }
@@ -186,7 +186,7 @@ spirv.ARM.Graph @conv3d_accumulator_must_be_either_FP16_or_FP32_for_f16_input_el
 spirv.ARM.Graph @conv3d_accumulator_must_be_either_FP32_for_f32_input_element_type(%arg0: !spirv.arm.tensor<1x34x18x27x1xf32>, %arg1: !spirv.arm.tensor<11x1x1x27x1xf32>, %arg2: !spirv.arm.tensor<11xf32>) -> (!spirv.arm.tensor<1x34x18x11x1xf32>) {
   %5 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
   %6 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
-  // expected-error @+1 {{op accumulator type for f32 tensorARM is not f32}}
+  // expected-error @+1 {{op failed to verify that acc_type must be one in [FP32] when type has value 32-bit float}}
   %7 = spirv.Tosa.Conv3D pad = [0, 0, 0, 0, 0, 0], stride = [1, 1, 1], dilation = [1, 1, 1], acc_type = <FP16>, local_bound = true, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x34x18x27x1xf32>, !spirv.arm.tensor<11x1x1x27x1xf32>, !spirv.arm.tensor<11xf32>, !spirv.arm.tensor<1xf32>, !spirv.arm.tensor<1xf32> -> !spirv.arm.tensor<1x34x18x11x1xf32>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x34x18x11x1xf32>
 }
@@ -198,7 +198,7 @@ spirv.ARM.Graph @conv3d_accumulator_must_be_either_FP32_for_f32_input_element_ty
 spirv.ARM.Graph @depthwise_conv2d_wrong_input_integer_element_type(%arg0: !spirv.arm.tensor<1x65535x3x1xi32>, %arg1: !spirv.arm.tensor<7x1x1x1xi32>, %arg2: !spirv.arm.tensor<1xi64>) -> (!spirv.arm.tensor<1x65536x2x7xi64>) {
   %5 = spirv.Constant dense<35> : !spirv.arm.tensor<1xi32>
   %6 = spirv.Constant dense<57> : !spirv.arm.tensor<1xi32>
-  // expected-error @+1 {{op input element type can only be of width 8 or 16 when integer type}}
+  // expected-error @+1 {{op failed to verify that if input has type integer then input must have a type in [8-bit signless integer,16-bit signless integer]}}
   %7 = spirv.Tosa.DepthwiseConv2D pad = [1, 0, 0, 0], stride = [1, 2], dilation = [7, 1], acc_type = <INT32>, local_bound = false, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x65535x3x1xi32>, !spirv.arm.tensor<7x1x1x1xi32>, !spirv.arm.tensor<1xi64>, !spirv.arm.tensor<1xi32>, !spirv.arm.tensor<1xi32> -> !spirv.arm.tensor<1x65536x2x7xi64>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65536x2x7xi64>
 }
@@ -206,7 +206,7 @@ spirv.ARM.Graph @depthwise_conv2d_wrong_input_integer_element_type(%arg0: !spirv
 spirv.ARM.Graph @depthwise_conv2d_mismatch_result_element_type_i8_input(%arg0: !spirv.arm.tensor<1x65535x3x1xi8>, %arg1: !spirv.arm.tensor<7x1x1x1xi8>, %arg2: !spirv.arm.tensor<1xi16>) -> (!spirv.arm.tensor<1x65536x2x7xi16>) {
   %5 = spirv.Constant dense<35> : !spirv.arm.tensor<1xi8>
   %6 = spirv.Constant dense<57> : !spirv.arm.tensor<1xi8>
-  // expected-error @+1 {{op expect result type to be i32, got 'i16'}}
+  // expected-error @+1 {{op failed to verify that if input has type 8-bit signless integer then output must have a type in [32-bit signless integer]}}
   %7 = spirv.Tosa.DepthwiseConv2D pad = [1, 0, 0, 0], stride = [1, 2], dilation = [7, 1], acc_type = <INT32>, local_bound = false, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x65535x3x1xi8>, !spirv.arm.tensor<7x1x1x1xi8>, !spirv.arm.tensor<1xi16>, !spirv.arm.tensor<1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<1x65536x2x7xi16>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65536x2x7xi16>
 }
@@ -214,7 +214,7 @@ spirv.ARM.Graph @depthwise_conv2d_mismatch_result_element_type_i8_input(%arg0: !
 spirv.ARM.Graph @depthwise_conv2d_mismatch_result_element_type_i16_input(%arg0: !spirv.arm.tensor<1x65535x3x1xi16>, %arg1: !spirv.arm.tensor<7x1x1x1xi16>, %arg2: !spirv.arm.tensor<1xi32>) -> (!spirv.arm.tensor<1x65536x2x7xi32>) {
   %5 = spirv.Constant dense<35> : !spirv.arm.tensor<1xi16>
   %6 = spirv.Constant dense<57> : !spirv.arm.tensor<1xi16>
-  // expected-error @+1 {{op expect result type to be i64, got 'i32'}}
+  // expected-error @+1 {{op failed to verify that if input has type 16-bit signless integer then output must have a type in [64-bit signless integer]}}
   %7 = spirv.Tosa.DepthwiseConv2D pad = [1, 0, 0, 0], stride = [1, 2], dilation = [7, 1], acc_type = <INT32>, local_bound = false, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x65535x3x1xi16>, !spirv.arm.tensor<7x1x1x1xi16>, !spirv.arm.tensor<1xi32>, !spirv.arm.tensor<1xi16>, !spirv.arm.tensor<1xi16> -> !spirv.arm.tensor<1x65536x2x7xi32>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65536x2x7xi32>
 }
@@ -222,7 +222,7 @@ spirv.ARM.Graph @depthwise_conv2d_mismatch_result_element_type_i16_input(%arg0:
 spirv.ARM.Graph @depthwise_conv2d_mismatch_result_element_type_f16_input(%arg0: !spirv.arm.tensor<1x34x18x27xf16>, %arg1: !spirv.arm.tensor<11x1x1x27xf16>, %arg2: !spirv.arm.tensor<11xf32>) -> (!spirv.arm.tensor<1x34x18x11xf32>) {
   %5 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
   %6 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
-  // expected-error @+1 {{op expect result type to be f16, got 'f32'}}
+  // expected-error @+1 {{op failed to verify that if input has type 16-bit float then output must have a type in [16-bit float]}}
   %7 = spirv.Tosa.DepthwiseConv2D pad = [0, 0, 0, 0], stride = [1, 1], dilation = [1, 1], acc_type = <FP16>, local_bound = true, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x34x18x27xf16>, !spirv.arm.tensor<11x1x1x27xf16>, !spirv.arm.tensor<11xf32>, !spirv.arm.tensor<1xf16>, !spirv.arm.tensor<1xf16> -> !spirv.arm.tensor<1x34x18x11xf32>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x34x18x11xf32>
 }
@@ -230,7 +230,7 @@ spirv.ARM.Graph @depthwise_conv2d_mismatch_result_element_type_f16_input(%arg0:
 spirv.ARM.Graph @depthwise_conv2d_mismatch_result_element_type_f32_input(%arg0: !spirv.arm.tensor<1x34x18x27xf32>, %arg1: !spirv.arm.tensor<11x1x1x27xf32>, %arg2: !spirv.arm.tensor<11xf16>) -> (!spirv.arm.tensor<1x34x18x11xf16>) {
   %5 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
   %6 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
-  // expected-error @+1 {{op expect result type to be f32, got 'f16'}}
+  // expected-error @+1 {{op failed to verify that if input has type 32-bit float then output must have a type in [32-bit float]}}
   %7 = spirv.Tosa.DepthwiseConv2D pad = [0, 0, 0, 0], stride = [1, 1], dilation = [1, 1], acc_type = <FP16>, local_bound = true, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x34x18x27xf32>, !spirv.arm.tensor<11x1x1x27xf32>, !spirv.arm.tensor<11xf16>, !spirv.arm.tensor<1xf32>, !spirv.arm.tensor<1xf32> -> !spirv.arm.tensor<1x34x18x11xf16>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x34x18x11xf16>
 }
@@ -246,7 +246,7 @@ spirv.ARM.Graph @depthwise_conv2d_bias_element_type_must_be_same_as_result_eleme
 spirv.ARM.Graph @depthwise_conv2d_accumulator_must_be_INT32_for_i8_input_element_type(%arg0: !spirv.arm.tensor<1x65535x3x1xi8>, %arg1: !spirv.arm.tensor<7x1x1x1xi8>, %arg2: !spirv.arm.tensor<1xi32>) -> (!spirv.arm.tensor<1x65536x2x7xi32>) {
   %5 = spirv.Constant dense<35> : !spirv.arm.tensor<1xi8>
   %6 = spirv.Constant dense<57> : !spirv.arm.tensor<1xi8>
-  // expected-error @+1 {{op accumulator type for i8 tensorARM is not i32}}
+  // expected-error @+1 {{op failed to verify that acc_type must be one in [INT32] when type has value 8-bit signless integer}}
   %7 = spirv.Tosa.DepthwiseConv2D pad = [1, 0, 0, 0], stride = [1, 2], dilation = [7, 1], acc_type = <INT48>, local_bound = false, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x65535x3x1xi8>, !spirv.arm.tensor<7x1x1x1xi8>, !spirv.arm.tensor<1xi32>, !spirv.arm.tensor<1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<1x65536x2x7xi32>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65536x2x7xi32>
 }
@@ -254,7 +254,7 @@ spirv.ARM.Graph @depthwise_conv2d_accumulator_must_be_INT32_for_i8_input_element
 spirv.ARM.Graph @depthwise_conv2d_accumulator_must_be_INT48_for_i16_input_element_type(%arg0: !spirv.arm.tensor<1x65535x3x1xi16>, %arg1: !spirv.arm.tensor<7x1x1x1xi16>, %arg2: !spirv.arm.tensor<1xi64>) -> (!spirv.arm.tensor<1x65536x2x7xi64>) {
   %5 = spirv.Constant dense<35> : !spirv.arm.tensor<1xi16>
   %6 = spirv.Constant dense<57> : !spirv.arm.tensor<1xi16>
-  // expected-error @+1 {{op accumulator type for i16 tensorARM is not i48}}
+  // expected-error @+1 {{op failed to verify that acc_type must be one in [INT48] when type has value 16-bit signless integer}}
   %7 = spirv.Tosa.DepthwiseConv2D pad = [1, 0, 0, 0], stride = [1, 2], dilation = [7, 1], acc_type = <INT32>, local_bound = false, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x65535x3x1xi16>, !spirv.arm.tensor<7x1x1x1xi16>, !spirv.arm.tensor<1xi64>, !spirv.arm.tensor<1xi16>, !spirv.arm.tensor<1xi16> -> !spirv.arm.tensor<1x65536x2x7xi64>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65536x2x7xi64>
 }
@@ -262,7 +262,7 @@ spirv.ARM.Graph @depthwise_conv2d_accumulator_must_be_INT48_for_i16_input_elemen
 spirv.ARM.Graph @depthwise_conv2d_accumulator_must_be_either_FP16_or_FP32_for_f16_input_element_type(%arg0: !spirv.arm.tensor<1x34x18x27xf16>, %arg1: !spirv.arm.tensor<11x1x1x27xf16>, %arg2: !spirv.arm.tensor<11xf16>) -> (!spirv.arm.tensor<1x34x18x11xf16>) {
   %5 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
   %6 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
-  // expected-error @+1 {{op accumulator type for f16 tensorARM is not f16 or f32}}
+  // expected-error @+1 {{op failed to verify that acc_type must be one in [FP16,FP32] when type has value 16-bit float}}
   %7 = spirv.Tosa.DepthwiseConv2D pad = [0, 0, 0, 0], stride = [1, 1], dilation = [1, 1], acc_type = <INT32>, local_bound = true, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x34x18x27xf16>, !spirv.arm.tensor<11x1x1x27xf16>, !spirv.arm.tensor<11xf16>, !spirv.arm.tensor<1xf16>, !spirv.arm.tensor<1xf16> -> !spirv.arm.tensor<1x34x18x11xf16>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x34x18x11xf16>
 }
@@ -270,7 +270,7 @@ spirv.ARM.Graph @depthwise_conv2d_accumulator_must_be_either_FP16_or_FP32_for_f1
 spirv.ARM.Graph @depthwise_conv2d_accumulator_must_be_either_FP32_for_f32_input_element_type(%arg0: !spirv.arm.tensor<1x34x18x27xf32>, %arg1: !spirv.arm.tensor<11x1x1x27xf32>, %arg2: !spirv.arm.tensor<11xf32>) -> (!spirv.arm.tensor<1x34x18x11xf32>) {
   %5 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
   %6 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
-  // expected-error @+1 {{op accumulator type for f32 tensorARM is not f32}}
+  // expected-error @+1 {{op failed to verify that acc_type must be one in [FP32] when type has value 32-bit float}}
   %7 = spirv.Tosa.DepthwiseConv2D pad = [0, 0, 0, 0], stride = [1, 1], dilation = [1, 1], acc_type = <FP16>, local_bound = true, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x34x18x27xf32>, !spirv.arm.tensor<11x1x1x27xf32>, !spirv.arm.tensor<11xf32>, !spirv.arm.tensor<1xf32>, !spirv.arm.tensor<1xf32> -> !spirv.arm.tensor<1x34x18x11xf32>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x34x18x11xf32>
 }
@@ -282,7 +282,7 @@ spirv.ARM.Graph @depthwise_conv2d_accumulator_must_be_either_FP32_for_f32_input_
 spirv.ARM.Graph @transpose_conv2d_wrong_input_integer_element_type(%arg0: !spirv.arm.tensor<1x65535x3x1xi32>, %arg1: !spirv.arm.tensor<7x1x1x1xi32>, %arg2: !spirv.arm.tensor<1xi64>) -> (!spirv.arm.tensor<1x65536x2x7xi64>) {
   %5 = spirv.Constant dense<35> : !spirv.arm.tensor<1xi32>
   %6 = spirv.Constant dense<57> : !spirv.arm.tensor<1xi32>
-  // expected-error @+1 {{op input element type can only be of width 8 or 16 when integer type}}
+  // expected-error @+1 {{op failed to verify that if input has type integer then input must have a type in [8-bit signless integer,16-bit signless integer]}}
   %7 = spirv.Tosa.TransposeConv2D out_pad = [1, 0, 0, 0], stride = [1, 2], acc_type = <INT32>, local_bound = false, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x65535x3x1xi32>, !spirv.arm.tensor<7x1x1x1xi32>, !spirv.arm.tensor<1xi64>, !spirv.arm.tensor<1xi32>, !spirv.arm.tensor<1xi32> -> !spirv.arm.tensor<1x65536x2x7xi64>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65536x2x7xi64>
 }
@@ -290,7 +290,7 @@ spirv.ARM.Graph @transpose_conv2d_wrong_input_integer_element_type(%arg0: !spirv
 spirv.ARM.Graph @transpose_conv2d_mismatch_result_element_type_i8_input(%arg0: !spirv.arm.tensor<1x65535x3x1xi8>, %arg1: !spirv.arm.tensor<7x1x1x1xi8>, %arg2: !spirv.arm.tensor<1xi16>) -> (!spirv.arm.tensor<1x65536x2x7xi16>) {
   %5 = spirv.Constant dense<35> : !spirv.arm.tensor<1xi8>
   %6 = spirv.Constant dense<57> : !spirv.arm.tensor<1xi8>
-  // expected-error @+1 {{op expect result type to be i32, got 'i16'}}
+  // expected-error @+1 {{op failed to verify that if input has type 8-bit signless integer then output must have a type in [32-bit signless integer]}}
   %7 = spirv.Tosa.TransposeConv2D out_pad = [1, 0, 0, 0], stride = [1, 2], acc_type = <INT32>, local_bound = false, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x65535x3x1xi8>, !spirv.arm.tensor<7x1x1x1xi8>, !spirv.arm.tensor<1xi16>, !spirv.arm.tensor<1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<1x65536x2x7xi16>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65536x2x7xi16>
 }
@@ -298,7 +298,7 @@ spirv.ARM.Graph @transpose_conv2d_mismatch_result_element_type_i8_input(%arg0: !
 spirv.ARM.Graph @transpose_conv2d_mismatch_result_element_type_i16_input(%arg0: !spirv.arm.tensor<1x65535x3x1xi16>, %arg1: !spirv.arm.tensor<7x1x1x1xi16>, %arg2: !spirv.arm.tensor<1xi32>) -> (!spirv.arm.tensor<1x65536x2x7xi32>) {
   %5 = spirv.Constant dense<35> : !spirv.arm.tensor<1xi16>
   %6 = spirv.Constant dense<57> : !spirv.arm.tensor<1xi16>
-  // expected-error @+1 {{op expect result type to be i64, got 'i32'}}
+  // expected-error @+1 {{op failed to verify that if input has type 16-bit signless integer then output must have a type in [64-bit signless integer]}}
   %7 = spirv.Tosa.TransposeConv2D out_pad = [1, 0, 0, 0], stride = [1, 2], acc_type = <INT32>, local_bound = false, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x65535x3x1xi16>, !spirv.arm.tensor<7x1x1x1xi16>, !spirv.arm.tensor<1xi32>, !spirv.arm.tensor<1xi16>, !spirv.arm.tensor<1xi16> -> !spirv.arm.tensor<1x65536x2x7xi32>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65536x2x7xi32>
 }
@@ -306,7 +306,7 @@ spirv.ARM.Graph @transpose_conv2d_mismatch_result_element_type_i16_input(%arg0:
 spirv.ARM.Graph @transpose_conv2d_mismatch_result_element_type_f16_input(%arg0: !spirv.arm.tensor<1x34x18x27xf16>, %arg1: !spirv.arm.tensor<11x1x1x27xf16>, %arg2: !spirv.arm.tensor<11xf32>) -> (!spirv.arm.tensor<1x34x18x11xf32>) {
   %5 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
   %6 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
-  // expected-error @+1 {{op expect result type to be f16, got 'f32'}}
+  // expected-error @+1 {{op failed to verify that if input has type 16-bit float then output must have a type in [16-bit float]}}
   %7 = spirv.Tosa.TransposeConv2D out_pad = [0, 0, 0, 0], stride = [1, 1], acc_type = <FP16>, local_bound = true, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x34x18x27xf16>, !spirv.arm.tensor<11x1x1x27xf16>, !spirv.arm.tensor<11xf32>, !spirv.arm.tensor<1xf16>, !spirv.arm.tensor<1xf16> -> !spirv.arm.tensor<1x34x18x11xf32>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x34x18x11xf32>
 }
@@ -314,7 +314,7 @@ spirv.ARM.Graph @transpose_conv2d_mismatch_result_element_type_f16_input(%arg0:
 spirv.ARM.Graph @transpose_conv2d_mismatch_result_element_type_f32_input(%arg0: !spirv.arm.tensor<1x34x18x27xf32>, %arg1: !spirv.arm.tensor<11x1x1x27xf32>, %arg2: !spirv.arm.tensor<11xf16>) -> (!spirv.arm.tensor<1x34x18x11xf16>) {
   %5 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
   %6 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
-  // expected-error @+1 {{op expect result type to be f32, got 'f16'}}
+  // expected-error @+1 {{op failed to verify that if input has type 32-bit float then output must have a type in [32-bit float]}}
   %7 = spirv.Tosa.TransposeConv2D out_pad = [0, 0, 0, 0], stride = [1, 1], acc_type = <FP16>, local_bound = true, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x34x18x27xf32>, !spirv.arm.tensor<11x1x1x27xf32>, !spirv.arm.tensor<11xf16>, !spirv.arm.tensor<1xf32>, !spirv.arm.tensor<1xf32> -> !spirv.arm.tensor<1x34x18x11xf16>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x34x18x11xf16>
 }
@@ -330,7 +330,7 @@ spirv.ARM.Graph @transpose_conv2d_bias_element_type_must_be_same_as_result_eleme
 spirv.ARM.Graph @transpose_conv2d_accumulator_must_be_INT32_for_i8_input_element_type(%arg0: !spirv.arm.tensor<1x65535x3x1xi8>, %arg1: !spirv.arm.tensor<7x1x1x1xi8>, %arg2: !spirv.arm.tensor<1xi32>) -> (!spirv.arm.tensor<1x65536x2x7xi32>) {
   %5 = spirv.Constant dense<35> : !spirv.arm.tensor<1xi8>
   %6 = spirv.Constant dense<57> : !spirv.arm.tensor<1xi8>
-  // expected-error @+1 {{op accumulator type for i8 tensorARM is not i32}}
+  // expected-error @+1 {{op failed to verify that acc_type must be one in [INT32] when type has value 8-bit signless integer}}
   %7 = spirv.Tosa.TransposeConv2D out_pad = [1, 0, 0, 0], stride = [1, 2], acc_type = <INT48>, local_bound = false, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x65535x3x1xi8>, !spirv.arm.tensor<7x1x1x1xi8>, !spirv.arm.tensor<1xi32>, !spirv.arm.tensor<1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<1x65536x2x7xi32>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65536x2x7xi32>
 }
@@ -338,7 +338,7 @@ spirv.ARM.Graph @transpose_conv2d_accumulator_must_be_INT32_for_i8_input_element
 spirv.ARM.Graph @transpose_conv2d_accumulator_must_be_INT48_for_i16_input_element_type(%arg0: !spirv.arm.tensor<1x65535x3x1xi16>, %arg1: !spirv.arm.tensor<7x1x1x1xi16>, %arg2: !spirv.arm.tensor<1xi64>) -> (!spirv.arm.tensor<1x65536x2x7xi64>) {
   %5 = spirv.Constant dense<35> : !spirv.arm.tensor<1xi16>
   %6 = spirv.Constant dense<57> : !spirv.arm.tensor<1xi16>
-  // expected-error @+1 {{op accumulator type for i16 tensorARM is not i48}}
+  // expected-error @+1 {{op failed to verify that acc_type must be one in [INT48] when type has value 16-bit signless integer}}
   %7 = spirv.Tosa.TransposeConv2D out_pad = [1, 0, 0, 0], stride = [1, 2], acc_type = <INT32>, local_bound = false, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x65535x3x1xi16>, !spirv.arm.tensor<7x1x1x1xi16>, !spirv.arm.tensor<1xi64>, !spirv.arm.tensor<1xi16>, !spirv.arm.tensor<1xi16> -> !spirv.arm.tensor<1x65536x2x7xi64>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65536x2x7xi64>
 }
@@ -346,7 +346,7 @@ spirv.ARM.Graph @transpose_conv2d_accumulator_must_be_INT48_for_i16_input_elemen
 spirv.ARM.Graph @transpose_conv2d_accumulator_must_be_either_FP16_or_FP32_for_f16_input_element_type(%arg0: !spirv.arm.tensor<1x34x18x27xf16>, %arg1: !spirv.arm.tensor<11x1x1x27xf16>, %arg2: !spirv.arm.tensor<11xf16>) -> (!spirv.arm.tensor<1x34x18x11xf16>) {
   %5 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
   %6 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
-  // expected-error @+1 {{op accumulator type for f16 tensorARM is not f16 or f32}}
+  // expected-error @+1 {{op failed to verify that acc_type must be one in [FP16,FP32] when type has value 16-bit float}}
   %7 = spirv.Tosa.TransposeConv2D out_pad = [0, 0, 0, 0], stride = [1, 1], acc_type = <INT32>, local_bound = true, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x34x18x27xf16>, !spirv.arm.tensor<11x1x1x27xf16>, !spirv.arm.tensor<11xf16>, !spirv.arm.tensor<1xf16>, !spirv.arm.tensor<1xf16> -> !spirv.arm.tensor<1x34x18x11xf16>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x34x18x11xf16>
 }
@@ -354,7 +354,64 @@ spirv.ARM.Graph @transpose_conv2d_accumulator_must_be_either_FP16_or_FP32_for_f1
 spirv.ARM.Graph @transpose_conv2d_accumulator_must_be_either_FP32_for_f32_input_element_type(%arg0: !spirv.arm.tensor<1x34x18x27xf32>, %arg1: !spirv.arm.tensor<11x1x1x27xf32>, %arg2: !spirv.arm.tensor<11xf32>) -> (!spirv.arm.tensor<1x34x18x11xf32>) {
   %5 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
   %6 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
-  // expected-error @+1 {{op accumulator type for f32 tensorARM is not f32}}
+  // expected-error @+1 {{op failed to verify that acc_type must be one in [FP32] when type has value 32-bit float}}
   %7 = spirv.Tosa.TransposeConv2D out_pad = [0, 0, 0, 0], stride = [1, 1], acc_type = <FP16>, local_bound = true, %arg0, %arg1, %arg2, %5, %6 : !spirv.arm.tensor<1x34x18x27xf32>, !spirv.arm.tensor<11x1x1x27xf32>, !spirv.arm.tensor<11xf32>, !spirv.arm.tensor<1xf32>, !spirv.arm.tensor<1xf32> -> !spirv.arm.tensor<1x34x18x11xf32>
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x34x18x11xf32>
 }
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.AvgPool2D
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @avgpool2d_input_output_different_type(%arg0: !spirv.arm.tensor<1x3x65537x1xi8>) -> (!spirv.arm.tensor<1x2x32768x1xi16>) {
+  %4 = spirv.Constant dense<125> : !spirv.arm.tensor<1xi8>
+  %5 = spirv.Constant dense<-90> : !spirv.arm.tensor<1xi8>
+  // expected-error @+1 {{op failed to verify that all of {input, input_zp, output, output_zp} have same element type}}
+  %6 = spirv.Tosa.AvgPool2D kernel = [3, 3], stride = [1, 2], pad = [0, 1, 0, 0], acc_type = <INT32>, %arg0, %4, %5 : !spirv.arm.tensor<1x3x65537x1xi8>, !spirv.arm.tensor<1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<1x2x32768x1xi16>
+  spirv.ARM.GraphOutputs %6 : !spirv.arm.tensor<1x2x32768x1xi16>
+}
+
+spirv.ARM.Graph @avgpool2d_accumulator_should_be_INT32_for_integer_element_types(%arg0: !spirv.arm.tensor<1x3x65537x1xi8>) -> (!spirv.arm.tensor<1x2x32768x1xi8>) {
+  %4 = spirv.Constant dense<125> : !spirv.arm.tensor<1xi8>
+  %5 = spirv.Constant dense<-90> : !spirv.arm.tensor<1xi8>
+  // expected-error @+1 {{op failed to verify that acc_type must be one in [INT32] when type has value 8-bit signless integer}}
+  %6 = spirv.Tosa.AvgPool2D kernel = [3, 3], stride = [1, 2], pad = [0, 1, 0, 0], acc_type = <INT48>, %arg0, %4, %5 : !spirv.arm.tensor<1x3x65537x1xi8>, !spirv.arm.tensor<1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<1x2x32768x1xi8>
+  spirv.ARM.GraphOutputs %6 : !spirv.arm.tensor<1x2x32768x1xi8>
+}
+
+spirv.ARM.Graph @avgpool2d_accumulator_should_be_either_FP16_or_FP32_for_fp16_element_types(%arg0: !spirv.arm.tensor<1x2x65533x2xf16>) -> (!spirv.arm.tensor<1x2x65532x2xf16>) {
+  %4 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
+  %5 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
+  // expected-error @+1 {{op failed to verify that acc_type must be one in [FP16,FP32] when type has value 16-bit float}}
+  %6 = spirv.Tosa.AvgPool2D kernel = [2, 2], stride = [1, 1], pad = [1, 0, 0, 0], acc_type = <INT32>, %arg0, %4, %5 : !spirv.arm.tensor<1x2x65533x2xf16>, !spirv.arm.tensor<1xf16>, !spirv.arm.tensor<1xf16> -> !spirv.arm.tensor<1x2x65532x2xf16>
+  spirv.ARM.GraphOutputs %6 : !spirv.arm.tensor<1x2x65532x2xf16>
+}
+
+
+spirv.ARM.Graph @avgpool2d_accumulator_should_be_either_FP32_for_fp32_element_types(%arg0: !spirv.arm.tensor<1x2x65533x2xf32>) -> (!spirv.arm.tensor<1x2x65532x2xf32>) {
+  %4 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
+  %5 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
+  // expected-error @+1 {{op failed to verify that acc_type must be one in [FP32] when type has value 32-bit float}}
+  %6 = spirv.Tosa.AvgPool2D kernel = [2, 2], stride = [1, 1], pad = [1, 0, 0, 0], acc_type = <FP16>, %arg0, %4, %5 : !spirv.arm.tensor<1x2x65533x2xf32>, !spirv.arm.tensor<1xf32>, !spirv.arm.tensor<1xf32> -> !spirv.arm.tensor<1x2x65532x2xf32>
+  spirv.ARM.GraphOutputs %6 : !spirv.arm.tensor<1x2x65532x2xf32>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.MatMul
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @matmul_invalid_input_output_element_type_combination(%arg0: !spirv.arm.tensor<1x4x4xi16>, %arg1: !spirv.arm.tensor<1x4x4xi16>, %arg2: !spirv.arm.tensor<1xi16>, %arg3: !spirv.arm.tensor<1xi16>) -> (!spirv.arm.tensor<1x4x4xi32>) {
+  // expected-error @+1 {{op failed to verify that if A has type 16-bit signless integer then output must have a type in [64-bit signless integer]}}
+  %0 = spirv.Tosa.MatMul %arg0, %arg1, %arg2, %arg3 : !spirv.arm.tensor<1x4x4xi16>, !spirv.arm.tensor<1x4x4xi16>, !spirv.arm.tensor<1xi16>, !spirv.arm.tensor<1xi16> -> !spirv.arm.tensor<1x4x4xi32>
+  spirv.ARM.GraphOutputs %0 : !spirv.arm.tensor<1x4x4xi32>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.MaxPool2D
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @maxpool2d_int(%arg0: !spirv.arm.tensor<1x3x65537x1xi8>) -> (!spirv.arm.tensor<1x2x32769x1xi16>) {
+  // expected-error @+1 {{op failed to verify that all of {input, output} have same element type}}
+  %4 = spirv.Tosa.MaxPool2D kernel = [3, 2], stride = [1, 2], pad = [1, 0, 0, 1], nan_mode = <Propagate>, %arg0 : !spirv.arm.tensor<1x3x65537x1xi8> -> !spirv.arm.tensor<1x2x32769x1xi16>
+  spirv.ARM.GraphOutputs %4 : !spirv.arm.tensor<1x2x32769x1xi16>
+}
diff --git a/mlir/test/Dialect/SPIRV/IR/tosa-ops.mlir b/mlir/test/Dialect/SPIRV/IR/tosa-ops.mlir
index 45243a7553c56..1a43e2c95c530 100644
--- a/mlir/test/Dialect/SPIRV/IR/tosa-ops.mlir
+++ b/mlir/test/Dialect/SPIRV/IR/tosa-ops.mlir
@@ -22,6 +22,32 @@ spirv.ARM.Graph @argmax_fp(%arg0: !spirv.arm.tensor<2x2x7x14xf32>) -> (!spirv.ar
   spirv.ARM.GraphOutputs %2 : !spirv.arm.tensor<2x2x14xi32>
 }
 
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.AvgPool2D - PRO-INT
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @avgpool2d_int(%arg0: !spirv.arm.tensor<1x3x65537x1xi8>) -> (!spirv.arm.tensor<1x2x32768x1xi8>) {
+  %4 = spirv.Constant dense<125> : !spirv.arm.tensor<1xi8>
+  %5 = spirv.Constant dense<-90> : !spirv.arm.tensor<1xi8>
+  // CHECK: {{%.*}} = spirv.Tosa.AvgPool2D kernel = [3, 3], stride = [1, 2], pad = [0, 1, 0, 0], acc_type = <INT32>, %arg0, {{%.*}}, {{%.*}} : !spirv.arm.tensor<1x3x65537x1xi8>, !spirv.arm.tensor<1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<1x2x32768x1xi8>
+  %6 = spirv.Tosa.AvgPool2D kernel = [3, 3], stride = [1, 2], pad = [0, 1, 0, 0], acc_type = <INT32>, %arg0, %4, %5 : !spirv.arm.tensor<1x3x65537x1xi8>, !spirv.arm.tensor<1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<1x2x32768x1xi8>
+  // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<1x2x32768x1xi8>
+  spirv.ARM.GraphOutputs %6 : !spirv.arm.tensor<1x2x32768x1xi8>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.AvgPool2D - PRO-FP
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @avgpool2d_fp(%arg0: !spirv.arm.tensor<1x2x65533x2xf32>) -> (!spirv.arm.tensor<1x2x65532x2xf32>) {
+  %4 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
+  %5 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
+  // CHECK: {{%.*}} = spirv.Tosa.AvgPool2D kernel = [2, 2], stride = [1, 1], pad = [1, 0, 0, 0], acc_type = <FP32>, %arg0, {{%.*}}, {{%.*}} : !spirv.arm.tensor<1x2x65533x2xf32>, !spirv.arm.tensor<1xf32>, !spirv.arm.tensor<1xf32> -> !spirv.arm.tensor<1x2x65532x2xf32>
+  %6 = spirv.Tosa.AvgPool2D kernel = [2, 2], stride = [1, 1], pad = [1, 0, 0, 0], acc_type = <FP32>, %arg0, %4, %5 : !spirv.arm.tensor<1x2x65533x2xf32>, !spirv.arm.tensor<1xf32>, !spirv.arm.tensor<1xf32> -> !spirv.arm.tensor<1x2x65532x2xf32>
+  // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<1x2x65532x2xf32>
+  spirv.ARM.GraphOutputs %6 : !spirv.arm.tensor<1x2x65532x2xf32>
+}
+
 //===----------------------------------------------------------------------===//
 // spirv.TOSA.Conv2D - PRO-INT
 //===----------------------------------------------------------------------===//
@@ -100,6 +126,84 @@ spirv.ARM.Graph @depthwiseconv2d_fp(%arg0: !spirv.arm.tensor<1x65540x1x3xf32>, %
   spirv.ARM.GraphOutputs %7 : !spirv.arm.tensor<1x65541x2x3xf32>
 }
 
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.FFT2D - EXT-FFT
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @fft2d_fft(%arg0: !spirv.arm.tensor<1x32x32xf32>, %arg1: !spirv.arm.tensor<1x32x32xf32>) -> (!spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>) {
+  // CHECK: {{%.*}} = spirv.Tosa.FFT2D inverse = true, local_bound = false, %arg0, %arg1 : !spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32> -> !spirv.struct<(!spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>)>
+  %out = spirv.Tosa.FFT2D inverse = true, local_bound = false, %arg0, %arg1 : !spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32> -> !spirv.struct<(!spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>)>
+  // CHECK: {{%.*}} = spirv.CompositeExtract {{%.*}}[0 : i32] : !spirv.struct<(!spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>)>
+  %out0 = spirv.CompositeExtract %out[0 : i32] : !spirv.struct<(!spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>)>
+  // CHECK: {{%.*}} = spirv.CompositeExtract {{%.*}}[1 : i32] :  !spirv.struct<(!spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>)>
+  %out1 = spirv.CompositeExtract %out[1 : i32] : !spirv.struct<(!spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>)>
+  // CHECK: spirv.ARM.GraphOutputs {{%.*}}, {{%.*}} : !spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>
+  spirv.ARM.GraphOutputs  %out0, %out1 : !spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.MatMul - PRO-INT
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @matmul_int(%arg0: !spirv.arm.tensor<8x2x3xi8>, %arg1: !spirv.arm.tensor<8x3x8xi8>) -> (!spirv.arm.tensor<8x2x8xi32>) {
+  %0 = spirv.Constant dense<0> : !spirv.arm.tensor<1xi8>
+  %1 = spirv.Constant dense<0> : !spirv.arm.tensor<1xi8>
+  // CHECK: {{%.*}} = spirv.Tosa.MatMul %arg0, %arg1, {{%.*}}, {{%.*}} : !spirv.arm.tensor<8x2x3xi8>, !spirv.arm.tensor<8x3x8xi8>, !spirv.arm.tensor<1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<8x2x8xi32>
+  %2 = spirv.Tosa.MatMul %arg0, %arg1, %0, %1 : !spirv.arm.tensor<8x2x3xi8>, !spirv.arm.tensor<8x3x8xi8>, !spirv.arm.tensor<1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<8x2x8xi32>
+  // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<8x2x8xi32>
+  spirv.ARM.GraphOutputs %2 : !spirv.arm.tensor<8x2x8xi32>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.MatMul - PRO-FP
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @matmul_fp(%arg0: !spirv.arm.tensor<15x39x50xf16>, %arg1: !spirv.arm.tensor<15x50x24xf16>) -> (!spirv.arm.tensor<15x39x24xf16>) {
+  %0 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
+  %1 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
+  // CHECK: {{%.*}} = spirv.Tosa.MatMul %arg0, %arg1, {{%.*}}, {{%.*}} : !spirv.arm.tensor<15x39x50xf16>, !spirv.arm.tensor<15x50x24xf16>, !spirv.arm.tensor<1xf16>, !spirv.arm.tensor<1xf16> -> !spirv.arm.tensor<15x39x24xf16>
+  %2 = spirv.Tosa.MatMul %arg0, %arg1, %0, %1 : !spirv.arm.tensor<15x39x50xf16>, !spirv.arm.tensor<15x50x24xf16>, !spirv.arm.tensor<1xf16>, !spirv.arm.tensor<1xf16> -> !spirv.arm.tensor<15x39x24xf16>
+  // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<15x39x24xf16>
+  spirv.ARM.GraphOutputs %2 : !spirv.arm.tensor<15x39x24xf16>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.MaxPool2D - PRO-INT
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @maxpool2d_int(%arg0: !spirv.arm.tensor<1x3x65537x1xi8>) -> (!spirv.arm.tensor<1x2x32769x1xi8>) {
+  // CHECK: {{%.*}} = spirv.Tosa.MaxPool2D kernel = [3, 2], stride = [1, 2], pad = [1, 0, 0, 1], nan_mode = <Propagate>, %arg0 : !spirv.arm.tensor<1x3x65537x1xi8> -> !spirv.arm.tensor<1x2x32769x1xi8>
+  %4 = spirv.Tosa.MaxPool2D kernel = [3, 2], stride = [1, 2], pad = [1, 0, 0, 1], nan_mode = <Propagate>, %arg0 : !spirv.arm.tensor<1x3x65537x1xi8> -> !spirv.arm.tensor<1x2x32769x1xi8>
+  // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<1x2x32769x1xi8>
+  spirv.ARM.GraphOutputs %4 : !spirv.arm.tensor<1x2x32769x1xi8>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.MaxPool2D - PRO-FP
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @maxpool2d_fp(%arg0: !spirv.arm.tensor<1x6x65536x1xf32>) -> (!spirv.arm.tensor<1x3x32769x1xf32>) {
+  // CHECK: {{%.*}} = spirv.Tosa.MaxPool2D kernel = [3, 2], stride = [2, 2], pad = [1, 0, 1, 1], nan_mode = <Propagate>, %arg0 : !spirv.arm.tensor<1x6x65536x1xf32> -> !spirv.arm.tensor<1x3x32769x1xf32>
+  %4 = spirv.Tosa.MaxPool2D kernel = [3, 2], stride = [2, 2], pad = [1, 0, 1, 1], nan_mode = <Propagate>, %arg0 : !spirv.arm.tensor<1x6x65536x1xf32> -> !spirv.arm.tensor<1x3x32769x1xf32>
+  // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<1x3x32769x1xf32>
+  spirv.ARM.GraphOutputs %4 : !spirv.arm.tensor<1x3x32769x1xf32>
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.RFFT2D - EXT-FFT
+//===----------------------------------------------------------------------===//
+
+spirv.ARM.Graph @rfft2d_fft(%arg0: !spirv.arm.tensor<1x32x32xf32>) -> (!spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>) {
+  // CHECK: {{%.*}} = spirv.Tosa.RFFT2D local_bound = false, %arg0 : !spirv.arm.tensor<1x32x32xf32> -> !spirv.struct<(!spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>)>
+  %out = spirv.Tosa.RFFT2D local_bound = false, %arg0 : !spirv.arm.tensor<1x32x32xf32> -> !spirv.struct<(!spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>)>
+  // CHECK: {{%.*}} = spirv.CompositeExtract {{%.*}}[0 : i32] : !spirv.struct<(!spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>)>
+  %out0 = spirv.CompositeExtract %out[0 : i32] : !spirv.struct<(!spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>)>
+  // CHECK: {{%.*}} = spirv.CompositeExtract {{%.*}}[1 : i32] : !spirv.struct<(!spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>)>
+  %out1 = spirv.CompositeExtract %out[1 : i32] : !spirv.struct<(!spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>)>
+  // CHECK: spirv.ARM.GraphOutputs {{%.*}}, {{%.*}} : !spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>
+  spirv.ARM.GraphOutputs %out0, %out1 : !spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>
+}
+
 //===----------------------------------------------------------------------===//
 // spirv.TOSA.TransposeConv2D - PRO-INT
 //===----------------------------------------------------------------------===//
diff --git a/mlir/test/Target/SPIRV/tosa-ops.mlir b/mlir/test/Target/SPIRV/tosa-ops.mlir
index edaa000c183a8..1d219b855bec1 100644
--- a/mlir/test/Target/SPIRV/tosa-ops.mlir
+++ b/mlir/test/Target/SPIRV/tosa-ops.mlir
@@ -42,6 +42,48 @@ spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader
 
 // -----
 
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.AvgPool2D - 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 @avgpool2d_int_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<1x3x65537x1xi8>, UniformConstant>
+  spirv.GlobalVariable @avgpool2d_int_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<1x2x32768x1xi8>, UniformConstant>
+  spirv.ARM.GraphEntryPoint @avgpool2d_int, @avgpool2d_int_arg_0, @avgpool2d_int_res_0
+  spirv.ARM.Graph @avgpool2d_int(%arg0: !spirv.arm.tensor<1x3x65537x1xi8>) -> (!spirv.arm.tensor<1x2x32768x1xi8>) {
+    %4 = spirv.Constant dense<125> : !spirv.arm.tensor<1xi8>
+    %5 = spirv.Constant dense<-90> : !spirv.arm.tensor<1xi8>
+    // CHECK: {{%.*}} = spirv.Tosa.AvgPool2D kernel = [3, 3], stride = [1, 2], pad = [0, 1, 0, 0], acc_type = <INT32>, %arg0, {{%.*}}, {{%.*}} : !spirv.arm.tensor<1x3x65537x1xi8>, !spirv.arm.tensor<1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<1x2x32768x1xi8>
+    %6 = spirv.Tosa.AvgPool2D kernel = [3, 3], stride = [1, 2], pad = [0, 1, 0, 0], acc_type = <INT32>, %arg0, %4, %5 : !spirv.arm.tensor<1x3x65537x1xi8>, !spirv.arm.tensor<1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<1x2x32768x1xi8>
+    // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<1x2x32768x1xi8>
+    spirv.ARM.GraphOutputs %6 : !spirv.arm.tensor<1x2x32768x1xi8>
+  }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.AvgPool2D - 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 @avgpool2d_fp_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<1x2x65533x2xf32>, UniformConstant>
+  spirv.GlobalVariable @avgpool2d_fp_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<1x2x65532x2xf32>, UniformConstant>
+  spirv.ARM.GraphEntryPoint @avgpool2d_fp, @avgpool2d_fp_arg_0, @avgpool2d_fp_res_0
+  spirv.ARM.Graph @avgpool2d_fp(%arg0: !spirv.arm.tensor<1x2x65533x2xf32>) -> (!spirv.arm.tensor<1x2x65532x2xf32>) {
+    %4 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
+    %5 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf32>
+    // CHECK: {{%.*}} = spirv.Tosa.AvgPool2D kernel = [2, 2], stride = [1, 1], pad = [1, 0, 0, 0], acc_type = <FP32>, %arg0, {{%.*}}, {{%.*}} : !spirv.arm.tensor<1x2x65533x2xf32>, !spirv.arm.tensor<1xf32>, !spirv.arm.tensor<1xf32> -> !spirv.arm.tensor<1x2x65532x2xf32>
+    %6 = spirv.Tosa.AvgPool2D kernel = [2, 2], stride = [1, 1], pad = [1, 0, 0, 0], acc_type = <FP32>, %arg0, %4, %5 : !spirv.arm.tensor<1x2x65533x2xf32>, !spirv.arm.tensor<1xf32>, !spirv.arm.tensor<1xf32> -> !spirv.arm.tensor<1x2x65532x2xf32>
+    // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<1x2x65532x2xf32>
+    spirv.ARM.GraphOutputs %6 : !spirv.arm.tensor<1x2x65532x2xf32>
+  }
+}
+
+// -----
+
 //===----------------------------------------------------------------------===//
 // spirv.TOSA.Conv2D - PRO-INT
 //===----------------------------------------------------------------------===//
@@ -180,6 +222,137 @@ spirv.module Logical Vulkan requires #spirv.vce<v1.3, [VulkanMemoryModel, Shader
 
 // -----
 
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.FFT2D - EXT-FFT
+//===----------------------------------------------------------------------===//
+
+// 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 @fft2d_fft_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<1x32x32xf32>, UniformConstant>
+  spirv.GlobalVariable @fft2d_fft_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<1x32x32xf32>, UniformConstant>
+  spirv.GlobalVariable @fft2d_fft_res_0 bind(0, 2) : !spirv.ptr<!spirv.arm.tensor<1x32x32xf32>, UniformConstant>
+  spirv.GlobalVariable @fft2d_fft_res_1 bind(0, 3) : !spirv.ptr<!spirv.arm.tensor<1x32x32xf32>, UniformConstant>
+  spirv.ARM.GraphEntryPoint @fft2d_fft, @fft2d_fft_arg_0, @fft2d_fft_arg_1, @fft2d_fft_res_0, @fft2d_fft_res_1
+  spirv.ARM.Graph @fft2d_fft(%arg0: !spirv.arm.tensor<1x32x32xf32>, %arg1: !spirv.arm.tensor<1x32x32xf32>) -> (!spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>) {
+    // CHECK: {{%.*}} = spirv.Tosa.FFT2D inverse = true, local_bound = false, %arg0, %arg1 : !spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32> -> !spirv.struct<(!spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>)>
+    %out = spirv.Tosa.FFT2D inverse = true, local_bound = false, %arg0, %arg1 : !spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32> -> !spirv.struct<(!spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>)>
+    // CHECK: {{%.*}} = spirv.CompositeExtract {{%.*}}[0 : i32] : !spirv.struct<(!spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>)>
+    %out0 = spirv.CompositeExtract %out[0 : i32] : !spirv.struct<(!spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>)>
+    // CHECK: {{%.*}} = spirv.CompositeExtract {{%.*}}[1 : i32] :  !spirv.struct<(!spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>)>
+    %out1 = spirv.CompositeExtract %out[1 : i32] : !spirv.struct<(!spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>)>
+    // CHECK: spirv.ARM.GraphOutputs {{%.*}}, {{%.*}} : !spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>
+    spirv.ARM.GraphOutputs  %out0, %out1 : !spirv.arm.tensor<1x32x32xf32>, !spirv.arm.tensor<1x32x32xf32>
+  }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.MatMul - 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 @matmul_int_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<8x2x3xi8>, UniformConstant>
+  spirv.GlobalVariable @matmul_int_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<8x3x8xi8>, UniformConstant>
+  spirv.GlobalVariable @matmul_int_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<8x2x8xi32>, UniformConstant>
+  spirv.ARM.GraphEntryPoint @matmul_int, @matmul_int_arg_0, @matmul_int_arg_1, @matmul_int_res_0
+  spirv.ARM.Graph @matmul_int(%arg0: !spirv.arm.tensor<8x2x3xi8>, %arg1: !spirv.arm.tensor<8x3x8xi8>) -> (!spirv.arm.tensor<8x2x8xi32>) {
+    %0 = spirv.Constant dense<0> : !spirv.arm.tensor<1xi8>
+    %1 = spirv.Constant dense<0> : !spirv.arm.tensor<1xi8>
+    // CHECK: {{%.*}} = spirv.Tosa.MatMul %arg0, %arg1, {{%.*}}, {{%.*}} : !spirv.arm.tensor<8x2x3xi8>, !spirv.arm.tensor<8x3x8xi8>, !spirv.arm.tensor<1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<8x2x8xi32>
+    %2 = spirv.Tosa.MatMul %arg0, %arg1, %0, %1 : !spirv.arm.tensor<8x2x3xi8>, !spirv.arm.tensor<8x3x8xi8>, !spirv.arm.tensor<1xi8>, !spirv.arm.tensor<1xi8> -> !spirv.arm.tensor<8x2x8xi32>
+    // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<8x2x8xi32>
+    spirv.ARM.GraphOutputs %2 : !spirv.arm.tensor<8x2x8xi32>
+  }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.MatMul - 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 @matmul_fp_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<15x39x50xf16>, UniformConstant>
+  spirv.GlobalVariable @matmul_fp_arg_1 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<15x50x24xf16>, UniformConstant>
+  spirv.GlobalVariable @matmul_fp_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<15x39x24xf16>, UniformConstant>
+  spirv.ARM.GraphEntryPoint @matmul_fp, @matmul_fp_arg_0, @matmul_fp_arg_1, @matmul_fp_res_0
+  spirv.ARM.Graph @matmul_fp(%arg0: !spirv.arm.tensor<15x39x50xf16>, %arg1: !spirv.arm.tensor<15x50x24xf16>) -> (!spirv.arm.tensor<15x39x24xf16>) {
+    %0 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
+    %1 = spirv.Constant dense<0.000000e+00> : !spirv.arm.tensor<1xf16>
+    // CHECK: {{%.*}} = spirv.Tosa.MatMul %arg0, %arg1, {{%.*}}, {{%.*}} : !spirv.arm.tensor<15x39x50xf16>, !spirv.arm.tensor<15x50x24xf16>, !spirv.arm.tensor<1xf16>, !spirv.arm.tensor<1xf16> -> !spirv.arm.tensor<15x39x24xf16>
+    %2 = spirv.Tosa.MatMul %arg0, %arg1, %0, %1 : !spirv.arm.tensor<15x39x50xf16>, !spirv.arm.tensor<15x50x24xf16>, !spirv.arm.tensor<1xf16>, !spirv.arm.tensor<1xf16> -> !spirv.arm.tensor<15x39x24xf16>
+    // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<15x39x24xf16>
+    spirv.ARM.GraphOutputs %2 : !spirv.arm.tensor<15x39x24xf16>
+  }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.MaxPool2D - 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 @maxpool2d_int_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<1x3x65537x1xi8>, UniformConstant>
+  spirv.GlobalVariable @maxpool2d_int_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<1x2x32769x1xi8>, UniformConstant>
+  spirv.ARM.GraphEntryPoint @maxpool2d_int, @maxpool2d_int_arg_0, @maxpool2d_int_res_0
+  spirv.ARM.Graph @maxpool2d_int(%arg0: !spirv.arm.tensor<1x3x65537x1xi8>) -> (!spirv.arm.tensor<1x2x32769x1xi8>) {
+    // CHECK: {{%.*}} = spirv.Tosa.MaxPool2D kernel = [3, 2], stride = [1, 2], pad = [1, 0, 0, 1], nan_mode = <Propagate>, %arg0 : !spirv.arm.tensor<1x3x65537x1xi8> -> !spirv.arm.tensor<1x2x32769x1xi8>
+    %4 = spirv.Tosa.MaxPool2D kernel = [3, 2], stride = [1, 2], pad = [1, 0, 0, 1], nan_mode = <Propagate>, %arg0 : !spirv.arm.tensor<1x3x65537x1xi8> -> !spirv.arm.tensor<1x2x32769x1xi8>
+    // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<1x2x32769x1xi8>
+    spirv.ARM.GraphOutputs %4 : !spirv.arm.tensor<1x2x32769x1xi8>
+  }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.MaxPool2D - 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 @maxpool2d_fp_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<1x6x65536x1xf32>, UniformConstant>
+  spirv.GlobalVariable @maxpool2d_fp_res_0 bind(1, 0) : !spirv.ptr<!spirv.arm.tensor<1x3x32769x1xf32>, UniformConstant>
+  spirv.ARM.GraphEntryPoint @maxpool2d_fp, @maxpool2d_fp_arg_0, @maxpool2d_fp_res_0
+  spirv.ARM.Graph @maxpool2d_fp(%arg0: !spirv.arm.tensor<1x6x65536x1xf32>) -> (!spirv.arm.tensor<1x3x32769x1xf32>) {
+    // CHECK: {{%.*}} = spirv.Tosa.MaxPool2D kernel = [3, 2], stride = [2, 2], pad = [1, 0, 1, 1], nan_mode = <Propagate>, %arg0 : !spirv.arm.tensor<1x6x65536x1xf32> -> !spirv.arm.tensor<1x3x32769x1xf32>
+    %4 = spirv.Tosa.MaxPool2D kernel = [3, 2], stride = [2, 2], pad = [1, 0, 1, 1], nan_mode = <Propagate>, %arg0 : !spirv.arm.tensor<1x6x65536x1xf32> -> !spirv.arm.tensor<1x3x32769x1xf32>
+    // CHECK: spirv.ARM.GraphOutputs {{%.*}} : !spirv.arm.tensor<1x3x32769x1xf32>
+    spirv.ARM.GraphOutputs %4 : !spirv.arm.tensor<1x3x32769x1xf32>
+  }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.TOSA.RFFT2D - EXT-FFT
+//===----------------------------------------------------------------------===//
+
+// 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 @rfft2d_fft_arg_0 bind(0, 0) : !spirv.ptr<!spirv.arm.tensor<1x32x32xf32>, UniformConstant>
+  spirv.GlobalVariable @rfft2d_fft_res_0 bind(0, 1) : !spirv.ptr<!spirv.arm.tensor<1x32x17xf32>, UniformConstant>
+  spirv.GlobalVariable @rfft2d_fft_res_1 bind(0, 2) : !spirv.ptr<!spirv.arm.tensor<1x32x17xf32>, UniformConstant>
+  spirv.ARM.GraphEntryPoint @rfft2d_fft, @rfft2d_fft_arg_0, @rfft2d_fft_res_0, @rfft2d_fft_res_1
+  spirv.ARM.Graph @rfft2d_fft(%arg0: !spirv.arm.tensor<1x32x32xf32>) -> (!spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>) {
+    // CHECK: {{%.*}} = spirv.Tosa.RFFT2D local_bound = false, %arg0 : !spirv.arm.tensor<1x32x32xf32> -> !spirv.struct<(!spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>)>
+    %out = spirv.Tosa.RFFT2D local_bound = false, %arg0 : !spirv.arm.tensor<1x32x32xf32> -> !spirv.struct<(!spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>)>
+    // CHECK: {{%.*}} = spirv.CompositeExtract {{%.*}}[0 : i32] : !spirv.struct<(!spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>)>
+    %out0 = spirv.CompositeExtract %out[0 : i32] : !spirv.struct<(!spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>)>
+    // CHECK: {{%.*}} = spirv.CompositeExtract {{%.*}}[1 : i32] : !spirv.struct<(!spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>)>
+    %out1 = spirv.CompositeExtract %out[1 : i32] : !spirv.struct<(!spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>)>
+    // CHECK: spirv.ARM.GraphOutputs {{%.*}}, {{%.*}} : !spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>
+    spirv.ARM.GraphOutputs %out0, %out1 : !spirv.arm.tensor<1x32x17xf32>, !spirv.arm.tensor<1x32x17xf32>
+  }
+}
+
+// -----
+
 //===----------------------------------------------------------------------===//
 // spirv.TOSA.TransposeConv2D - PRO-INT
 //===----------------------------------------------------------------------===//



More information about the Mlir-commits mailing list