[Mlir-commits] [mlir] [MLIR] Add support for int8/uint8 properties (PR #145019)

Mehdi Amini llvmlistbot at llvm.org
Fri Jun 20 04:22:08 PDT 2025


https://github.com/joker-eph updated https://github.com/llvm/llvm-project/pull/145019

>From 577226f75002e63d1fe697c47305457d808492f8 Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Fri, 20 Jun 2025 04:03:49 -0700
Subject: [PATCH 1/2] [MLIR] Add support for int8/uint8 properties

---
 mlir/include/mlir/IR/ODSSupport.h       | 20 +++++++++++++++
 mlir/include/mlir/IR/OpImplementation.h | 13 ++++++++++
 mlir/include/mlir/IR/Properties.td      |  1 +
 mlir/lib/IR/ODSSupport.cpp              | 34 +++++++++++++++++++++++++
 mlir/test/IR/properties.mlir            | 10 ++++++--
 mlir/test/lib/Dialect/Test/TestOps.td   |  4 +++
 6 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/mlir/include/mlir/IR/ODSSupport.h b/mlir/include/mlir/IR/ODSSupport.h
index 25d6f3da6a861..b24a2470470ff 100644
--- a/mlir/include/mlir/IR/ODSSupport.h
+++ b/mlir/include/mlir/IR/ODSSupport.h
@@ -43,6 +43,26 @@ convertFromAttribute(int32_t &storage, Attribute attr,
 /// Convert the provided int32_t to an IntegerAttr attribute.
 Attribute convertToAttribute(MLIRContext *ctx, int32_t storage);
 
+/// Convert an IntegerAttr attribute to an int8_t, or return an error if the
+/// attribute isn't an IntegerAttr. If the optional diagnostic is provided an
+/// error message is also emitted.
+LogicalResult
+convertFromAttribute(int8_t &storage, Attribute attr,
+                     function_ref<InFlightDiagnostic()> emitError);
+
+/// Convert the provided int8_t to an IntegerAttr attribute.
+Attribute convertToAttribute(MLIRContext *ctx, int8_t storage);
+
+/// Convert an IntegerAttr attribute to an uint8_t, or return an error if the
+/// attribute isn't an IntegerAttr. If the optional diagnostic is provided an
+/// error message is also emitted.
+LogicalResult
+convertFromAttribute(uint8_t &storage, Attribute attr,
+                     function_ref<InFlightDiagnostic()> emitError);
+
+/// Convert the provided uint8_t to an IntegerAttr attribute.
+Attribute convertToAttribute(MLIRContext *ctx, uint8_t storage);
+
 /// Extract the string from `attr` into `storage`. If `attr` is not a
 /// `StringAttr`, return failure and emit an error into the diagnostic from
 /// `emitError`.
diff --git a/mlir/include/mlir/IR/OpImplementation.h b/mlir/include/mlir/IR/OpImplementation.h
index 8b56d81c8eecc..8710b970e8d75 100644
--- a/mlir/include/mlir/IR/OpImplementation.h
+++ b/mlir/include/mlir/IR/OpImplementation.h
@@ -135,6 +135,19 @@ class AsmPrinter {
   /// hook on the AsmParser.
   virtual void printFloat(const APFloat &value);
 
+  /// Print the given integer value. This is useful to force a uint8_t/int8_t to
+  /// be printed as an integer instead of a char.
+  template <typename IntT>
+  std::enable_if_t<std::is_integral_v<IntT>, void> printInteger(IntT value) {
+    // Handle int8_t/uint8_t specially to avoid printing as char
+    if constexpr (std::is_same_v<IntT, int8_t> ||
+                  std::is_same_v<IntT, uint8_t>) {
+      getStream() << static_cast<int>(value);
+    } else {
+      getStream() << value;
+    }
+  }
+
   virtual void printType(Type type);
   virtual void printAttribute(Attribute attr);
 
diff --git a/mlir/include/mlir/IR/Properties.td b/mlir/include/mlir/IR/Properties.td
index 25a45489c7b53..1aa19d0ecfa3a 100644
--- a/mlir/include/mlir/IR/Properties.td
+++ b/mlir/include/mlir/IR/Properties.td
@@ -219,6 +219,7 @@ class IntProp<string storageTypeParam, string desc = ""> :
   let optionalParser = [{
     return $_parser.parseOptionalInteger($_storage);
   }];
+  let printer = "$_printer.printInteger($_storage)";
   let writeToMlirBytecode = [{
     $_writer.writeVarInt($_storage);
   }];
diff --git a/mlir/lib/IR/ODSSupport.cpp b/mlir/lib/IR/ODSSupport.cpp
index d56c75ede9849..b8bad1f1b098f 100644
--- a/mlir/lib/IR/ODSSupport.cpp
+++ b/mlir/lib/IR/ODSSupport.cpp
@@ -48,6 +48,40 @@ Attribute mlir::convertToAttribute(MLIRContext *ctx, int32_t storage) {
   return IntegerAttr::get(IntegerType::get(ctx, 32), storage);
 }
 
+LogicalResult
+mlir::convertFromAttribute(int8_t &storage, Attribute attr,
+                           function_ref<InFlightDiagnostic()> emitError) {
+  auto valueAttr = dyn_cast<IntegerAttr>(attr);
+  if (!valueAttr) {
+    emitError() << "expected IntegerAttr for key `value`";
+    return failure();
+  }
+  storage = valueAttr.getValue().getZExtValue();
+  return success();
+}
+
+Attribute mlir::convertToAttribute(MLIRContext *ctx, int8_t storage) {
+  /// Convert the provided int8_t to an IntegerAttr attribute.
+  return IntegerAttr::get(IntegerType::get(ctx, 8), storage);
+}
+
+LogicalResult
+mlir::convertFromAttribute(uint8_t &storage, Attribute attr,
+                           function_ref<InFlightDiagnostic()> emitError) {
+  auto valueAttr = dyn_cast<IntegerAttr>(attr);
+  if (!valueAttr) {
+    emitError() << "expected IntegerAttr for key `value`";
+    return failure();
+  }
+  storage = valueAttr.getValue().getZExtValue();
+  return success();
+}
+
+Attribute mlir::convertToAttribute(MLIRContext *ctx, uint8_t storage) {
+  /// Convert the provided uint8_t to an IntegerAttr attribute.
+  return IntegerAttr::get(IntegerType::get(ctx, 8), storage);
+}
+
 LogicalResult
 mlir::convertFromAttribute(std::string &storage, Attribute attr,
                            function_ref<InFlightDiagnostic()> emitError) {
diff --git a/mlir/test/IR/properties.mlir b/mlir/test/IR/properties.mlir
index b339a03812bad..dde9100cde142 100644
--- a/mlir/test/IR/properties.mlir
+++ b/mlir/test/IR/properties.mlir
@@ -59,9 +59,15 @@ test.with_default_valued_properties 1 "foo" 0 unit
 // CHECK:   test.with_optional_properties
 // CHECK-SAME: simple = 0
 // GENERIC: "test.with_optional_properties"()
-// GENERIC-SAME:  <{hasDefault = [], hasUnit = false, longSyntax = [], maybeUnit = [], nested = [], nonTrivialStorage = [], simple = [0]}> : () -> ()
+// GENERIC-SAME:  <{hasDefault = [], hasUnit = false, longSyntax = [], maybeUnit = [], nested = [], nonTrivialStorage = [], simple = [0], simplei8 = [], simpleui8 = []}> : () -> ()
 test.with_optional_properties simple = 0
 
+// CHECK:   test.with_optional_properties
+// CHECK-SAME: simple = 1 simplei8 = -1 simpleui8 = 255
+// GENERIC: "test.with_optional_properties"()
+// GENERIC-SAME:  <{hasDefault = [], hasUnit = false, longSyntax = [], maybeUnit = [], nested = [], nonTrivialStorage = [], simple = [1], simplei8 = [-1 : i8], simpleui8 = [-1 : i8]}> : () -> ()
+test.with_optional_properties simple = 1 simplei8 = -1 simpleui8 = 255
+
 // CHECK:   test.with_optional_properties{{$}}
 // GENERIC: "test.with_optional_properties"()
 // GENERIC-SAME: simple = []
@@ -70,7 +76,7 @@ test.with_optional_properties
 // CHECK:    test.with_optional_properties
 // CHECK-SAME: anAttr = 0 simple = 1 nonTrivialStorage = "foo" hasDefault = some<0> nested = some<1>  longSyntax = some<"bar"> hasUnit maybeUnit = some<unit>
 // GENERIC: "test.with_optional_properties"()
-// GENERIC-SAME: <{anAttr = 0 : i32, hasDefault = [0], hasUnit, longSyntax = ["bar"], maybeUnit = [unit], nested = {{\[}}[1]], nonTrivialStorage = ["foo"], simple = [1]}> : () -> ()
+// GENERIC-SAME: <{anAttr = 0 : i32, hasDefault = [0], hasUnit, longSyntax = ["bar"], maybeUnit = [unit], nested = {{\[}}[1]], nonTrivialStorage = ["foo"], simple = [1], simplei8 = [], simpleui8 = []}> : () -> ()
 test.with_optional_properties
   anAttr = 0
   simple = 1
diff --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td
index 79bcd9c2e0a9a..d7554f1a83446 100644
--- a/mlir/test/lib/Dialect/Test/TestOps.td
+++ b/mlir/test/lib/Dialect/Test/TestOps.td
@@ -3387,6 +3387,8 @@ def TestOpWithOptionalProperties : TEST_Op<"with_optional_properties"> {
   let assemblyFormat = [{
     (`anAttr` `=` $anAttr^)?
     (`simple` `=` $simple^)?
+    (`simplei8` `=` $simplei8^)?
+    (`simpleui8` `=` $simpleui8^)?
     (`nonTrivialStorage` `=` $nonTrivialStorage^)?
     (`hasDefault` `=` $hasDefault^)?
     (`nested` `=` $nested^)?
@@ -3398,6 +3400,8 @@ def TestOpWithOptionalProperties : TEST_Op<"with_optional_properties"> {
   let arguments = (ins
     OptionalAttr<I32Attr>:$anAttr,
     OptionalProp<I64Prop>:$simple,
+    OptionalProp<IntProp<"int8_t">>:$simplei8,
+    OptionalProp<IntProp<"uint8_t">>:$simpleui8,
     OptionalProp<StringProp>:$nonTrivialStorage,
     // Confirm that properties with default values now default to nullopt and have
     // the long syntax.

>From 490eea909b714a6321b258b9977ddd7274373c3e Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Fri, 20 Jun 2025 13:22:00 +0200
Subject: [PATCH 2/2] Update mlir/lib/IR/ODSSupport.cpp

Co-authored-by: Copilot <175728472+Copilot at users.noreply.github.com>
---
 mlir/lib/IR/ODSSupport.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mlir/lib/IR/ODSSupport.cpp b/mlir/lib/IR/ODSSupport.cpp
index b8bad1f1b098f..5b0a3e22139e1 100644
--- a/mlir/lib/IR/ODSSupport.cpp
+++ b/mlir/lib/IR/ODSSupport.cpp
@@ -56,7 +56,7 @@ mlir::convertFromAttribute(int8_t &storage, Attribute attr,
     emitError() << "expected IntegerAttr for key `value`";
     return failure();
   }
-  storage = valueAttr.getValue().getZExtValue();
+  storage = valueAttr.getValue().getSExtValue();
   return success();
 }
 



More information about the Mlir-commits mailing list