[MLIR] Add support for int8/uint8 properties (#145019)

This patch is adding the ability to print a uint8_t/int8_t as an int
instead of a char and demonstrate support for int8_t/uin8_t properties.

Fix #144993
This commit is contained in:
Mehdi Amini
2025-06-23 16:57:14 +02:00
committed by GitHub
parent a50cb6ca3e
commit b0366eeb7e
6 changed files with 80 additions and 2 deletions

View File

@@ -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`.

View File

@@ -135,6 +135,19 @@ public:
/// 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);

View File

@@ -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);
}];

View File

@@ -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().getSExtValue();
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) {

View File

@@ -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

View File

@@ -3406,6 +3406,8 @@ def TestOpWithOptionalProperties : TEST_Op<"with_optional_properties"> {
let assemblyFormat = [{
(`anAttr` `=` $anAttr^)?
(`simple` `=` $simple^)?
(`simplei8` `=` $simplei8^)?
(`simpleui8` `=` $simpleui8^)?
(`nonTrivialStorage` `=` $nonTrivialStorage^)?
(`hasDefault` `=` $hasDefault^)?
(`nested` `=` $nested^)?
@@ -3417,6 +3419,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.