[Mlir-commits] [mlir] 4f63790 - [mlir][tosa][tosa-to-linalg] Fix rescale with double rounding failing validation (#184787)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed Mar 18 03:10:26 PDT 2026


Author: Luke Hutton
Date: 2026-03-18T10:10:20Z
New Revision: 4f6379069eb200ec57f0b39b1ecbb4004d73c82f

URL: https://github.com/llvm/llvm-project/commit/4f6379069eb200ec57f0b39b1ecbb4004d73c82f
DIFF: https://github.com/llvm/llvm-project/commit/4f6379069eb200ec57f0b39b1ecbb4004d73c82f.diff

LOG: [mlir][tosa][tosa-to-linalg] Fix rescale with double rounding failing validation (#184787)

The validation pass added attribute checks on rescale rounding mode, but
the tosa-to-linalg-pipeline did not specify support for the doubleround
extension, causing rescale with doubleround to be rejected by the
validation in the tosa-to-linalg-pipeline.

One method of fixing this would be to only enable the attribute checks
when the "strictOpSpecAlignment" validation option is enabled. However,
I feel this is the wrong direction of travel. Long-term it would be nice
if the tosa-to-linalg-pipeline specified all the extensions it supports,
gracefully rejecting operations that require unsupported extensions.

Therefore, this change declares support for the doubleround extension to
fix the legalization failure with the ambition of adding more extensions
in the future.

Added: 
    

Modified: 
    mlir/include/mlir/Conversion/TosaToLinalg/TosaToLinalg.h
    mlir/lib/Conversion/TosaToLinalg/TosaToLinalgPass.cpp
    mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-pipeline.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Conversion/TosaToLinalg/TosaToLinalg.h b/mlir/include/mlir/Conversion/TosaToLinalg/TosaToLinalg.h
index 66f68ae71f271..c1d28528a2f90 100644
--- a/mlir/include/mlir/Conversion/TosaToLinalg/TosaToLinalg.h
+++ b/mlir/include/mlir/Conversion/TosaToLinalg/TosaToLinalg.h
@@ -38,7 +38,8 @@ void addTosaToLinalgPasses(
         TosaToLinalgNamedOptions(),
     // Note: Default to 'none' level unless otherwise specified.
     std::optional<tosa::TosaValidationOptions> validationOptions =
-        tosa::TosaValidationOptions{false, false});
+        tosa::TosaValidationOptions{false, false},
+    std::optional<TosaAttachTargetOptions> attachTargetOptions = std::nullopt);
 
 /// Populates TOSA to linalg pipelines
 /// Currently, this includes only the "tosa-to-linalg-pipeline".

diff  --git a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalgPass.cpp b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalgPass.cpp
index e7602b4508cf1..c60e3ab705722 100644
--- a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalgPass.cpp
+++ b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalgPass.cpp
@@ -19,6 +19,7 @@
 #include "mlir/Dialect/Math/IR/Math.h"
 #include "mlir/Dialect/SCF/IR/SCF.h"
 #include "mlir/Dialect/Tensor/IR/Tensor.h"
+#include "mlir/Dialect/Tosa/IR/TargetEnv.h"
 #include "mlir/Dialect/Tosa/IR/TosaOps.h"
 #include "mlir/Dialect/Tosa/Transforms/Passes.h"
 #include "mlir/IR/PatternMatch.h"
@@ -80,7 +81,8 @@ std::unique_ptr<Pass> mlir::tosa::createTosaToLinalg() {
 void mlir::tosa::addTosaToLinalgPasses(
     OpPassManager &pm, const TosaToLinalgOptions &options,
     const TosaToLinalgNamedOptions &tosaToLinalgNamedOptions,
-    std::optional<tosa::TosaValidationOptions> validationOptions) {
+    std::optional<tosa::TosaValidationOptions> validationOptions,
+    std::optional<TosaAttachTargetOptions> attachTargetOptions) {
   // Optional decompositions are designed to benefit linalg.
   if (!options.disableTosaDecompositions)
     pm.addNestedPass<func::FuncOp>(
@@ -96,6 +98,14 @@ void mlir::tosa::addTosaToLinalgPasses(
   pm.addNestedPass<func::FuncOp>(tosa::createTosaLayerwiseConstantFoldPass(
       {options.aggressiveReduceConstant}));
   pm.addNestedPass<func::FuncOp>(tosa::createTosaMakeBroadcastablePass());
+  if (!attachTargetOptions) {
+    attachTargetOptions = TosaAttachTargetOptions();
+    attachTargetOptions->profiles = {"pro_int", "pro_fp"};
+    // TODO: populate with all the extensions that the tosa->linalg conversion
+    // supports
+    attachTargetOptions->extensions = {"doubleround"};
+  }
+  pm.addPass(tosa::createTosaAttachTarget(*attachTargetOptions));
   if (validationOptions)
     pm.addPass(tosa::createTosaValidation(*validationOptions));
   pm.addNestedPass<func::FuncOp>(tosa::createTosaToLinalg());

diff  --git a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-pipeline.mlir b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-pipeline.mlir
index 74706c426ea9c..67b6aa63f2293 100644
--- a/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-pipeline.mlir
+++ b/mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-pipeline.mlir
@@ -1,4 +1,4 @@
-// RUN: mlir-opt %s --split-input-file --tosa-to-linalg-pipeline -verify-diagnostics
+// RUN: mlir-opt %s --split-input-file --tosa-to-linalg-pipeline -verify-diagnostics | FileCheck %s
 
 
 // -----
@@ -28,3 +28,28 @@ func.func @avg_pool2d_with_unsupported_quant_type(%arg0: tensor<1x7x7x9x!quant.u
   %0 = "tosa.avg_pool2d"(%arg0, %arg1, %arg2) {acc_type = i32, kernel = array<i64: 2, 2>, pad = array<i64: 0, 1, 0, 1>, stride = array<i64: 1, 1>} : (tensor<1x7x7x9x!quant.uniform<i8:f32, 0.01>>, tensor<1xi8>, tensor<1xi8>) -> tensor<1x7x7x9x!quant.uniform<i8:f32, 0.01>>
   return %0 : tensor<1x7x7x9x!quant.uniform<i8:f32, 0.01>>
 }
+
+// -----
+
+// CHECK-LABEL: rescale_doubleround
+func.func @rescale_doubleround(%arg0: tensor<8x9x7x14xi32>) -> tensor<8x9x7x14xi8> {
+  %0 = "tosa.const"() <{values = dense<0> : tensor<14xi32>}> : () -> tensor<14xi32>
+  %1 = "tosa.const"() <{values = dense<0> : tensor<14xi8>}> : () -> tensor<14xi8>
+  %2 = "tosa.const"() <{values = dense<0> : tensor<1xi32>}> : () -> tensor<1xi32>
+  %3 = "tosa.const"() <{values = dense<-5> : tensor<1xi8>}> : () -> tensor<1xi8>
+  // CHECK: tosa.apply_scale
+  %4 = tosa.rescale %arg0, %0, %1, %2, %3 {input_unsigned = false, output_unsigned = false, per_channel = true, rounding_mode = DOUBLE_ROUND, scale32 = true} : (tensor<8x9x7x14xi32>, tensor<14xi32>, tensor<14xi8>, tensor<1xi32>, tensor<1xi8>) -> tensor<8x9x7x14xi8>
+  return %4 : tensor<8x9x7x14xi8>
+}
+
+// -----
+
+func.func @rescale_inexactround(%arg0: tensor<8x9x7x14xi32>) -> tensor<8x9x7x14xi8> {
+  %0 = "tosa.const"() <{values = dense<0> : tensor<14xi32>}> : () -> tensor<14xi32>
+  %1 = "tosa.const"() <{values = dense<0> : tensor<14xi8>}> : () -> tensor<14xi8>
+  %2 = "tosa.const"() <{values = dense<0> : tensor<1xi32>}> : () -> tensor<1xi32>
+  %3 = "tosa.const"() <{values = dense<-5> : tensor<1xi8>}> : () -> tensor<1xi8>
+  // expected-error at +1 {{'tosa.rescale' op failed attribute check: rounding_mode = INEXACT_ROUND requires extension [inexactround]}}
+  %4 = tosa.rescale %arg0, %0, %1, %2, %3 {input_unsigned = false, output_unsigned = false, per_channel = true, rounding_mode = INEXACT_ROUND, scale32 = true} : (tensor<8x9x7x14xi32>, tensor<14xi32>, tensor<14xi8>, tensor<1xi32>, tensor<1xi8>) -> tensor<8x9x7x14xi8>
+  return %4 : tensor<8x9x7x14xi8>
+}


        


More information about the Mlir-commits mailing list