diff --git a/mlir/include/mlir/IR/BuiltinAttributes.td b/mlir/include/mlir/IR/BuiltinAttributes.td index 05dbc6bd7230..1a5c60aadd33 100644 --- a/mlir/include/mlir/IR/BuiltinAttributes.td +++ b/mlir/include/mlir/IR/BuiltinAttributes.td @@ -466,6 +466,12 @@ def Builtin_IntegerAttr : Builtin_Attr<"Integer"> { return BoolAttr::get(type.getContext(), value.getBoolValue()); return $_get(type.getContext(), type, value); }]>, + AttrBuilder<(ins "const APSInt &":$value), [{ + auto signedness = value.isSigned() ? + IntegerType::Signed : IntegerType::Unsigned; + auto type = IntegerType::get($_ctxt, value.getBitWidth(), signedness); + return $_get(type.getContext(), type, value); + }]>, AttrBuilderWithInferredContext<(ins "Type":$type, "int64_t":$value), [{ // `index` has a defined internal storage width. if (type.isIndex()) { @@ -492,6 +498,10 @@ def Builtin_IntegerAttr : Builtin_Attr<"Integer"> { /// an unsigned integer. uint64_t getUInt() const; + /// Return the value as an APSInt which carries the signed from the type of + /// the attribute. This traps on signless integers types! + APSInt getAPSInt() const; + private: /// Return a boolean attribute. This is a special variant of the `get` /// method that is used by the MLIRContext to cache the boolean IntegerAttr diff --git a/mlir/include/mlir/Support/LLVM.h b/mlir/include/mlir/Support/LLVM.h index 0683e4d55593..096cd9d43995 100644 --- a/mlir/include/mlir/Support/LLVM.h +++ b/mlir/include/mlir/Support/LLVM.h @@ -64,6 +64,7 @@ template class TypeSwitch; // Other common classes. class APInt; +class APSInt; class APFloat; template class function_ref; template class iterator_range; @@ -118,6 +119,7 @@ using TypeSwitch = llvm::TypeSwitch; // Other common classes. using llvm::APFloat; using llvm::APInt; +using llvm::APSInt; template using function_ref = llvm::function_ref; using llvm::iterator_range; using llvm::raw_ostream; diff --git a/mlir/lib/IR/BuiltinAttributes.cpp b/mlir/lib/IR/BuiltinAttributes.cpp index 76ce6ca4bb92..b36a24435a9c 100644 --- a/mlir/lib/IR/BuiltinAttributes.cpp +++ b/mlir/lib/IR/BuiltinAttributes.cpp @@ -259,6 +259,14 @@ uint64_t IntegerAttr::getUInt() const { return getValue().getZExtValue(); } +/// Return the value as an APSInt which carries the signed from the type of +/// the attribute. This traps on signless integers types! +APSInt IntegerAttr::getAPSInt() const { + assert(!getType().isSignlessInteger() && + "Signless integers don't carry a sign for APSInt"); + return APSInt(getValue(), getType().isUnsignedInteger()); +} + LogicalResult IntegerAttr::verify(function_ref emitError, Type type, APInt value) { if (IntegerType integerType = type.dyn_cast()) {