[Mlir-commits] [mlir] [mlir][py] ability to downcast AffineExpr after #172892 (PR #174808)
Oleksandr Alex Zinenko
llvmlistbot at llvm.org
Wed Jan 7 09:29:05 PST 2026
https://github.com/ftynse updated https://github.com/llvm/llvm-project/pull/174808
>From 25118ce5932e3490bb8c8cd7a2c5b70450181c34 Mon Sep 17 00:00:00 2001
From: Alex Zinenko <git at ozinenko.com>
Date: Wed, 7 Jan 2026 18:20:12 +0100
Subject: [PATCH] [mlir][py] ability to downcast AffineExpr after #172892
AffineExpr is a separate hierarchy of LLVM-style nested classes that doesn't
rely on TypeID and is not extensible. We need the ability to downcast the
Python equivalent of those to a specific subclass that was seemingly lost in
PR #172892. Bring it back by having an explicit cast. We don't really need
user-defined type casters here since AffineExpr is entirely closed and not
typed, unlike values.
---
mlir/include/mlir/Bindings/Python/IRCore.h | 2 ++
mlir/lib/Bindings/Python/IRAffine.cpp | 30 +++++++++++++++++++---
mlir/test/python/ir/affine_expr.py | 11 ++++++++
3 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/mlir/include/mlir/Bindings/Python/IRCore.h b/mlir/include/mlir/Bindings/Python/IRCore.h
index 729cbb6df3267..1f19683dfe80d 100644
--- a/mlir/include/mlir/Bindings/Python/IRCore.h
+++ b/mlir/include/mlir/Bindings/Python/IRCore.h
@@ -1214,6 +1214,8 @@ class MLIR_PYTHON_API_EXPORTED PyAffineExpr : public BaseContextObject {
PyAffineExpr ceilDiv(const PyAffineExpr &other) const;
PyAffineExpr mod(const PyAffineExpr &other) const;
+ nanobind::typed<nanobind::object, PyAffineExpr> maybeDownCast();
+
private:
MlirAffineExpr affineExpr;
};
diff --git a/mlir/lib/Bindings/Python/IRAffine.cpp b/mlir/lib/Bindings/Python/IRAffine.cpp
index b3d15ee59566b..3c2da03181e6a 100644
--- a/mlir/lib/Bindings/Python/IRAffine.cpp
+++ b/mlir/lib/Bindings/Python/IRAffine.cpp
@@ -193,14 +193,14 @@ class PyAffineBinaryExpr : public PyConcreteAffineExpr<PyAffineBinaryExpr> {
static constexpr const char *pyClassName = "AffineBinaryExpr";
using PyConcreteAffineExpr::PyConcreteAffineExpr;
- PyAffineExpr lhs() {
+ nb::typed<nb::object, PyAffineExpr> lhs() {
MlirAffineExpr lhsExpr = mlirAffineBinaryOpExprGetLHS(get());
- return PyAffineExpr(getContext(), lhsExpr);
+ return PyAffineExpr(getContext(), lhsExpr).maybeDownCast();
}
- PyAffineExpr rhs() {
+ nb::typed<nb::object, PyAffineExpr> rhs() {
MlirAffineExpr rhsExpr = mlirAffineBinaryOpExprGetRHS(get());
- return PyAffineExpr(getContext(), rhsExpr);
+ return PyAffineExpr(getContext(), rhsExpr).maybeDownCast();
}
static void bindDerived(ClassTy &c) {
@@ -375,6 +375,27 @@ PyAffineExpr PyAffineExpr::createFromCapsule(const nb::object &capsule) {
rawAffineExpr);
}
+nb::typed<nb::object, PyAffineExpr> PyAffineExpr::maybeDownCast() {
+ MlirAffineExpr expr = get();
+ if (mlirAffineExprIsAConstant(expr))
+ return nb::cast(PyAffineConstantExpr(getContext(), expr));
+ if (mlirAffineExprIsADim(expr))
+ return nb::cast(PyAffineDimExpr(getContext(), expr));
+ if (mlirAffineExprIsASymbol(expr))
+ return nb::cast(PyAffineSymbolExpr(getContext(), expr));
+ if (mlirAffineExprIsAAdd(expr))
+ return nb::cast(PyAffineAddExpr(getContext(), expr));
+ if (mlirAffineExprIsAMul(expr))
+ return nb::cast(PyAffineMulExpr(getContext(), expr));
+ if (mlirAffineExprIsAMod(expr))
+ return nb::cast(PyAffineModExpr(getContext(), expr));
+ if (mlirAffineExprIsAFloorDiv(expr))
+ return nb::cast(PyAffineFloorDivExpr(getContext(), expr));
+ if (mlirAffineExprIsACeilDiv(expr))
+ return nb::cast(PyAffineCeilDivExpr(getContext(), expr));
+ return nb::cast(*this);
+}
+
//------------------------------------------------------------------------------
// PyAffineMap and utilities.
//------------------------------------------------------------------------------
@@ -593,6 +614,7 @@ void populateIRAffine(nb::module_ &m) {
return PyAffineExpr(self.getContext(),
mlirAffineExprCompose(self, other));
})
+ .def("maybe_downcast", &PyAffineExpr::maybeDownCast)
.def(
"shift_dims",
[](PyAffineExpr &self, uint32_t numDims, uint32_t shift,
diff --git a/mlir/test/python/ir/affine_expr.py b/mlir/test/python/ir/affine_expr.py
index 82c509efdf8fc..cf1d5258333d7 100644
--- a/mlir/test/python/ir/affine_expr.py
+++ b/mlir/test/python/ir/affine_expr.py
@@ -424,3 +424,14 @@ def testAffineExprSimplify():
with Context() as ctx:
expr = AffineExpr.get_dim(0) + AffineExpr.get_symbol(0)
assert expr == AffineExpr.simplify_affine_expr(expr, 1, 1)
+
+
+# CHECK-LABEL: TEST: testAffineExprDowncast
+ at run
+def testAffineExprDowncast():
+ with Context() as ctx:
+ expr = AffineExpr.get_dim(0) + AffineExpr.get_symbol(0)
+ assert isinstance(expr.lhs, AffineDimExpr)
+ assert isinstance(expr.rhs, AffineSymbolExpr)
+ assert expr.lhs.position == 0
+ assert expr.rhs.position == 0
More information about the Mlir-commits
mailing list