[Mlir-commits] [mlir] [mlir][python] Support Arbitrary Precision Integers in MLIR C API and Python Bindings (PR #177733)
Maksim Levental
llvmlistbot at llvm.org
Sat Jan 24 20:58:44 PST 2026
================
@@ -343,8 +343,50 @@ void PyFloatAttribute::bindDerived(ClassTy &c) {
void PyIntegerAttribute::bindDerived(ClassTy &c) {
c.def_static(
"get",
- [](PyType &type, int64_t value) {
- MlirAttribute attr = mlirIntegerAttrGet(type, value);
+ [](PyType &type, nb::object value) {
+ // Handle IndexType - it doesn't have a bit width or signedness.
+ if (mlirTypeIsAIndex(type)) {
+ int64_t intValue = nb::cast<int64_t>(value);
+ MlirAttribute attr = mlirIntegerAttrGet(type, intValue);
+ return PyIntegerAttribute(type.getContext(), attr);
+ }
+
+ // Get the bit width of the integer type.
+ unsigned bitWidth = mlirIntegerTypeGetWidth(type);
+
+ // Try to use the fast path for small integers.
+ if (bitWidth <= 64) {
+ int64_t intValue = nb::cast<int64_t>(value);
+ MlirAttribute attr = mlirIntegerAttrGet(type, intValue);
+ return PyIntegerAttribute(type.getContext(), attr);
+ }
+
+ // For larger integers, convert Python int to array of 64-bit words.
+ unsigned numWords = (bitWidth + 63) / 64;
+ std::vector<uint64_t> words(numWords, 0);
+
+ // Extract words from Python integer (little-endian order).
+ nb::object mask = nb::int_(0xFFFFFFFFFFFFFFFFULL);
+ nb::object shift = nb::int_(64);
+ nb::object current = value;
+
+ // Handle negative numbers for signed types by converting to two's
+ // complement representation.
+ if (mlirIntegerTypeIsSigned(type)) {
+ nb::object zero = nb::int_(0);
+ if (nb::cast<bool>(current < zero)) {
+ nb::object twoToTheBitWidth = nb::int_(1) << nb::int_(bitWidth);
+ current = current + twoToTheBitWidth;
----------------
makslevental wrote:
ah now it clicks for me: i didn't realize python was stored `(sgn)b(pos int)` (even though I did notice the `-` in the binary repr...
https://github.com/llvm/llvm-project/pull/177733
More information about the Mlir-commits
mailing list