[Mlir-commits] [mlir] [mlir][tosa] Add support for boolean cast/gather/scatter operations (PR #177693)
Luke Hutton
llvmlistbot at llvm.org
Wed Feb 4 06:13:43 PST 2026
https://github.com/lhutton1 updated https://github.com/llvm/llvm-project/pull/177693
>From 91a984181490790814482654600d372558ade2f4 Mon Sep 17 00:00:00 2001
From: Luke Hutton <luke.hutton at arm.com>
Date: Fri, 23 Jan 2026 20:34:01 +0000
Subject: [PATCH 1/2] [mlir][tosa] Add support for boolean cast/gather/scatter
operations
Aligns with the spec change: https://github.com/arm/tosa-specification/pull/32
Change-Id: I1897c58c6f502f3872a393b5f3ec69158a7ae460
---
.../Dialect/Tosa/IR/TosaComplianceData.h.inc | 28 ++++++--
.../tosa-validation-version-1p0-invalid.mlir | 64 ++++++++++++++++++
.../tosa-validation-version-1p1-valid.mlir | 66 ++++++++++++++++++-
3 files changed, 150 insertions(+), 8 deletions(-)
diff --git a/mlir/include/mlir/Dialect/Tosa/IR/TosaComplianceData.h.inc b/mlir/include/mlir/Dialect/Tosa/IR/TosaComplianceData.h.inc
index 009775293a987..601649cd02854 100644
--- a/mlir/include/mlir/Dialect/Tosa/IR/TosaComplianceData.h.inc
+++ b/mlir/include/mlir/Dialect/Tosa/IR/TosaComplianceData.h.inc
@@ -371,7 +371,11 @@ profileComplianceMap = {
{{i32T, i32T, i32T}, SpecificationVersion::V_1_0}}},
{{Profile::pro_fp},
{{{fp16T, i32T, fp16T}, SpecificationVersion::V_1_0},
- {{fp32T, i32T, fp32T}, SpecificationVersion::V_1_0}}}}},
+ {{fp32T, i32T, fp32T}, SpecificationVersion::V_1_0}}},
+ {{Profile::pro_fp, Profile::pro_int},
+ {{{boolT, i32T, boolT}, SpecificationVersion::V_1_1_DRAFT},
+ {{boolT, i64T, boolT}, SpecificationVersion::V_1_1_DRAFT}},
+ anyOf}}},
{"tosa.scatter",
{{{Profile::pro_int},
{{{i8T, i32T, i8T, i8T}, SpecificationVersion::V_1_0},
@@ -379,7 +383,11 @@ profileComplianceMap = {
{{i32T, i32T, i32T, i32T}, SpecificationVersion::V_1_0}}},
{{Profile::pro_fp},
{{{fp16T, i32T, fp16T, fp16T}, SpecificationVersion::V_1_0},
- {{fp32T, i32T, fp32T, fp32T}, SpecificationVersion::V_1_0}}}}},
+ {{fp32T, i32T, fp32T, fp32T}, SpecificationVersion::V_1_0}}},
+ {{Profile::pro_fp, Profile::pro_int},
+ {{{boolT, i32T, boolT, boolT}, SpecificationVersion::V_1_1_DRAFT},
+ {{boolT, i64T, boolT, boolT}, SpecificationVersion::V_1_1_DRAFT}},
+ anyOf}}},
{"tosa.resize",
{{{Profile::pro_int},
{{{i8T, i32T}, SpecificationVersion::V_1_0},
@@ -402,7 +410,8 @@ profileComplianceMap = {
{{i32T, i8T}, SpecificationVersion::V_1_0},
{{i32T, i16T}, SpecificationVersion::V_1_0}}},
{{Profile::pro_fp},
- {{{i8T, fp16T}, SpecificationVersion::V_1_0},
+ {{{boolT, fp32T}, SpecificationVersion::V_1_1_DRAFT},
+ {{i8T, fp16T}, SpecificationVersion::V_1_0},
{{i8T, fp32T}, SpecificationVersion::V_1_0},
{{i16T, fp16T}, SpecificationVersion::V_1_0},
{{i16T, fp32T}, SpecificationVersion::V_1_0},
@@ -415,7 +424,8 @@ profileComplianceMap = {
{{fp32T, i8T}, SpecificationVersion::V_1_0},
{{fp32T, i16T}, SpecificationVersion::V_1_0},
{{fp32T, i32T}, SpecificationVersion::V_1_0},
- {{fp32T, fp16T}, SpecificationVersion::V_1_0}}}}},
+ {{fp32T, fp16T}, SpecificationVersion::V_1_0},
+ {{fp32T, boolT}, SpecificationVersion::V_1_1_DRAFT}}}}},
{"tosa.rescale",
{{{Profile::pro_int},
{{{i8T, i8T, i8T, i8T}, SpecificationVersion::V_1_0},
@@ -824,7 +834,8 @@ extensionComplianceMap = {
{{i32T, i64T, i32T}, SpecificationVersion::V_1_1_DRAFT},
{{i64T, i64T, i64T}, SpecificationVersion::V_1_1_DRAFT},
{{fp16T, i64T, fp16T}, SpecificationVersion::V_1_1_DRAFT},
- {{fp32T, i64T, fp32T}, SpecificationVersion::V_1_1_DRAFT}}},
+ {{fp32T, i64T, fp32T}, SpecificationVersion::V_1_1_DRAFT},
+ {{boolT, i64T, boolT}, SpecificationVersion::V_1_1_DRAFT}}},
{{Extension::fp8e4m3, Extension::int64},
{{{fp8e4m3T, i64T, fp8e4m3T}, SpecificationVersion::V_1_1_DRAFT}},
allOf},
@@ -847,7 +858,8 @@ extensionComplianceMap = {
{{i32T, i64T, i32T, i32T}, SpecificationVersion::V_1_1_DRAFT},
{{i64T, i64T, i64T, i64T}, SpecificationVersion::V_1_1_DRAFT},
{{fp16T, i64T, fp16T, fp16T}, SpecificationVersion::V_1_1_DRAFT},
- {{fp32T, i64T, fp32T, fp32T}, SpecificationVersion::V_1_1_DRAFT}}},
+ {{fp32T, i64T, fp32T, fp32T}, SpecificationVersion::V_1_1_DRAFT},
+ {{boolT, i64T, boolT, boolT}, SpecificationVersion::V_1_1_DRAFT}}},
{{Extension::fp8e4m3, Extension::int64},
{{{fp8e4m3T, i64T, fp8e4m3T, fp8e4m3T},
SpecificationVersion::V_1_1_DRAFT}},
@@ -876,7 +888,9 @@ extensionComplianceMap = {
{{fp32T, bf16T}, SpecificationVersion::V_1_0}}},
{{Extension::int64},
{{{i32T, i64T}, SpecificationVersion::V_1_1_DRAFT},
- {{i64T, i32T}, SpecificationVersion::V_1_1_DRAFT}}},
+ {{i64T, i32T}, SpecificationVersion::V_1_1_DRAFT},
+ {{boolT, i64T}, SpecificationVersion::V_1_1_DRAFT},
+ {{i64T, boolT}, SpecificationVersion::V_1_1_DRAFT}}},
{{Extension::bf16, Extension::fp8e4m3},
{{{bf16T, fp8e4m3T}, SpecificationVersion::V_1_0},
{{fp8e4m3T, bf16T}, SpecificationVersion::V_1_0}},
diff --git a/mlir/test/Dialect/Tosa/tosa-validation-version-1p0-invalid.mlir b/mlir/test/Dialect/Tosa/tosa-validation-version-1p0-invalid.mlir
index fe38e2f61b2e8..0893afbc2f96b 100644
--- a/mlir/test/Dialect/Tosa/tosa-validation-version-1p0-invalid.mlir
+++ b/mlir/test/Dialect/Tosa/tosa-validation-version-1p0-invalid.mlir
@@ -62,6 +62,70 @@ func.func @test_transpose_conv2d_fp8_acc32(%arg0: tensor<1x32x32x8xf8E5M2>, %arg
// -----
+func.func @test_gather_bool_i64(%arg0: tensor<13x21x3xi1>, %arg1: tensor<13x26xi64>) -> tensor<13x26x3xi1> {
+ // expected-error at +1 {{'tosa.gather' op illegal: the target specification version (1.0) is not backwards compatible with the op compliance specification version (1.1)}}
+ %0 = tosa.gather %arg0, %arg1 : (tensor<13x21x3xi1>, tensor<13x26xi64>) -> tensor<13x26x3xi1>
+ return %0 : tensor<13x26x3xi1>
+}
+
+// -----
+
+func.func @test_gather_bool_i32(%arg0: tensor<13x21x3xi1>, %arg1: tensor<13x26xi32>) -> tensor<13x26x3xi1> {
+ // expected-error at +1 {{'tosa.gather' op illegal: the target specification version (1.0) is not backwards compatible with the op compliance specification version (1.1)}}
+ %0 = tosa.gather %arg0, %arg1 : (tensor<13x21x3xi1>, tensor<13x26xi32>) -> tensor<13x26x3xi1>
+ return %0 : tensor<13x26x3xi1>
+}
+
+// -----
+
+func.func @test_scatter_bool_i64(%arg0: tensor<13x52x3xi1>, %arg1: tensor<13x26xi64>, %arg2: tensor<13x26x3xi1>) -> tensor<13x52x3xi1> {
+ // expected-error at +1 {{'tosa.scatter' op illegal: the target specification version (1.0) is not backwards compatible with the op compliance specification version (1.1)}}
+ %0 = tosa.scatter %arg0, %arg1, %arg2 : (tensor<13x52x3xi1>, tensor<13x26xi64>, tensor<13x26x3xi1>) -> tensor<13x52x3xi1>
+ return %0 : tensor<13x52x3xi1>
+}
+
+// -----
+
+func.func @test_scatter_bool_i32(%arg0: tensor<13x52x3xi1>, %arg1: tensor<13x26xi32>, %arg2: tensor<13x26x3xi1>) -> tensor<13x52x3xi1> {
+ // expected-error at +1 {{'tosa.scatter' op illegal: the target specification version (1.0) is not backwards compatible with the op compliance specification version (1.1)}}
+ %0 = tosa.scatter %arg0, %arg1, %arg2 : (tensor<13x52x3xi1>, tensor<13x26xi32>, tensor<13x26x3xi1>) -> tensor<13x52x3xi1>
+ return %0 : tensor<13x52x3xi1>
+}
+
+// -----
+
+func.func @test_cast_bool_fp32(%arg0: tensor<13x21x3xi1>) -> tensor<13x21x3xf32> {
+ // expected-error at +1 {{'tosa.cast' op illegal: the target specification version (1.0) is not backwards compatible with the op compliance specification version (1.1)}}
+ %0 = tosa.cast %arg0 : (tensor<13x21x3xi1>) -> tensor<13x21x3xf32>
+ return %0 : tensor<13x21x3xf32>
+}
+
+// -----
+
+func.func @test_cast_bool_i64(%arg0: tensor<13x21x3xi1>) -> tensor<13x21x3xi64> {
+ // expected-error at +1 {{'tosa.cast' op illegal: requires [int64] but not enabled in target}}
+ %0 = tosa.cast %arg0 : (tensor<13x21x3xi1>) -> tensor<13x21x3xi64>
+ return %0 : tensor<13x21x3xi64>
+}
+
+// -----
+
+func.func @test_cast_fp32_bool(%arg0: tensor<13x21x3xf32>) -> tensor<13x21x3xi1> {
+ // expected-error at +1 {{'tosa.cast' op illegal: the target specification version (1.0) is not backwards compatible with the op compliance specification version (1.1)}}
+ %0 = tosa.cast %arg0 : (tensor<13x21x3xf32>) -> tensor<13x21x3xi1>
+ return %0 : tensor<13x21x3xi1>
+}
+
+// -----
+
+func.func @test_cast_i64_bool(%arg0: tensor<13x21x3xi64>) -> tensor<13x21x3xi1> {
+ // expected-error at +1 {{'tosa.cast' op illegal: requires [int64] but not enabled in target}}
+ %0 = tosa.cast %arg0 : (tensor<13x21x3xi64>) -> tensor<13x21x3xi1>
+ return %0 : tensor<13x21x3xi1>
+}
+
+// -----
+
func.func @test_dyanmic_dims(%arg0: tensor<?x8x16xi8>) -> tensor<?x16xi32> {
// expected-error at +1 {{'tosa.argmax' op failed level check: operand shape dimension cannot be dynamic when targeting TOSA specification version 1.0 or below}}
%0 = tosa.argmax %arg0 { axis = 1 : i32 } : (tensor<?x8x16xi8>) -> tensor<?x16xi32>
diff --git a/mlir/test/Dialect/Tosa/tosa-validation-version-1p1-valid.mlir b/mlir/test/Dialect/Tosa/tosa-validation-version-1p1-valid.mlir
index 97fb14927f7e8..72269d21f3d98 100644
--- a/mlir/test/Dialect/Tosa/tosa-validation-version-1p1-valid.mlir
+++ b/mlir/test/Dialect/Tosa/tosa-validation-version-1p1-valid.mlir
@@ -183,6 +183,70 @@ func.func @test_scatter_const_indices_int64(%arg0: tensor<2x52x3xf32>, %arg2: te
// -----
+// CHECK-LABEL: test_gather_bool_i64
+func.func @test_gather_bool_i64(%arg0: tensor<13x21x3xi1>, %arg1: tensor<13x26xi64>) -> tensor<13x26x3xi1> {
+ %0 = tosa.gather %arg0, %arg1 : (tensor<13x21x3xi1>, tensor<13x26xi64>) -> tensor<13x26x3xi1>
+ return %0 : tensor<13x26x3xi1>
+}
+
+// -----
+
+// CHECK-LABEL: test_gather_bool_i32
+func.func @test_gather_bool_i32(%arg0: tensor<13x21x3xi1>, %arg1: tensor<13x26xi32>) -> tensor<13x26x3xi1> {
+ %0 = tosa.gather %arg0, %arg1 : (tensor<13x21x3xi1>, tensor<13x26xi32>) -> tensor<13x26x3xi1>
+ return %0 : tensor<13x26x3xi1>
+}
+
+// -----
+
+// CHECK-LABEL: test_scatter_bool_i64
+func.func @test_scatter_bool_i64(%arg0: tensor<13x52x3xi1>, %arg1: tensor<13x26xi64>, %arg2: tensor<13x26x3xi1>) -> tensor<13x52x3xi1> {
+ %0 = tosa.scatter %arg0, %arg1, %arg2 : (tensor<13x52x3xi1>, tensor<13x26xi64>, tensor<13x26x3xi1>) -> tensor<13x52x3xi1>
+ return %0 : tensor<13x52x3xi1>
+}
+
+// -----
+
+// CHECK-LABEL: test_scatter_bool_i32
+func.func @test_scatter_bool_i32(%arg0: tensor<13x52x3xi1>, %arg1: tensor<13x26xi32>, %arg2: tensor<13x26x3xi1>) -> tensor<13x52x3xi1> {
+ %0 = tosa.scatter %arg0, %arg1, %arg2 : (tensor<13x52x3xi1>, tensor<13x26xi32>, tensor<13x26x3xi1>) -> tensor<13x52x3xi1>
+ return %0 : tensor<13x52x3xi1>
+}
+
+// -----
+
+// CHECK-LABEL: test_cast_bool_fp32
+func.func @test_cast_bool_fp32(%arg0: tensor<13x21x3xi1>) -> tensor<13x21x3xf32> {
+ %0 = tosa.cast %arg0 : (tensor<13x21x3xi1>) -> tensor<13x21x3xf32>
+ return %0 : tensor<13x21x3xf32>
+}
+
+// -----
+
+// CHECK-LABEL: test_cast_bool_i64
+func.func @test_cast_bool_i64(%arg0: tensor<13x21x3xi1>) -> tensor<13x21x3xi64> {
+ %0 = tosa.cast %arg0 : (tensor<13x21x3xi1>) -> tensor<13x21x3xi64>
+ return %0 : tensor<13x21x3xi64>
+}
+
+// -----
+
+// CHECK-LABEL: test_cast_fp32_bool
+func.func @test_cast_fp32_bool(%arg0: tensor<13x21x3xf32>) -> tensor<13x21x3xi1> {
+ %0 = tosa.cast %arg0 : (tensor<13x21x3xf32>) -> tensor<13x21x3xi1>
+ return %0 : tensor<13x21x3xi1>
+}
+
+// -----
+
+// CHECK-LABEL: test_cast_i64_bool
+func.func @test_cast_i64_bool(%arg0: tensor<13x21x3xi64>) -> tensor<13x21x3xi1> {
+ %0 = tosa.cast %arg0 : (tensor<13x21x3xi64>) -> tensor<13x21x3xi1>
+ return %0 : tensor<13x21x3xi1>
+}
+
+// -----
+
// CHECK-LABEL: test_dynamic_dims
func.func @test_dynamic_dims(%arg0: tensor<?x8x16xi8>) -> tensor<?x16xi32> {
%0 = tosa.argmax %arg0 { axis = 1 : i32 } : (tensor<?x8x16xi8>) -> tensor<?x16xi32>
@@ -250,4 +314,4 @@ func.func @test_assert_equal_shape() {
%1 = tosa.const_shape {values = dense<[5, 2]> : tensor<2xindex>} : () -> !tosa.shape<2>
tosa.assert_equal_shape %0, %1 {allow_broadcast = true} : (!tosa.shape<2>, !tosa.shape<2>) -> ()
return
-}
\ No newline at end of file
+}
>From 7aae7ef97f95d33f3ecc956e2ab7b60aaddcc94d Mon Sep 17 00:00:00 2001
From: Luke Hutton <luke.hutton at arm.com>
Date: Wed, 4 Feb 2026 14:11:03 +0000
Subject: [PATCH 2/2] Address review comments
Change-Id: I91b963798b964929354ef00ddd552491b078b0cb
---
.../include/mlir/Dialect/Tosa/IR/TosaComplianceData.h.inc | 8 ++++----
.../Dialect/Tosa/tosa-validation-version-1p0-invalid.mlir | 4 ++--
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/mlir/include/mlir/Dialect/Tosa/IR/TosaComplianceData.h.inc b/mlir/include/mlir/Dialect/Tosa/IR/TosaComplianceData.h.inc
index 601649cd02854..a4eb3dd12bd54 100644
--- a/mlir/include/mlir/Dialect/Tosa/IR/TosaComplianceData.h.inc
+++ b/mlir/include/mlir/Dialect/Tosa/IR/TosaComplianceData.h.inc
@@ -373,8 +373,7 @@ profileComplianceMap = {
{{{fp16T, i32T, fp16T}, SpecificationVersion::V_1_0},
{{fp32T, i32T, fp32T}, SpecificationVersion::V_1_0}}},
{{Profile::pro_fp, Profile::pro_int},
- {{{boolT, i32T, boolT}, SpecificationVersion::V_1_1_DRAFT},
- {{boolT, i64T, boolT}, SpecificationVersion::V_1_1_DRAFT}},
+ {{{boolT, i32T, boolT}, SpecificationVersion::V_1_1_DRAFT}},
anyOf}}},
{"tosa.scatter",
{{{Profile::pro_int},
@@ -385,8 +384,9 @@ profileComplianceMap = {
{{{fp16T, i32T, fp16T, fp16T}, SpecificationVersion::V_1_0},
{{fp32T, i32T, fp32T, fp32T}, SpecificationVersion::V_1_0}}},
{{Profile::pro_fp, Profile::pro_int},
- {{{boolT, i32T, boolT, boolT}, SpecificationVersion::V_1_1_DRAFT},
- {{boolT, i64T, boolT, boolT}, SpecificationVersion::V_1_1_DRAFT}},
+ {
+ {{boolT, i32T, boolT, boolT}, SpecificationVersion::V_1_1_DRAFT},
+ },
anyOf}}},
{"tosa.resize",
{{{Profile::pro_int},
diff --git a/mlir/test/Dialect/Tosa/tosa-validation-version-1p0-invalid.mlir b/mlir/test/Dialect/Tosa/tosa-validation-version-1p0-invalid.mlir
index 0893afbc2f96b..fbd935d56fcc6 100644
--- a/mlir/test/Dialect/Tosa/tosa-validation-version-1p0-invalid.mlir
+++ b/mlir/test/Dialect/Tosa/tosa-validation-version-1p0-invalid.mlir
@@ -63,7 +63,7 @@ func.func @test_transpose_conv2d_fp8_acc32(%arg0: tensor<1x32x32x8xf8E5M2>, %arg
// -----
func.func @test_gather_bool_i64(%arg0: tensor<13x21x3xi1>, %arg1: tensor<13x26xi64>) -> tensor<13x26x3xi1> {
- // expected-error at +1 {{'tosa.gather' op illegal: the target specification version (1.0) is not backwards compatible with the op compliance specification version (1.1)}}
+ // expected-error at +1 {{'tosa.gather' op illegal: requires [int64] but not enabled in target}}
%0 = tosa.gather %arg0, %arg1 : (tensor<13x21x3xi1>, tensor<13x26xi64>) -> tensor<13x26x3xi1>
return %0 : tensor<13x26x3xi1>
}
@@ -79,7 +79,7 @@ func.func @test_gather_bool_i32(%arg0: tensor<13x21x3xi1>, %arg1: tensor<13x26xi
// -----
func.func @test_scatter_bool_i64(%arg0: tensor<13x52x3xi1>, %arg1: tensor<13x26xi64>, %arg2: tensor<13x26x3xi1>) -> tensor<13x52x3xi1> {
- // expected-error at +1 {{'tosa.scatter' op illegal: the target specification version (1.0) is not backwards compatible with the op compliance specification version (1.1)}}
+ // expected-error at +1 {{'tosa.scatter' op illegal: requires [int64] but not enabled in target}}
%0 = tosa.scatter %arg0, %arg1, %arg2 : (tensor<13x52x3xi1>, tensor<13x26xi64>, tensor<13x26x3xi1>) -> tensor<13x52x3xi1>
return %0 : tensor<13x52x3xi1>
}
More information about the Mlir-commits
mailing list