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

llvmlistbot at llvm.org llvmlistbot at llvm.org
Thu Mar 5 05:03:11 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-tosa

@llvm/pr-subscribers-mlir-linalg

Author: Luke Hutton (lhutton1)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/184787.diff


3 Files Affected:

- (modified) mlir/include/mlir/Conversion/TosaToLinalg/TosaToLinalg.h (+2-1) 
- (modified) mlir/lib/Conversion/TosaToLinalg/TosaToLinalgPass.cpp (+11-3) 
- (modified) mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-pipeline.mlir (+26-1) 


``````````diff
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..bd4d5ed15f934 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,8 @@ void mlir::tosa::addTosaToLinalgPasses(
   pm.addNestedPass<func::FuncOp>(tosa::createTosaLayerwiseConstantFoldPass(
       {options.aggressiveReduceConstant}));
   pm.addNestedPass<func::FuncOp>(tosa::createTosaMakeBroadcastablePass());
+  if (attachTargetOptions)
+    pm.addPass(tosa::createTosaAttachTarget(*attachTargetOptions));
   if (validationOptions)
     pm.addPass(tosa::createTosaValidation(*validationOptions));
   pm.addNestedPass<func::FuncOp>(tosa::createTosaToLinalg());
@@ -114,11 +118,15 @@ void mlir::tosa::registerTosaToLinalgPipelines() {
       [](OpPassManager &pm) {
         TosaToLinalgOptions tosaToLinalgOptions;
         TosaToLinalgNamedOptions tosaToLinalgNamedOptions;
+        TosaAttachTargetOptions tosaAttachTargetOptions;
+        tosaAttachTargetOptions.profiles = {"pro_int", "pro_fp"};
+        // TODO: Populate all the extensions that this conversion supports
+        tosaAttachTargetOptions.extensions = {"doubleround"};
         TosaValidationOptions validationOptions;
         validationOptions.strictOpSpecAlignment = false;
         validationOptions.allowInvalidOpDatatypeCombinations = false;
         tosa::addTosaToLinalgPasses(pm, tosaToLinalgOptions,
-                                    tosaToLinalgNamedOptions,
-                                    validationOptions);
+                                    tosaToLinalgNamedOptions, validationOptions,
+                                    tosaAttachTargetOptions);
       });
 }
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>
+}

``````````

</details>


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


More information about the Mlir-commits mailing list