Skip to content

Conversation

Tai78641
Copy link
Contributor

@Tai78641 Tai78641 commented Aug 27, 2025

This commit updates the printer/parser of operations that use
enum type attributes such that they aren't required to specify
the full enum name e.g.
rounding_mode = #tosa.rounding_mode<SINGLE_ROUND> becomes
rounding_mode = SINGLE_ROUND.

For compatibility, text with #tosa.rounding_mode<...> will still be
accepted by the parser.

@llvmbot
Copy link
Member

llvmbot commented Aug 27, 2025

@llvm/pr-subscribers-mlir

@llvm/pr-subscribers-mlir-linalg

Author: Tai Ly (Tai78641)

Changes

This PR contains 2 commits:
@AnnuCode 's PR: 152856: [mlir][tosa] Convert TOSA enumerations from StringBasedAttr to Tosa_I32EnumAttr

and then a second commit on top of this, that implements custom assembly format parser and printer
for operators with enum type attributes such that they aren't required to specify
the full enum name e.g.
rounding_mode = #tosa.rounding_mode&lt;SINGLE_ROUND&gt; becomes
rounding_mode = SINGLE_ROUND.

For compatibility, text with #tosa.rounding_mode<...> will still be
accepted by the parser.


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

31 Files Affected:

  • (modified) mlir/include/mlir/Dialect/Tosa/IR/TosaOpBase.td (+33-12)
  • (modified) mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td (+126-11)
  • (modified) mlir/include/mlir/Dialect/Tosa/IR/TosaTypesBase.td (-23)
  • (modified) mlir/include/mlir/Dialect/Tosa/IR/TosaUtilOps.td (+2-2)
  • (modified) mlir/lib/Conversion/TosaToArith/TosaToArith.cpp (+8-6)
  • (modified) mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp (+22-19)
  • (modified) mlir/lib/Conversion/TosaToLinalg/TosaToLinalgNamed.cpp (+9-7)
  • (modified) mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp (+10-3)
  • (modified) mlir/lib/Dialect/Tosa/IR/TosaOps.cpp (+236)
  • (modified) mlir/lib/Dialect/Tosa/Transforms/TosaValidation.cpp (+3-3)
  • (modified) mlir/test/Conversion/TosaToArith/tosa-to-arith-invalid.mlir (+1-1)
  • (modified) mlir/test/Conversion/TosaToArith/tosa-to-arith.mlir (+4-4)
  • (modified) mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-invalid.mlir (+1-1)
  • (modified) mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-named.mlir (+4-4)
  • (modified) mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-resize.mlir (+16-16)
  • (modified) mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir (+42-42)
  • (modified) mlir/test/Dialect/Tosa/availability.mlir (+2-2)
  • (modified) mlir/test/Dialect/Tosa/canonicalize.mlir (+14-14)
  • (modified) mlir/test/Dialect/Tosa/dynamic_extension.mlir (+4-4)
  • (modified) mlir/test/Dialect/Tosa/error_if_check.mlir (+15-15)
  • (modified) mlir/test/Dialect/Tosa/invalid.mlir (+28-28)
  • (modified) mlir/test/Dialect/Tosa/invalid_extension.mlir (+7-7)
  • (modified) mlir/test/Dialect/Tosa/level_check.mlir (+4-4)
  • (modified) mlir/test/Dialect/Tosa/ops.mlir (+55-13)
  • (modified) mlir/test/Dialect/Tosa/profile_pro_fp_unsupported.mlir (+1-1)
  • (modified) mlir/test/Dialect/Tosa/profile_pro_int_unsupported.mlir (+2-2)
  • (modified) mlir/test/Dialect/Tosa/tosa-convert-integer-type-to-signless.mlir (+5-5)
  • (modified) mlir/test/Dialect/Tosa/tosa-infer-shapes.mlir (+10-10)
  • (modified) mlir/test/Dialect/Tosa/tosa-validation-valid.mlir (+2-2)
  • (modified) mlir/test/Dialect/Tosa/verifier.mlir (+1-1)
  • (modified) mlir/test/lib/Dialect/Tosa/TosaTestPasses.cpp (+3-1)
diff --git a/mlir/include/mlir/Dialect/Tosa/IR/TosaOpBase.td b/mlir/include/mlir/Dialect/Tosa/IR/TosaOpBase.td
index e048f8af7cc33..115a11b346780 100644
--- a/mlir/include/mlir/Dialect/Tosa/IR/TosaOpBase.td
+++ b/mlir/include/mlir/Dialect/Tosa/IR/TosaOpBase.td
@@ -381,6 +381,34 @@ class Extension<list<I32EnumAttrCase> extensions> : Availability {
   let instance = "ref";
 }
 
+//===----------------------------------------------------------------------===//
+// Iterable attributes.
+//===----------------------------------------------------------------------===//
+// Defined in `section 3. Enumerations` of the TOSA specification.
+
+def Tosa_RESIZE_NEAREST_NEIGHBOR          : I32EnumAttrCase<"NEAREST_NEIGHBOR", 1>;
+def Tosa_RESIZE_BILINEAR                  : I32EnumAttrCase<"BILINEAR", 2>;
+
+def Tosa_ResizeModeAttr
+    : Tosa_I32EnumAttr<"ResizeMode", "Supported resize/upsampling strategies", "resize_mode",
+                    [Tosa_RESIZE_NEAREST_NEIGHBOR, Tosa_RESIZE_BILINEAR]>;
+
+def Tosa_NANPROPAGATION_PROPAGATE : I32EnumAttrCase<"PROPAGATE", 1>;
+def Tosa_NANPROPAGATION_IGNORE    : I32EnumAttrCase<"IGNORE", 2>;
+
+def Tosa_NanPropagationModeAttr
+    : Tosa_I32EnumAttr<"NanPropagationMode", "Supported NaN propagation strategies", "nan_mode",
+                    [Tosa_NANPROPAGATION_PROPAGATE, Tosa_NANPROPAGATION_IGNORE]>;
+
+def Tosa_ROUNDING_SINGLE_ROUND    : I32EnumAttrCase<"SINGLE_ROUND", 1>;
+def Tosa_ROUNDING_INEXACT_ROUND   : I32EnumAttrCase<"INEXACT_ROUND", 2>;
+def Tosa_ROUNDING_DOUBLE_ROUND    : I32EnumAttrCase<"DOUBLE_ROUND", 3>;
+
+def Tosa_RoundingModeAttr
+    : Tosa_I32EnumAttr<"RoundingMode", "Supported rounding modes", "rounding_mode",
+                    [Tosa_ROUNDING_SINGLE_ROUND, Tosa_ROUNDING_INEXACT_ROUND, Tosa_ROUNDING_DOUBLE_ROUND]>;
+
+
 //===----------------------------------------------------------------------===//
 // TOSA Interfaces.
 //===----------------------------------------------------------------------===//
@@ -444,10 +472,7 @@ class Tosa_ElementwiseOp<string mnemonic, list<Trait> traits = []> :
               ResultsBroadcastableShape,
               TosaElementwiseOperator,
               SameOperandsAndResultRank,
-              Pure])> {
-  let assemblyFormat =
-      "operands attr-dict `:` functional-type(operands, results)";
-}
+              Pure])> {}
 
 class Tosa_ElementwiseUnaryOp<string mnemonic, list<Trait> traits = []> :
     Tosa_ElementwiseOp<mnemonic, !listconcat(traits, [
@@ -455,22 +480,18 @@ class Tosa_ElementwiseUnaryOp<string mnemonic, list<Trait> traits = []> :
               SameOperandsAndResultElementType])> {}
 
 class Tosa_InferTensorTypeOp<string mnemonic, list<Trait> traits = []>
-    : Tosa_Op<mnemonic, !listconcat(traits, [InferTensorTypeAdaptor, Pure])> {
-  let assemblyFormat =
-      "operands attr-dict `:` functional-type(operands, results)";
-}
+    : Tosa_Op<mnemonic, !listconcat(traits, [InferTensorTypeAdaptor, Pure])> {}
 
 class Tosa_InferShapedTypeOp<string mnemonic, list<Trait> traits = []>
-    : Tosa_Op<mnemonic, !listconcat(traits, [InferShapedTypeOpAdaptor, Pure])> {
-  let assemblyFormat =
-      "operands attr-dict `:` functional-type(operands, results)";
-}
+    : Tosa_Op<mnemonic, !listconcat(traits, [InferShapedTypeOpAdaptor, Pure])> {}
 
 // The "SameVariadicOperandSize" trait allows us to pass optional arguments
 // for multiple zero points in convolution ops.
 class Tosa_ConvOp<string mnemonic, list<Trait> traits = []>
     : Tosa_InferShapedTypeOp<mnemonic, !listconcat(traits,
       [SameVariadicOperandSize])> {
+  let assemblyFormat =
+      "operands attr-dict `:` functional-type(operands, results)";
 }
 
 #endif // TOSA_OP_BASE
diff --git a/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td b/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td
index 416df6e87b11f..953e7c304da85 100644
--- a/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td
+++ b/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td
@@ -43,7 +43,7 @@ def Tosa_ArgMaxOp : Tosa_InferShapedTypeOp<"argmax"> {
   let arguments = (ins
     Tosa_TensorAtLeast1D: $input,
     I32Attr: $axis,
-    DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode
+    DefaultValuedAttr<Tosa_NanPropagationModeAttr, "::mlir::tosa::NanPropagationMode::PROPAGATE">:$nan_mode
   );
 
   let results = (outs
@@ -57,6 +57,7 @@ def Tosa_ArgMaxOp : Tosa_InferShapedTypeOp<"argmax"> {
 
   let hasFolder = 1;
   let hasVerifier = 1;
+  let hasCustomAssemblyFormat = 1;
 }
 
 //===----------------------------------------------------------------------===//
@@ -109,6 +110,9 @@ def Tosa_AvgPool2dOp : Tosa_InferShapedTypeOp<"avg_pool2d"> {
 
   let hasCanonicalizer = 1;
   let hasVerifier = 1;
+
+  let assemblyFormat =
+      "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -299,6 +303,9 @@ def Tosa_FFT2dOp : Tosa_InferShapedTypeOp<"fft2d", [
   }];
 
   let hasVerifier = 1;
+
+  let assemblyFormat =
+      "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -336,6 +343,9 @@ def Tosa_MatMulOp : Tosa_InferShapedTypeOp<"matmul"> {
 
   let builders = [Tosa_MatMulOpQuantInfoBuilder];
   let hasVerifier = 1;
+
+  let assemblyFormat =
+      "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -357,7 +367,7 @@ def Tosa_MaxPool2dOp : Tosa_InferShapedTypeOp<"max_pool2d"> {
     Tosa_IntArrayAttr2:$kernel,
     Tosa_IntArrayAttr2:$stride,
     Tosa_IntArrayAttr4:$pad,
-    DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode
+    DefaultValuedAttr<Tosa_NanPropagationModeAttr, "::mlir::tosa::NanPropagationMode::PROPAGATE">:$nan_mode
   );
 
   let results = (outs
@@ -371,6 +381,7 @@ def Tosa_MaxPool2dOp : Tosa_InferShapedTypeOp<"max_pool2d"> {
 
   let hasCanonicalizer = 1;
   let hasVerifier = 1;
+  let hasCustomAssemblyFormat = 1;
 }
 
 //===----------------------------------------------------------------------===//
@@ -418,6 +429,9 @@ def Tosa_RFFT2dOp : Tosa_InferShapedTypeOp<"rfft2d", [
   }];
 
   let hasVerifier = 1;
+
+  let assemblyFormat =
+      "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -487,7 +501,7 @@ def Tosa_ClampOp : Tosa_ElementwiseUnaryOp<"clamp"> {
     Tosa_Tensor:$input,
     Tosa_IntOrFloatAttr:$min_val,
     Tosa_IntOrFloatAttr:$max_val,
-    DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode
+    DefaultValuedAttr<Tosa_NanPropagationModeAttr, "::mlir::tosa::NanPropagationMode::PROPAGATE">:$nan_mode
   );
 
   let results = (outs
@@ -501,6 +515,7 @@ def Tosa_ClampOp : Tosa_ElementwiseUnaryOp<"clamp"> {
 
   let hasCanonicalizer = 1;
   let hasVerifier = 1;
+  let hasCustomAssemblyFormat = 1;
 }
 
 //===----------------------------------------------------------------------===//
@@ -560,6 +575,8 @@ def Tosa_SigmoidOp : Tosa_ElementwiseUnaryOp<"sigmoid"> {
     Profile<[Tosa_PRO_FP]>,
     Extension<[Tosa_EXT_BF16]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -589,6 +606,8 @@ def Tosa_TanhOp : Tosa_ElementwiseUnaryOp<"tanh"> {
     Profile<[Tosa_PRO_FP]>,
     Extension<[Tosa_EXT_BF16]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -633,6 +652,8 @@ def Tosa_AddOp : Tosa_ElementwiseOp<"add", [
   ];
 
   let hasFolder = 1;
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -662,6 +683,8 @@ def Tosa_ArithmeticRightShiftOp : Tosa_ElementwiseOp<"arithmetic_right_shift",
     Profile<[Tosa_PRO_INT]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -690,6 +713,8 @@ def Tosa_BitwiseAndOp : Tosa_ElementwiseOp<"bitwise_and", [
     Profile<[Tosa_PRO_INT]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -718,6 +743,8 @@ def Tosa_BitwiseOrOp : Tosa_ElementwiseOp<"bitwise_or", [
     Profile<[Tosa_PRO_INT]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -746,6 +773,8 @@ def Tosa_BitwiseXorOp : Tosa_ElementwiseOp<"bitwise_xor", [
     Profile<[Tosa_PRO_INT]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -777,6 +806,8 @@ def Tosa_IntDivOp : Tosa_ElementwiseOp<"intdiv", [SameOperandsAndResultElementTy
   ];
 
   let hasFolder = 1;
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -805,6 +836,8 @@ def Tosa_LogicalAndOp : Tosa_ElementwiseOp<"logical_and", [
     Profile<[Tosa_PRO_INT, Tosa_PRO_FP]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -833,6 +866,8 @@ def Tosa_LogicalLeftShiftOp : Tosa_ElementwiseOp<"logical_left_shift",
     Profile<[Tosa_PRO_INT, Tosa_PRO_FP]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -861,6 +896,8 @@ def Tosa_LogicalRightShiftOp : Tosa_ElementwiseOp<"logical_right_shift",
     Profile<[Tosa_PRO_INT, Tosa_PRO_FP]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -889,6 +926,8 @@ def Tosa_LogicalOrOp : Tosa_ElementwiseOp<"logical_or", [
     Profile<[Tosa_PRO_INT, Tosa_PRO_FP]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -917,6 +956,8 @@ def Tosa_LogicalXorOp : Tosa_ElementwiseOp<"logical_xor", [
     Profile<[Tosa_PRO_INT, Tosa_PRO_FP]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -935,7 +976,7 @@ def Tosa_MaximumOp : Tosa_ElementwiseOp<"maximum", [
   let arguments = (ins
     Tosa_Tensor:$input1,
     Tosa_Tensor:$input2,
-    DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode
+    DefaultValuedAttr<Tosa_NanPropagationModeAttr, "::mlir::tosa::NanPropagationMode::PROPAGATE">:$nan_mode
   );
 
   let results = (outs
@@ -946,6 +987,7 @@ def Tosa_MaximumOp : Tosa_ElementwiseOp<"maximum", [
     Profile<[Tosa_PRO_INT, Tosa_PRO_FP]>,
     Extension<[Tosa_EXT_BF16]>,
   ];
+  let hasCustomAssemblyFormat = 1;
 }
 
 //===----------------------------------------------------------------------===//
@@ -964,7 +1006,7 @@ def Tosa_MinimumOp : Tosa_ElementwiseOp<"minimum", [
   let arguments = (ins
     Tosa_Tensor:$input1,
     Tosa_Tensor:$input2,
-    DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode
+    DefaultValuedAttr<Tosa_NanPropagationModeAttr, "::mlir::tosa::NanPropagationMode::PROPAGATE">:$nan_mode
   );
 
   let results = (outs
@@ -975,6 +1017,8 @@ def Tosa_MinimumOp : Tosa_ElementwiseOp<"minimum", [
     Profile<[Tosa_PRO_INT, Tosa_PRO_FP]>,
     Extension<[Tosa_EXT_BF16]>,
   ];
+
+  let hasCustomAssemblyFormat = 1;
 }
 
 //===----------------------------------------------------------------------===//
@@ -1041,6 +1085,8 @@ def Tosa_PowOp : Tosa_ElementwiseOp<"pow", [SameOperandsAndResultElementType]> {
     Profile<[Tosa_PRO_FP]>,
     Extension<[Tosa_EXT_BF16]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1069,6 +1115,8 @@ def Tosa_SubOp : Tosa_ElementwiseOp<"sub", [SameOperandsAndResultElementType]> {
   ];
 
   let hasFolder = 1;
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1113,6 +1161,9 @@ def Tosa_TableOp : Tosa_InferShapedTypeOp<"table"> {
   }];
 
   let hasVerifier = 1;
+
+  let assemblyFormat =
+      "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1149,6 +1200,8 @@ def Tosa_AbsOp : Tosa_ElementwiseUnaryOp<"abs"> {
   ];
 
   let hasFolder = 1;
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1173,6 +1226,8 @@ def Tosa_BitwiseNotOp : Tosa_ElementwiseUnaryOp<"bitwise_not"> {
     Profile<[Tosa_PRO_INT]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1197,6 +1252,8 @@ def Tosa_CeilOp : Tosa_ElementwiseUnaryOp<"ceil"> {
     Profile<[Tosa_PRO_FP]>,
     Extension<[Tosa_EXT_BF16]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1221,6 +1278,8 @@ def Tosa_ClzOp : Tosa_ElementwiseUnaryOp<"clz"> {
     Profile<[Tosa_PRO_INT]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1245,6 +1304,8 @@ def Tosa_CosOp : Tosa_ElementwiseUnaryOp<"cos"> {
     Profile<[Tosa_PRO_FP]>,
     Extension<[Tosa_EXT_BF16]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1271,6 +1332,8 @@ def Tosa_ExpOp : Tosa_ElementwiseUnaryOp<"exp"> {
   ];
 
   let hasFolder = 1;
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1295,6 +1358,8 @@ def Tosa_FloorOp : Tosa_ElementwiseUnaryOp<"floor"> {
     Profile<[Tosa_PRO_FP]>,
     Extension<[Tosa_EXT_BF16]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1321,6 +1386,8 @@ def Tosa_LogOp : Tosa_ElementwiseUnaryOp<"log"> {
   ];
 
   let hasFolder = 1;
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1345,6 +1412,8 @@ def Tosa_LogicalNotOp : Tosa_ElementwiseUnaryOp<"logical_not"> {
     Profile<[Tosa_PRO_INT, Tosa_PRO_FP]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1424,6 +1493,8 @@ def Tosa_ReciprocalOp : Tosa_ElementwiseUnaryOp<"reciprocal"> {
   }];
 
   let hasFolder = 1;
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1449,6 +1520,8 @@ def Tosa_RsqrtOp : Tosa_ElementwiseUnaryOp<"rsqrt"> {
     Profile<[Tosa_PRO_FP]>,
     Extension<[Tosa_EXT_BF16]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1473,6 +1546,8 @@ def Tosa_SinOp : Tosa_ElementwiseUnaryOp<"sin"> {
     Profile<[Tosa_PRO_FP]>,
     Extension<[Tosa_EXT_BF16]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1519,6 +1594,8 @@ def Tosa_SelectOp : Tosa_ElementwiseOp<"select"> {
     ::mlir::TypedValue<::mlir::TensorType> getOnTrue() { return getInput2(); }
     ::mlir::TypedValue<::mlir::TensorType> getOnFalse() { return getInput3(); }
   }];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1559,6 +1636,8 @@ def Tosa_EqualOp : Tosa_ElementwiseOp<"equal", [
   }];
 
   let hasFolder = 1;
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1586,6 +1665,8 @@ def Tosa_GreaterOp : Tosa_ElementwiseOp<"greater", [SameOperandsElementType]> {
   ];
 
   let hasFolder = 1;
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1614,6 +1695,8 @@ def Tosa_GreaterEqualOp : Tosa_ElementwiseOp<"greater_equal",
   ];
 
   let hasFolder = 1;
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1657,6 +1740,8 @@ def Tosa_ReduceAllOp : Tosa_InferTensorTypeOp<"reduce_all"> {
       return leftOperand & rightOperand;
     }
   }];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1696,6 +1781,8 @@ def Tosa_ReduceAnyOp : Tosa_InferTensorTypeOp<"reduce_any"> {
       return leftOperand | rightOperand;
     }
   }];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1711,7 +1798,7 @@ def Tosa_ReduceMaxOp : Tosa_InferTensorTypeOp<"reduce_max"> {
   let arguments = (ins
     Tosa_TensorAtLeast1D:$input,
     I32Attr:$axis,
-    DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode
+    DefaultValuedAttr<Tosa_NanPropagationModeAttr, "::mlir::tosa::NanPropagationMode::PROPAGATE">:$nan_mode
   );
 
   let results = (outs
@@ -1736,6 +1823,8 @@ def Tosa_ReduceMaxOp : Tosa_InferTensorTypeOp<"reduce_max"> {
       return (leftOperand.sge(rightOperand)) ? leftOperand : rightOperand;
     }
   }];
+
+  let hasCustomAssemblyFormat = 1;
 }
 
 //===----------------------------------------------------------------------===//
@@ -1751,7 +1840,7 @@ def Tosa_ReduceMinOp : Tosa_InferTensorTypeOp<"reduce_min"> {
   let arguments = (ins
     Tosa_TensorAtLeast1D:$input,
     I32Attr:$axis,
-    DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode
+    DefaultValuedAttr<Tosa_NanPropagationModeAttr, "::mlir::tosa::NanPropagationMode::PROPAGATE">:$nan_mode
   );
 
   let results = (outs
@@ -1776,6 +1865,8 @@ def Tosa_ReduceMinOp : Tosa_InferTensorTypeOp<"reduce_min"> {
       return (leftOperand.sle(rightOperand)) ? leftOperand : rightOperand;
     }
   }];
+
+  let hasCustomAssemblyFormat = 1;
 }
 
 //===----------------------------------------------------------------------===//
@@ -1815,6 +1906,8 @@ def Tosa_ReduceProductOp : Tosa_InferTensorTypeOp<"reduce_product"> {
       return leftOperand * rightOperand;
     }
   }];
+
+  let a...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Aug 27, 2025

@llvm/pr-subscribers-mlir-tosa

Author: Tai Ly (Tai78641)

Changes

This PR contains 2 commits:
@AnnuCode 's PR: 152856: [mlir][tosa] Convert TOSA enumerations from StringBasedAttr to Tosa_I32EnumAttr

and then a second commit on top of this, that implements custom assembly format parser and printer
for operators with enum type attributes such that they aren't required to specify
the full enum name e.g.
rounding_mode = #tosa.rounding_mode&lt;SINGLE_ROUND&gt; becomes
rounding_mode = SINGLE_ROUND.

For compatibility, text with #tosa.rounding_mode<...> will still be
accepted by the parser.


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

31 Files Affected:

  • (modified) mlir/include/mlir/Dialect/Tosa/IR/TosaOpBase.td (+33-12)
  • (modified) mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td (+126-11)
  • (modified) mlir/include/mlir/Dialect/Tosa/IR/TosaTypesBase.td (-23)
  • (modified) mlir/include/mlir/Dialect/Tosa/IR/TosaUtilOps.td (+2-2)
  • (modified) mlir/lib/Conversion/TosaToArith/TosaToArith.cpp (+8-6)
  • (modified) mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp (+22-19)
  • (modified) mlir/lib/Conversion/TosaToLinalg/TosaToLinalgNamed.cpp (+9-7)
  • (modified) mlir/lib/Dialect/Tosa/IR/TosaCanonicalizations.cpp (+10-3)
  • (modified) mlir/lib/Dialect/Tosa/IR/TosaOps.cpp (+236)
  • (modified) mlir/lib/Dialect/Tosa/Transforms/TosaValidation.cpp (+3-3)
  • (modified) mlir/test/Conversion/TosaToArith/tosa-to-arith-invalid.mlir (+1-1)
  • (modified) mlir/test/Conversion/TosaToArith/tosa-to-arith.mlir (+4-4)
  • (modified) mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-invalid.mlir (+1-1)
  • (modified) mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-named.mlir (+4-4)
  • (modified) mlir/test/Conversion/TosaToLinalg/tosa-to-linalg-resize.mlir (+16-16)
  • (modified) mlir/test/Conversion/TosaToLinalg/tosa-to-linalg.mlir (+42-42)
  • (modified) mlir/test/Dialect/Tosa/availability.mlir (+2-2)
  • (modified) mlir/test/Dialect/Tosa/canonicalize.mlir (+14-14)
  • (modified) mlir/test/Dialect/Tosa/dynamic_extension.mlir (+4-4)
  • (modified) mlir/test/Dialect/Tosa/error_if_check.mlir (+15-15)
  • (modified) mlir/test/Dialect/Tosa/invalid.mlir (+28-28)
  • (modified) mlir/test/Dialect/Tosa/invalid_extension.mlir (+7-7)
  • (modified) mlir/test/Dialect/Tosa/level_check.mlir (+4-4)
  • (modified) mlir/test/Dialect/Tosa/ops.mlir (+55-13)
  • (modified) mlir/test/Dialect/Tosa/profile_pro_fp_unsupported.mlir (+1-1)
  • (modified) mlir/test/Dialect/Tosa/profile_pro_int_unsupported.mlir (+2-2)
  • (modified) mlir/test/Dialect/Tosa/tosa-convert-integer-type-to-signless.mlir (+5-5)
  • (modified) mlir/test/Dialect/Tosa/tosa-infer-shapes.mlir (+10-10)
  • (modified) mlir/test/Dialect/Tosa/tosa-validation-valid.mlir (+2-2)
  • (modified) mlir/test/Dialect/Tosa/verifier.mlir (+1-1)
  • (modified) mlir/test/lib/Dialect/Tosa/TosaTestPasses.cpp (+3-1)
diff --git a/mlir/include/mlir/Dialect/Tosa/IR/TosaOpBase.td b/mlir/include/mlir/Dialect/Tosa/IR/TosaOpBase.td
index e048f8af7cc33..115a11b346780 100644
--- a/mlir/include/mlir/Dialect/Tosa/IR/TosaOpBase.td
+++ b/mlir/include/mlir/Dialect/Tosa/IR/TosaOpBase.td
@@ -381,6 +381,34 @@ class Extension<list<I32EnumAttrCase> extensions> : Availability {
   let instance = "ref";
 }
 
+//===----------------------------------------------------------------------===//
+// Iterable attributes.
+//===----------------------------------------------------------------------===//
+// Defined in `section 3. Enumerations` of the TOSA specification.
+
+def Tosa_RESIZE_NEAREST_NEIGHBOR          : I32EnumAttrCase<"NEAREST_NEIGHBOR", 1>;
+def Tosa_RESIZE_BILINEAR                  : I32EnumAttrCase<"BILINEAR", 2>;
+
+def Tosa_ResizeModeAttr
+    : Tosa_I32EnumAttr<"ResizeMode", "Supported resize/upsampling strategies", "resize_mode",
+                    [Tosa_RESIZE_NEAREST_NEIGHBOR, Tosa_RESIZE_BILINEAR]>;
+
+def Tosa_NANPROPAGATION_PROPAGATE : I32EnumAttrCase<"PROPAGATE", 1>;
+def Tosa_NANPROPAGATION_IGNORE    : I32EnumAttrCase<"IGNORE", 2>;
+
+def Tosa_NanPropagationModeAttr
+    : Tosa_I32EnumAttr<"NanPropagationMode", "Supported NaN propagation strategies", "nan_mode",
+                    [Tosa_NANPROPAGATION_PROPAGATE, Tosa_NANPROPAGATION_IGNORE]>;
+
+def Tosa_ROUNDING_SINGLE_ROUND    : I32EnumAttrCase<"SINGLE_ROUND", 1>;
+def Tosa_ROUNDING_INEXACT_ROUND   : I32EnumAttrCase<"INEXACT_ROUND", 2>;
+def Tosa_ROUNDING_DOUBLE_ROUND    : I32EnumAttrCase<"DOUBLE_ROUND", 3>;
+
+def Tosa_RoundingModeAttr
+    : Tosa_I32EnumAttr<"RoundingMode", "Supported rounding modes", "rounding_mode",
+                    [Tosa_ROUNDING_SINGLE_ROUND, Tosa_ROUNDING_INEXACT_ROUND, Tosa_ROUNDING_DOUBLE_ROUND]>;
+
+
 //===----------------------------------------------------------------------===//
 // TOSA Interfaces.
 //===----------------------------------------------------------------------===//
@@ -444,10 +472,7 @@ class Tosa_ElementwiseOp<string mnemonic, list<Trait> traits = []> :
               ResultsBroadcastableShape,
               TosaElementwiseOperator,
               SameOperandsAndResultRank,
-              Pure])> {
-  let assemblyFormat =
-      "operands attr-dict `:` functional-type(operands, results)";
-}
+              Pure])> {}
 
 class Tosa_ElementwiseUnaryOp<string mnemonic, list<Trait> traits = []> :
     Tosa_ElementwiseOp<mnemonic, !listconcat(traits, [
@@ -455,22 +480,18 @@ class Tosa_ElementwiseUnaryOp<string mnemonic, list<Trait> traits = []> :
               SameOperandsAndResultElementType])> {}
 
 class Tosa_InferTensorTypeOp<string mnemonic, list<Trait> traits = []>
-    : Tosa_Op<mnemonic, !listconcat(traits, [InferTensorTypeAdaptor, Pure])> {
-  let assemblyFormat =
-      "operands attr-dict `:` functional-type(operands, results)";
-}
+    : Tosa_Op<mnemonic, !listconcat(traits, [InferTensorTypeAdaptor, Pure])> {}
 
 class Tosa_InferShapedTypeOp<string mnemonic, list<Trait> traits = []>
-    : Tosa_Op<mnemonic, !listconcat(traits, [InferShapedTypeOpAdaptor, Pure])> {
-  let assemblyFormat =
-      "operands attr-dict `:` functional-type(operands, results)";
-}
+    : Tosa_Op<mnemonic, !listconcat(traits, [InferShapedTypeOpAdaptor, Pure])> {}
 
 // The "SameVariadicOperandSize" trait allows us to pass optional arguments
 // for multiple zero points in convolution ops.
 class Tosa_ConvOp<string mnemonic, list<Trait> traits = []>
     : Tosa_InferShapedTypeOp<mnemonic, !listconcat(traits,
       [SameVariadicOperandSize])> {
+  let assemblyFormat =
+      "operands attr-dict `:` functional-type(operands, results)";
 }
 
 #endif // TOSA_OP_BASE
diff --git a/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td b/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td
index 416df6e87b11f..953e7c304da85 100644
--- a/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td
+++ b/mlir/include/mlir/Dialect/Tosa/IR/TosaOps.td
@@ -43,7 +43,7 @@ def Tosa_ArgMaxOp : Tosa_InferShapedTypeOp<"argmax"> {
   let arguments = (ins
     Tosa_TensorAtLeast1D: $input,
     I32Attr: $axis,
-    DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode
+    DefaultValuedAttr<Tosa_NanPropagationModeAttr, "::mlir::tosa::NanPropagationMode::PROPAGATE">:$nan_mode
   );
 
   let results = (outs
@@ -57,6 +57,7 @@ def Tosa_ArgMaxOp : Tosa_InferShapedTypeOp<"argmax"> {
 
   let hasFolder = 1;
   let hasVerifier = 1;
+  let hasCustomAssemblyFormat = 1;
 }
 
 //===----------------------------------------------------------------------===//
@@ -109,6 +110,9 @@ def Tosa_AvgPool2dOp : Tosa_InferShapedTypeOp<"avg_pool2d"> {
 
   let hasCanonicalizer = 1;
   let hasVerifier = 1;
+
+  let assemblyFormat =
+      "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -299,6 +303,9 @@ def Tosa_FFT2dOp : Tosa_InferShapedTypeOp<"fft2d", [
   }];
 
   let hasVerifier = 1;
+
+  let assemblyFormat =
+      "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -336,6 +343,9 @@ def Tosa_MatMulOp : Tosa_InferShapedTypeOp<"matmul"> {
 
   let builders = [Tosa_MatMulOpQuantInfoBuilder];
   let hasVerifier = 1;
+
+  let assemblyFormat =
+      "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -357,7 +367,7 @@ def Tosa_MaxPool2dOp : Tosa_InferShapedTypeOp<"max_pool2d"> {
     Tosa_IntArrayAttr2:$kernel,
     Tosa_IntArrayAttr2:$stride,
     Tosa_IntArrayAttr4:$pad,
-    DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode
+    DefaultValuedAttr<Tosa_NanPropagationModeAttr, "::mlir::tosa::NanPropagationMode::PROPAGATE">:$nan_mode
   );
 
   let results = (outs
@@ -371,6 +381,7 @@ def Tosa_MaxPool2dOp : Tosa_InferShapedTypeOp<"max_pool2d"> {
 
   let hasCanonicalizer = 1;
   let hasVerifier = 1;
+  let hasCustomAssemblyFormat = 1;
 }
 
 //===----------------------------------------------------------------------===//
@@ -418,6 +429,9 @@ def Tosa_RFFT2dOp : Tosa_InferShapedTypeOp<"rfft2d", [
   }];
 
   let hasVerifier = 1;
+
+  let assemblyFormat =
+      "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -487,7 +501,7 @@ def Tosa_ClampOp : Tosa_ElementwiseUnaryOp<"clamp"> {
     Tosa_Tensor:$input,
     Tosa_IntOrFloatAttr:$min_val,
     Tosa_IntOrFloatAttr:$max_val,
-    DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode
+    DefaultValuedAttr<Tosa_NanPropagationModeAttr, "::mlir::tosa::NanPropagationMode::PROPAGATE">:$nan_mode
   );
 
   let results = (outs
@@ -501,6 +515,7 @@ def Tosa_ClampOp : Tosa_ElementwiseUnaryOp<"clamp"> {
 
   let hasCanonicalizer = 1;
   let hasVerifier = 1;
+  let hasCustomAssemblyFormat = 1;
 }
 
 //===----------------------------------------------------------------------===//
@@ -560,6 +575,8 @@ def Tosa_SigmoidOp : Tosa_ElementwiseUnaryOp<"sigmoid"> {
     Profile<[Tosa_PRO_FP]>,
     Extension<[Tosa_EXT_BF16]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -589,6 +606,8 @@ def Tosa_TanhOp : Tosa_ElementwiseUnaryOp<"tanh"> {
     Profile<[Tosa_PRO_FP]>,
     Extension<[Tosa_EXT_BF16]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -633,6 +652,8 @@ def Tosa_AddOp : Tosa_ElementwiseOp<"add", [
   ];
 
   let hasFolder = 1;
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -662,6 +683,8 @@ def Tosa_ArithmeticRightShiftOp : Tosa_ElementwiseOp<"arithmetic_right_shift",
     Profile<[Tosa_PRO_INT]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -690,6 +713,8 @@ def Tosa_BitwiseAndOp : Tosa_ElementwiseOp<"bitwise_and", [
     Profile<[Tosa_PRO_INT]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -718,6 +743,8 @@ def Tosa_BitwiseOrOp : Tosa_ElementwiseOp<"bitwise_or", [
     Profile<[Tosa_PRO_INT]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -746,6 +773,8 @@ def Tosa_BitwiseXorOp : Tosa_ElementwiseOp<"bitwise_xor", [
     Profile<[Tosa_PRO_INT]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -777,6 +806,8 @@ def Tosa_IntDivOp : Tosa_ElementwiseOp<"intdiv", [SameOperandsAndResultElementTy
   ];
 
   let hasFolder = 1;
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -805,6 +836,8 @@ def Tosa_LogicalAndOp : Tosa_ElementwiseOp<"logical_and", [
     Profile<[Tosa_PRO_INT, Tosa_PRO_FP]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -833,6 +866,8 @@ def Tosa_LogicalLeftShiftOp : Tosa_ElementwiseOp<"logical_left_shift",
     Profile<[Tosa_PRO_INT, Tosa_PRO_FP]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -861,6 +896,8 @@ def Tosa_LogicalRightShiftOp : Tosa_ElementwiseOp<"logical_right_shift",
     Profile<[Tosa_PRO_INT, Tosa_PRO_FP]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -889,6 +926,8 @@ def Tosa_LogicalOrOp : Tosa_ElementwiseOp<"logical_or", [
     Profile<[Tosa_PRO_INT, Tosa_PRO_FP]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -917,6 +956,8 @@ def Tosa_LogicalXorOp : Tosa_ElementwiseOp<"logical_xor", [
     Profile<[Tosa_PRO_INT, Tosa_PRO_FP]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -935,7 +976,7 @@ def Tosa_MaximumOp : Tosa_ElementwiseOp<"maximum", [
   let arguments = (ins
     Tosa_Tensor:$input1,
     Tosa_Tensor:$input2,
-    DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode
+    DefaultValuedAttr<Tosa_NanPropagationModeAttr, "::mlir::tosa::NanPropagationMode::PROPAGATE">:$nan_mode
   );
 
   let results = (outs
@@ -946,6 +987,7 @@ def Tosa_MaximumOp : Tosa_ElementwiseOp<"maximum", [
     Profile<[Tosa_PRO_INT, Tosa_PRO_FP]>,
     Extension<[Tosa_EXT_BF16]>,
   ];
+  let hasCustomAssemblyFormat = 1;
 }
 
 //===----------------------------------------------------------------------===//
@@ -964,7 +1006,7 @@ def Tosa_MinimumOp : Tosa_ElementwiseOp<"minimum", [
   let arguments = (ins
     Tosa_Tensor:$input1,
     Tosa_Tensor:$input2,
-    DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode
+    DefaultValuedAttr<Tosa_NanPropagationModeAttr, "::mlir::tosa::NanPropagationMode::PROPAGATE">:$nan_mode
   );
 
   let results = (outs
@@ -975,6 +1017,8 @@ def Tosa_MinimumOp : Tosa_ElementwiseOp<"minimum", [
     Profile<[Tosa_PRO_INT, Tosa_PRO_FP]>,
     Extension<[Tosa_EXT_BF16]>,
   ];
+
+  let hasCustomAssemblyFormat = 1;
 }
 
 //===----------------------------------------------------------------------===//
@@ -1041,6 +1085,8 @@ def Tosa_PowOp : Tosa_ElementwiseOp<"pow", [SameOperandsAndResultElementType]> {
     Profile<[Tosa_PRO_FP]>,
     Extension<[Tosa_EXT_BF16]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1069,6 +1115,8 @@ def Tosa_SubOp : Tosa_ElementwiseOp<"sub", [SameOperandsAndResultElementType]> {
   ];
 
   let hasFolder = 1;
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1113,6 +1161,9 @@ def Tosa_TableOp : Tosa_InferShapedTypeOp<"table"> {
   }];
 
   let hasVerifier = 1;
+
+  let assemblyFormat =
+      "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1149,6 +1200,8 @@ def Tosa_AbsOp : Tosa_ElementwiseUnaryOp<"abs"> {
   ];
 
   let hasFolder = 1;
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1173,6 +1226,8 @@ def Tosa_BitwiseNotOp : Tosa_ElementwiseUnaryOp<"bitwise_not"> {
     Profile<[Tosa_PRO_INT]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1197,6 +1252,8 @@ def Tosa_CeilOp : Tosa_ElementwiseUnaryOp<"ceil"> {
     Profile<[Tosa_PRO_FP]>,
     Extension<[Tosa_EXT_BF16]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1221,6 +1278,8 @@ def Tosa_ClzOp : Tosa_ElementwiseUnaryOp<"clz"> {
     Profile<[Tosa_PRO_INT]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1245,6 +1304,8 @@ def Tosa_CosOp : Tosa_ElementwiseUnaryOp<"cos"> {
     Profile<[Tosa_PRO_FP]>,
     Extension<[Tosa_EXT_BF16]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1271,6 +1332,8 @@ def Tosa_ExpOp : Tosa_ElementwiseUnaryOp<"exp"> {
   ];
 
   let hasFolder = 1;
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1295,6 +1358,8 @@ def Tosa_FloorOp : Tosa_ElementwiseUnaryOp<"floor"> {
     Profile<[Tosa_PRO_FP]>,
     Extension<[Tosa_EXT_BF16]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1321,6 +1386,8 @@ def Tosa_LogOp : Tosa_ElementwiseUnaryOp<"log"> {
   ];
 
   let hasFolder = 1;
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1345,6 +1412,8 @@ def Tosa_LogicalNotOp : Tosa_ElementwiseUnaryOp<"logical_not"> {
     Profile<[Tosa_PRO_INT, Tosa_PRO_FP]>,
     Extension<[]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1424,6 +1493,8 @@ def Tosa_ReciprocalOp : Tosa_ElementwiseUnaryOp<"reciprocal"> {
   }];
 
   let hasFolder = 1;
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1449,6 +1520,8 @@ def Tosa_RsqrtOp : Tosa_ElementwiseUnaryOp<"rsqrt"> {
     Profile<[Tosa_PRO_FP]>,
     Extension<[Tosa_EXT_BF16]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1473,6 +1546,8 @@ def Tosa_SinOp : Tosa_ElementwiseUnaryOp<"sin"> {
     Profile<[Tosa_PRO_FP]>,
     Extension<[Tosa_EXT_BF16]>,
   ];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1519,6 +1594,8 @@ def Tosa_SelectOp : Tosa_ElementwiseOp<"select"> {
     ::mlir::TypedValue<::mlir::TensorType> getOnTrue() { return getInput2(); }
     ::mlir::TypedValue<::mlir::TensorType> getOnFalse() { return getInput3(); }
   }];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1559,6 +1636,8 @@ def Tosa_EqualOp : Tosa_ElementwiseOp<"equal", [
   }];
 
   let hasFolder = 1;
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1586,6 +1665,8 @@ def Tosa_GreaterOp : Tosa_ElementwiseOp<"greater", [SameOperandsElementType]> {
   ];
 
   let hasFolder = 1;
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1614,6 +1695,8 @@ def Tosa_GreaterEqualOp : Tosa_ElementwiseOp<"greater_equal",
   ];
 
   let hasFolder = 1;
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1657,6 +1740,8 @@ def Tosa_ReduceAllOp : Tosa_InferTensorTypeOp<"reduce_all"> {
       return leftOperand & rightOperand;
     }
   }];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1696,6 +1781,8 @@ def Tosa_ReduceAnyOp : Tosa_InferTensorTypeOp<"reduce_any"> {
       return leftOperand | rightOperand;
     }
   }];
+
+  let assemblyFormat = "operands attr-dict `:` functional-type(operands, results)";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1711,7 +1798,7 @@ def Tosa_ReduceMaxOp : Tosa_InferTensorTypeOp<"reduce_max"> {
   let arguments = (ins
     Tosa_TensorAtLeast1D:$input,
     I32Attr:$axis,
-    DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode
+    DefaultValuedAttr<Tosa_NanPropagationModeAttr, "::mlir::tosa::NanPropagationMode::PROPAGATE">:$nan_mode
   );
 
   let results = (outs
@@ -1736,6 +1823,8 @@ def Tosa_ReduceMaxOp : Tosa_InferTensorTypeOp<"reduce_max"> {
       return (leftOperand.sge(rightOperand)) ? leftOperand : rightOperand;
     }
   }];
+
+  let hasCustomAssemblyFormat = 1;
 }
 
 //===----------------------------------------------------------------------===//
@@ -1751,7 +1840,7 @@ def Tosa_ReduceMinOp : Tosa_InferTensorTypeOp<"reduce_min"> {
   let arguments = (ins
     Tosa_TensorAtLeast1D:$input,
     I32Attr:$axis,
-    DefaultValuedAttr<Tosa_NanPropagationAttr, "\"PROPAGATE\"">:$nan_mode
+    DefaultValuedAttr<Tosa_NanPropagationModeAttr, "::mlir::tosa::NanPropagationMode::PROPAGATE">:$nan_mode
   );
 
   let results = (outs
@@ -1776,6 +1865,8 @@ def Tosa_ReduceMinOp : Tosa_InferTensorTypeOp<"reduce_min"> {
       return (leftOperand.sle(rightOperand)) ? leftOperand : rightOperand;
     }
   }];
+
+  let hasCustomAssemblyFormat = 1;
 }
 
 //===----------------------------------------------------------------------===//
@@ -1815,6 +1906,8 @@ def Tosa_ReduceProductOp : Tosa_InferTensorTypeOp<"reduce_product"> {
       return leftOperand * rightOperand;
     }
   }];
+
+  let a...
[truncated]

@Tai78641
Copy link
Contributor Author

@AnnuCode This PR is on top of your PR.
please review. Lets figure out how best to get this merged in together.
thanks!

Copy link

github-actions bot commented Aug 27, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@Tai78641 Tai78641 force-pushed the pr_tosa_enums branch 2 times, most recently from 04299d1 to 8faa712 Compare August 27, 2025 21:47
@lhutton1
Copy link
Contributor

I just wanted to add some context here. While updating other dependencies (e.g. TensorFlow) @Tai78641 suggested it would be nice if we avoided the need for using the full enum name in the textual format e.g. go from #tosa.rounding_mode<SINGLE_ROUND> to SINGLE_ROUND.

Thanks for your patience here @AnnuCode, this was certainly more work than I was expecting for a "first-issue" task!

@AnnuCode
Copy link
Contributor

AnnuCode commented Aug 28, 2025

@Tai78641, thanks for making it easier to use these attributes!

Thanks, @lhutton1! I got to learn about how a change in upstream trickles down to dependencies.

@Tai78641 Tai78641 force-pushed the pr_tosa_enums branch 2 times, most recently from d13baf8 to bf29a4f Compare August 28, 2025 15:51
AnnuCode and others added 2 commits August 29, 2025 14:35
… enumerations.

This PR replaces `StringBasedAttr` with `Tosa_I32EnumAttr` to represent Tosa enumerations as per the specification.
The intent is to make the IR and C++ APIs more type-safe and prevent fragile string comparisons in passes.

Enumerations rewritten are:

- `Tosa_ResizeTypeAttr`
- `Tosa_NanPropagationAttr`
- `Tosa_RoundingTypeAttr`

BREAKING CHANGE:

This commit changes attribute assembly and the C++ API surface for the listed attributes.
Code that previously used `StringAttr` for these fields must now be updated to use the new enum representation.
In `.mlir` files, replace string literals with the enum assembly (e.g. `mode = #tosa.resize_type<BILINEAR>`).
In C++, update call sites to either pass the generated enum (e.g. `::mlir::tosa::RoundingType::SINGLE_ROUND`) into builder overloads or construct the typed attribute with `tosa::RoundingTypeAttr::get(context, /*enum*/)` and pass that.

Change-Id: Ic101ddfc3bef73a08ab2d6f59f54598c8e0dbad8
This commit updates the printer/parser of operations that use
enum type attributes such that they aren't required to specify
the full enum name e.g.
`rounding_mode = #tosa.rounding_mode<SINGLE_ROUND>` becomes
`rounding_mode = SINGLE_ROUND`.

For compatibility, text with #tosa.rounding_mode<...> will still be
accepted by the parser.

Change-Id: Ic19c961069a297d442450fdab3dc727b0b64bd1a
Signed-off-by: Tai Ly <tai.ly@arm.com>
@Tai78641 Tai78641 changed the title [mlir][tosa] Use Tosa_I32EnumAttr to represent Tosa enumerations [mlir][tosa] Avoid requirement to specify enum name for enum attributes Aug 29, 2025
Copy link
Contributor

@lhutton1 lhutton1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@lhutton1 lhutton1 merged commit 13471e1 into llvm:main Aug 29, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants