[Mlir-commits] [mlir] [mlir][tosa] Support variadic batch dimensions in MATMUL operator (PR #232371)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Fri Oct 16 02:01:50 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir-tosa

Author: kmehanna (karmeh01)

<details>
<summary>Changes</summary>

Extend TOSA-to-Linalg MATMUL lowering to support rank-two inputs and multiple batch dimensions. 

Reuse MATMUL_T helpers to add missing batch dimensions and broadcast singleton dimensions, preserving quantized zero-point handling.

Add conversion tests for dynamic shapes, broadcasting, quantized inputs, and unsupported cases.

Assisted-by: Codex

---

Patch is 51.33 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/232371.diff


5 Files Affected:

- (modified) mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp (+24-22) 
- (modified) mlir/lib/Conversion/TosaToLinalg/TosaToLinalgNamed.cpp (+93-57) 
- (modified) mlir/lib/Conversion/TosaToLinalg/TosaToLinalgUtils.h (+4-3) 
- (modified) mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-named-invalid.mlir (+36) 
- (modified) mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-named.mlir (+415-18) 


``````````diff
diff --git a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
index 25b4b360723b2..97793761f006c 100644
--- a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
+++ b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
@@ -1432,9 +1432,9 @@ static LogicalResult reduceMatchAndRewriteHelper(OpTy op, uint64_t axis,
 }
 
 // Insert missing leading batch dimensions, taking their sizes from `other`.
-static Value broadcastMatMulTLeadingDimensions(PatternRewriter &rewriter,
-                                               Location loc, Value operand,
-                                               Value other) {
+static Value broadcastMatMulLeadingDimensions(PatternRewriter &rewriter,
+                                              Location loc, Value operand,
+                                              Value other) {
   auto type = cast<RankedTensorType>(operand.getType());
   int64_t missingDims =
       cast<RankedTensorType>(other.getType()).getRank() - type.getRank();
@@ -1456,13 +1456,12 @@ static Value broadcastMatMulTLeadingDimensions(PatternRewriter &rewriter,
 }
 
 // Expand an existing singleton batch dimension to `size`, preserving the rank.
-// Missing dimensions are handled by broadcastMatMulTLeadingDimensions.
+// Missing dimensions are handled by broadcastMatMulLeadingDimensions.
 // linalg.broadcast inserts dimensions, so first remove the singleton dimension
 // with a rank-reducing slice, then reinsert it at the target size.
-static Value broadcastMatMulTSingletonDimension(PatternRewriter &rewriter,
-                                                Location loc, Value operand,
-                                                int64_t dim,
-                                                OpFoldResult size) {
+static Value broadcastMatMulSingletonDimension(PatternRewriter &rewriter,
+                                               Location loc, Value operand,
+                                               int64_t dim, OpFoldResult size) {
   auto type = cast<RankedTensorType>(operand.getType());
   SmallVector<int64_t> sliceShape(type.getShape());
   sliceShape.erase(sliceShape.begin() + dim);
@@ -1484,13 +1483,13 @@ static Value broadcastMatMulTSingletonDimension(PatternRewriter &rewriter,
 
 // Align the ranks, then broadcast each shared batch dimension independently.
 static std::pair<Value, Value>
-normalizeMatMulTBatchDimensions(PatternRewriter &rewriter, Location loc,
-                                Value a, Value b, int64_t batchRank) {
+normalizeMatMulBatchDimensions(PatternRewriter &rewriter, Location loc, Value a,
+                               Value b, int64_t batchRank) {
   int64_t aRank = cast<RankedTensorType>(a.getType()).getRank();
   int64_t bRank = cast<RankedTensorType>(b.getType()).getRank();
   int64_t firstSharedDim = std::max(aRank, bRank) - std::min(aRank, bRank);
-  a = broadcastMatMulTLeadingDimensions(rewriter, loc, a, b);
-  b = broadcastMatMulTLeadingDimensions(rewriter, loc, b, a);
+  a = broadcastMatMulLeadingDimensions(rewriter, loc, a, b);
+  b = broadcastMatMulLeadingDimensions(rewriter, loc, b, a);
 
   IndexPool indexPool;
   // The inserted leading dimensions already match their partner's sizes.
@@ -1507,11 +1506,11 @@ normalizeMatMulTBatchDimensions(PatternRewriter &rewriter, Location loc,
     auto [size, masterOperand] =
         computeTargetSize(rewriter, loc, indexPool, ValueRange{a, b}, dim);
     if (aSize == 1) {
-      a = broadcastMatMulTSingletonDimension(rewriter, loc, a, dim, size);
+      a = broadcastMatMulSingletonDimension(rewriter, loc, a, dim, size);
       continue;
     }
     if (bSize == 1) {
-      b = broadcastMatMulTSingletonDimension(rewriter, loc, b, dim, size);
+      b = broadcastMatMulSingletonDimension(rewriter, loc, b, dim, size);
       continue;
     }
     a = broadcastDynamicDimension(rewriter, loc, indexPool, a, dim, size,
@@ -1522,14 +1521,15 @@ normalizeMatMulTBatchDimensions(PatternRewriter &rewriter, Location loc,
   return {a, b};
 }
 
-MatMulTOperands
-mlir::tosa::prepareMatMulTOperands(PatternRewriter &rewriter, Location loc,
-                                   Value a, Value b,
-                                   RankedTensorType outputType) {
+MatMulTOperands mlir::tosa::prepareMatMulOperands(PatternRewriter &rewriter,
+                                                  Location loc, Value a,
+                                                  Value b,
+                                                  RankedTensorType outputType,
+                                                  bool transposeB) {
   const int64_t outputRank = outputType.getRank();
   const int64_t batchRank = outputRank - 2;
   auto normalizedOperands =
-      normalizeMatMulTBatchDimensions(rewriter, loc, a, b, batchRank);
+      normalizeMatMulBatchDimensions(rewriter, loc, a, b, batchRank);
   a = normalizedOperands.first;
   b = normalizedOperands.second;
 
@@ -1538,7 +1538,8 @@ mlir::tosa::prepareMatMulTOperands(PatternRewriter &rewriter, Location loc,
   for (int64_t batchDim = 0; batchDim < batchRank; ++batchDim)
     outputShape.push_back(tensor::getMixedSize(rewriter, loc, a, batchDim));
   outputShape.push_back(tensor::getMixedSize(rewriter, loc, a, outputRank - 2));
-  outputShape.push_back(tensor::getMixedSize(rewriter, loc, b, outputRank - 2));
+  outputShape.push_back(
+      tensor::getMixedSize(rewriter, loc, b, outputRank - 1 - transposeB));
   SmallVector<Value> dynamicDims;
   for (auto [dim, size] : llvm::enumerate(outputShape))
     if (outputType.isDynamicDim(dim))
@@ -1592,8 +1593,9 @@ class QuantizedMatMulTConverter : public OpConversionPattern<tosa::MatMulTOp> {
 
     const int64_t outputRank = outputType.getRank();
     const int64_t batchRank = outputRank - 2;
-    auto [a, b, zeroTensor] = prepareMatMulTOperands(
-        rewriter, loc, adaptor.getA(), adaptor.getB(), outputType);
+    auto [a, b, zeroTensor] =
+        prepareMatMulOperands(rewriter, loc, adaptor.getA(), adaptor.getB(),
+                              outputType, /*transposeB=*/true);
     Type outputElementType = outputType.getElementType();
 
     int64_t loopRank = outputRank + 1;
diff --git a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalgNamed.cpp b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalgNamed.cpp
index a7f7414bf56ed..f646c3a80f06f 100644
--- a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalgNamed.cpp
+++ b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalgNamed.cpp
@@ -605,6 +605,16 @@ class DepthwiseConvConverter
   }
 };
 
+static SmallVector<ReassociationIndices>
+getMatMulBatchCollapseReassociation(int64_t rank) {
+  SmallVector<ReassociationIndices> reassociation(3);
+  for (int64_t dim = 0; dim < rank - 2; ++dim)
+    reassociation[0].push_back(dim);
+  reassociation[1].push_back(rank - 2);
+  reassociation[2].push_back(rank - 1);
+  return reassociation;
+}
+
 class MatMulConverter : public OpConversionPattern<tosa::MatMulOp> {
 public:
   using OpConversionPattern<tosa::MatMulOp>::OpConversionPattern;
@@ -612,85 +622,110 @@ class MatMulConverter : public OpConversionPattern<tosa::MatMulOp> {
   matchAndRewrite(tosa::MatMulOp op, OpAdaptor adaptor,
                   ConversionPatternRewriter &rewriter) const final {
     Location loc = op.getLoc();
-
-    auto outputTy = cast<ShapedType>(op.getType());
-    auto outputElementTy = outputTy.getElementType();
-
-    SmallVector<Value> dynDims;
-    dynDims.resize(cast<ShapedType>(op->getResult(0).getType()).getRank());
-
-    if (!outputTy.hasRank() || outputTy.isDynamicDim(0)) {
-      dynDims[0] = tensor::DimOp::create(rewriter, loc, op->getOperand(0), 0);
-    }
-
-    if (!outputTy.hasRank() || outputTy.isDynamicDim(1)) {
-      dynDims[1] = tensor::DimOp::create(rewriter, loc, op->getOperand(0), 1);
-    }
-
-    if (!outputTy.hasRank() || outputTy.isDynamicDim(2)) {
-      dynDims[2] = tensor::DimOp::create(rewriter, loc, op->getOperand(1), 2);
-    }
-
-    SmallVector<Value> filteredDims = condenseValues(dynDims);
-
-    auto zeroAttr = rewriter.getZeroAttr(outputElementTy);
-    Value zero = arith::ConstantOp::create(rewriter, loc, zeroAttr);
-    auto emptyTensor =
-        tensor::EmptyOp::create(rewriter, loc, outputTy.getShape(),
-                                outputTy.getElementType(), filteredDims);
-    Value zeroTensor = linalg::FillOp::create(rewriter, loc, ValueRange{zero},
-                                              ValueRange{emptyTensor})
-                           .result();
+    auto aType = dyn_cast<RankedTensorType>(adaptor.getA().getType());
+    auto bType = dyn_cast<RankedTensorType>(adaptor.getB().getType());
+    auto outputType = dyn_cast<RankedTensorType>(op.getType());
+    if (!aType || !bType || !outputType)
+      return rewriter.notifyMatchFailure(op, "only supports ranked tensors");
 
     FailureOr<int64_t> maybeAZp = op.getAZeroPoint();
     FailureOr<int64_t> maybeBZp = op.getBZeroPoint();
     if (failed(maybeAZp))
       return rewriter.notifyMatchFailure(
-          op, "input a zero point cannot be statically determined");
+          op, "input A zero point cannot be statically determined");
     if (failed(maybeBZp))
       return rewriter.notifyMatchFailure(
-          op, "input b zero point cannot be statically determined");
+          op, "input B zero point cannot be statically determined");
 
     const int64_t aZpVal = *maybeAZp;
     const int64_t bZpVal = *maybeBZp;
 
     if (op.verifyAZeroPoint(aZpVal).failed())
       return rewriter.notifyMatchFailure(
-          op, "input a zero point must be zero for non-int8 integer types");
+          op, "input A zero point must be zero for non-int8 integer types");
 
     if (op.verifyBZeroPoint(bZpVal).failed())
       return rewriter.notifyMatchFailure(
-          op, "input b zero point must be zero for non-int8 integer types");
+          op, "input B zero point must be zero for non-int8 integer types");
+
+    const int64_t outputRank = outputType.getRank();
+    auto [a, b, zeroTensor] =
+        prepareMatMulOperands(rewriter, loc, adaptor.getA(), adaptor.getB(),
+                              outputType, /*transposeB=*/false);
+
+    Value aZp, bZp;
+    const bool hasNonzeroZeroPoint = aZpVal != 0 || bZpVal != 0;
+    if (hasNonzeroZeroPoint) {
+      aZp = arith::ConstantOp::create(rewriter, loc,
+                                      rewriter.getI32IntegerAttr(aZpVal));
+      bZp = arith::ConstantOp::create(rewriter, loc,
+                                      rewriter.getI32IntegerAttr(bZpVal));
+    }
 
-    if (aZpVal == 0 && bZpVal == 0) {
-      rewriter.replaceOpWithNewOp<linalg::BatchMatmulOp>(
-          op, TypeRange{op.getType()},
-          ValueRange{adaptor.getA(), adaptor.getB()}, ValueRange{zeroTensor});
+    if (outputRank == 2) {
+      if (!hasNonzeroZeroPoint) {
+        rewriter.replaceOpWithNewOp<linalg::MatmulOp>(op, TypeRange{outputType},
+                                                      ValueRange{a, b},
+                                                      ValueRange{zeroTensor});
+      } else {
+        rewriter.replaceOpWithNewOp<linalg::QuantizedMatmulOp>(
+            op, TypeRange{outputType}, ValueRange{a, b, aZp, bZp},
+            ValueRange{zeroTensor});
+      }
       return success();
     }
 
-    auto aZp = arith::ConstantOp::create(rewriter, loc,
-                                         rewriter.getI32IntegerAttr(aZpVal));
-    auto bZp = arith::ConstantOp::create(rewriter, loc,
-                                         rewriter.getI32IntegerAttr(bZpVal));
-    rewriter.replaceOpWithNewOp<linalg::QuantizedBatchMatmulOp>(
-        op, TypeRange{op.getType()},
-        ValueRange{adaptor.getA(), adaptor.getB(), aZp, bZp}, zeroTensor);
+    if (outputRank == 3) {
+      if (!hasNonzeroZeroPoint) {
+        rewriter.replaceOpWithNewOp<linalg::BatchMatmulOp>(
+            op, TypeRange{outputType}, ValueRange{a, b},
+            ValueRange{zeroTensor});
+      } else {
+        rewriter.replaceOpWithNewOp<linalg::QuantizedBatchMatmulOp>(
+            op, TypeRange{outputType}, ValueRange{a, b, aZp, bZp},
+            ValueRange{zeroTensor});
+      }
+      return success();
+    }
+
+    SmallVector<ReassociationIndices> reassociation =
+        getMatMulBatchCollapseReassociation(outputRank);
+    auto collapse = [&](Value value) {
+      auto type = cast<RankedTensorType>(value.getType());
+      auto collapsedType =
+          tensor::CollapseShapeOp::inferCollapsedType(type, reassociation);
+      return tensor::CollapseShapeOp::create(rewriter, loc, collapsedType,
+                                             value, reassociation);
+    };
+
+    Value collapsedA = collapse(a);
+    Value collapsedB = collapse(b);
+    Value collapsedInit = collapse(zeroTensor);
+    auto collapsedOutputType = cast<RankedTensorType>(collapsedInit.getType());
+    Value collapsedResult;
 
+    if (!hasNonzeroZeroPoint) {
+      collapsedResult =
+          linalg::BatchMatmulOp::create(
+              rewriter, loc, TypeRange{collapsedOutputType},
+              ValueRange{collapsedA, collapsedB}, ValueRange{collapsedInit})
+              .getResult(0);
+    } else {
+      collapsedResult = linalg::QuantizedBatchMatmulOp::create(
+                            rewriter, loc, TypeRange{collapsedOutputType},
+                            ValueRange{collapsedA, collapsedB, aZp, bZp},
+                            ValueRange{collapsedInit})
+                            .getResult(0);
+    }
+
+    Value result = tensor::ExpandShapeOp::create(
+        rewriter, loc, outputType, collapsedResult, reassociation,
+        tensor::getMixedSizes(rewriter, loc, zeroTensor));
+    rewriter.replaceOp(op, result);
     return success();
   }
 };
 
-static SmallVector<ReassociationIndices>
-getMatMulTBatchCollapseReassociation(int64_t rank) {
-  SmallVector<ReassociationIndices> reassociation(3);
-  for (int64_t dim = 0; dim < rank - 2; ++dim)
-    reassociation[0].push_back(dim);
-  reassociation[1].push_back(rank - 2);
-  reassociation[2].push_back(rank - 1);
-  return reassociation;
-}
-
 class MatMulTConverter : public OpConversionPattern<tosa::MatMulTOp> {
 public:
   using OpConversionPattern<tosa::MatMulTOp>::OpConversionPattern;
@@ -721,8 +756,9 @@ class MatMulTConverter : public OpConversionPattern<tosa::MatMulTOp> {
           op, "nonzero zero points require the generic MATMUL_T lowering");
 
     const int64_t outputRank = outputType.getRank();
-    auto [a, b, zeroTensor] = prepareMatMulTOperands(
-        rewriter, loc, adaptor.getA(), adaptor.getB(), outputType);
+    auto [a, b, zeroTensor] =
+        prepareMatMulOperands(rewriter, loc, adaptor.getA(), adaptor.getB(),
+                              outputType, /*transposeB=*/true);
 
     if (outputRank == 2) {
       rewriter.replaceOpWithNewOp<linalg::MatmulTransposeBOp>(
@@ -737,7 +773,7 @@ class MatMulTConverter : public OpConversionPattern<tosa::MatMulTOp> {
     }
 
     SmallVector<ReassociationIndices> reassociation =
-        getMatMulTBatchCollapseReassociation(outputRank);
+        getMatMulBatchCollapseReassociation(outputRank);
     auto collapse = [&](Value value) {
       auto type = cast<RankedTensorType>(value.getType());
       auto collapsedType =
diff --git a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalgUtils.h b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalgUtils.h
index 2bc56c043a57b..e40b2d0a64216 100644
--- a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalgUtils.h
+++ b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalgUtils.h
@@ -25,9 +25,10 @@ struct MatMulTOperands {
 
 /// Broadcast the batch dimensions of the ranked operands and create a
 /// zero-filled result tensor for either MATMUL_T lowering pattern.
-MatMulTOperands prepareMatMulTOperands(PatternRewriter &rewriter, Location loc,
-                                       Value a, Value b,
-                                       RankedTensorType outputType);
+MatMulTOperands prepareMatMulOperands(PatternRewriter &rewriter, Location loc,
+                                      Value a, Value b,
+                                      RankedTensorType outputType,
+                                      bool transposeB);
 } // namespace tosa
 } // namespace mlir
 
diff --git a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-named-invalid.mlir b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-named-invalid.mlir
index d9de3f223f5d0..66be7f2603d62 100644
--- a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-named-invalid.mlir
+++ b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-named-invalid.mlir
@@ -25,3 +25,39 @@ func.func @avg_pool2d_adaptive_not_canonicalized(
     (tensor<1x4x4x1xf32>, tensor<1xf32>, tensor<1xf32>, !tosa.shape<2>, !tosa.shape<2>, !tosa.shape<4>) -> tensor<1x2x2x1xf32>
   return %0 : tensor<1x2x2x1xf32>
 }
+
+// -----
+
+// Unranked operands must fail conversion cleanly before accessing their shape.
+func.func @matmul_unranked_a(
+    %a: tensor<*xf32>, %b: tensor<1x3x6xf32>) -> tensor<1x5x6xf32> {
+  %a_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : () -> tensor<1xf32>
+  %b_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : () -> tensor<1xf32>
+  // expected-error at +1 {{failed to legalize operation 'tosa.matmul'}}
+  %0 = tosa.matmul %a, %b, %a_zp, %b_zp : (tensor<*xf32>, tensor<1x3x6xf32>, tensor<1xf32>, tensor<1xf32>) -> tensor<1x5x6xf32>
+  return %0 : tensor<1x5x6xf32>
+}
+
+// -----
+
+// A's zero point must be statically known; keep B's zero point constant.
+func.func @matmul_nonconstant_a_zero_point(
+    %a: tensor<1x5x3xi8>, %b: tensor<1x3x6xi8>,
+    %a_zp: tensor<1xi8>) -> tensor<1x5x6xi32> {
+  %b_zp = "tosa.const"() <{values = dense<0> : tensor<1xi8>}> : () -> tensor<1xi8>
+  // expected-error at +1 {{failed to legalize operation 'tosa.matmul'}}
+  %0 = tosa.matmul %a, %b, %a_zp, %b_zp : (tensor<1x5x3xi8>, tensor<1x3x6xi8>, tensor<1xi8>, tensor<1xi8>) -> tensor<1x5x6xi32>
+  return %0 : tensor<1x5x6xi32>
+}
+
+// -----
+
+// B's zero point must be statically known after A's zero point is accepted.
+func.func @matmul_nonconstant_b_zero_point(
+    %a: tensor<1x5x3xi8>, %b: tensor<1x3x6xi8>,
+    %b_zp: tensor<1xi8>) -> tensor<1x5x6xi32> {
+  %a_zp = "tosa.const"() <{values = dense<0> : tensor<1xi8>}> : () -> tensor<1xi8>
+  // expected-error at +1 {{failed to legalize operation 'tosa.matmul'}}
+  %0 = tosa.matmul %a, %b, %a_zp, %b_zp : (tensor<1x5x3xi8>, tensor<1x3x6xi8>, tensor<1xi8>, tensor<1xi8>) -> tensor<1x5x6xi32>
+  return %0 : tensor<1x5x6xi32>
+}
diff --git a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-named.mlir b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-named.mlir
index 4a052337335a7..22caf9d409eac 100644
--- a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-named.mlir
+++ b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-named.mlir
@@ -4,15 +4,15 @@
 // RUN: mlir-opt --verify-each --split-input-file -pass-pipeline="builtin.module(func.func(tosa-to-linalg-named{allow-non-finites=true}))" %s -verify-diagnostics -o -| FileCheck %s --check-prefixes=CHECK,NONFINITE
 
 // CHECK-LABEL: @matmul
-func.func @matmul(%arg0: tensor<1x5x3xf32>, %arg1: tensor<1x3x6xf32>) -> (tensor<1x5x6xf32>) {
+func.func @matmul(%arg0: tensor<2x5x3xf32>, %arg1: tensor<2x3x6xf32>) -> (tensor<2x5x6xf32>) {
   // CHECK: [[C0:%.+]] = arith.constant 0
   // CHECK: [[INIT:%.+]] = tensor.empty()
-  // CHECK: [[FILLED:%.+]] = linalg.fill ins([[C0]] : f32) outs([[INIT]] : tensor<1x5x6xf32>) -> tensor<1x5x6xf32>
-  // CHECK: linalg.batch_matmul ins(%arg0, %arg1 : tensor<1x5x3xf32>, tensor<1x3x6xf32>) outs([[FILLED]] : tensor<1x5x6xf32>) -> tensor<1x5x6xf32>
+  // CHECK: [[FILLED:%.+]] = linalg.fill ins([[C0]] : f32) outs([[INIT]] : tensor<2x5x6xf32>) -> tensor<2x5x6xf32>
+  // CHECK: linalg.batch_matmul ins(%arg0, %arg1 : tensor<2x5x3xf32>, tensor<2x3x6xf32>) outs([[FILLED]] : tensor<2x5x6xf32>) -> tensor<2x5x6xf32>
   %a_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : () -> tensor<1xf32>
   %b_zp = "tosa.const"() <{values = dense<0.0> : tensor<1xf32>}> : () -> tensor<1xf32>
-  %0 = tosa.matmul %arg0, %arg1, %a_zp, %b_zp : (tensor<1x5x3xf32>, tensor<1x3x6xf32>, tensor<1xf32>, tensor<1xf32>)  -> tensor<1x5x6xf32>
-  return %0 : tensor<1x5x6xf32>
+  %0 = tosa.matmul %arg0, %arg1, %a_zp, %b_zp : (tensor<2x5x3xf32>, tensor<2x3x6xf32>, tensor<1xf32>, tensor<1xf32>)  -> tensor<2x5x6xf32>
+  return %0 : tensor...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/232371


More information about the Mlir-commits mailing list