[Mlir-commits] [mlir] [mlir-c] Add mlirDialectMaterializeConstant (PR #206553)
Maksim Levental
llvmlistbot at llvm.org
Wed Sep 23 21:05:46 PDT 2026
https://github.com/makslevental updated https://github.com/llvm/llvm-project/pull/206553
>From d4aaf37a0cbe578fead44a8d7e4e60963fcbee9a Mon Sep 17 00:00:00 2001
From: makslevental <maksim.levental at gmail.com>
Date: Mon, 29 Jun 2026 11:12:25 -0700
Subject: [PATCH 1/2] [mlir-c] Add mlirDialectMaterializeConstant
---
mlir/include/mlir-c/Rewrite.h | 13 +++++++
mlir/lib/CAPI/Transforms/Rewrite.cpp | 12 +++++++
mlir/test/CAPI/rewrite.c | 54 ++++++++++++++++++++++++++++
3 files changed, 79 insertions(+)
diff --git a/mlir/include/mlir-c/Rewrite.h b/mlir/include/mlir-c/Rewrite.h
index 0e5562477d4f4..5e4caacd1901d 100644
--- a/mlir/include/mlir-c/Rewrite.h
+++ b/mlir/include/mlir-c/Rewrite.h
@@ -348,6 +348,19 @@ mlirIRRewriterCreateFromOp(MlirOperation op);
/// responsibility of the user to only pass an IRRewriter class.
MLIR_CAPI_EXPORTED void mlirIRRewriterDestroy(MlirRewriterBase rewriter);
+//===----------------------------------------------------------------------===//
+/// Dialect constant materialization API
+//===----------------------------------------------------------------------===//
+
+/// Materializes a constant for the given attribute `value` and `type` using the
+/// dialect's `materializeConstant` hook. The operation is created with the
+/// given rewriter (used as an OpBuilder) at its current insertion point,
+/// without changing that insertion point. Returns a null operation if the
+/// dialect does not support materializing the given constant.
+MLIR_CAPI_EXPORTED MlirOperation mlirDialectMaterializeConstant(
+ MlirDialect dialect, MlirRewriterBase rewriter, MlirAttribute value,
+ MlirType type, MlirLocation loc);
+
//===----------------------------------------------------------------------===//
/// FrozenRewritePatternSet API
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/CAPI/Transforms/Rewrite.cpp b/mlir/lib/CAPI/Transforms/Rewrite.cpp
index e54c7dcd7271a..cd8dccbd053c0 100644
--- a/mlir/lib/CAPI/Transforms/Rewrite.cpp
+++ b/mlir/lib/CAPI/Transforms/Rewrite.cpp
@@ -304,6 +304,18 @@ void mlirIRRewriterDestroy(MlirRewriterBase rewriter) {
delete static_cast<IRRewriter *>(unwrap(rewriter));
}
+//===----------------------------------------------------------------------===//
+/// Dialect constant materialization API
+//===----------------------------------------------------------------------===//
+
+MlirOperation mlirDialectMaterializeConstant(MlirDialect dialect,
+ MlirRewriterBase rewriter,
+ MlirAttribute value, MlirType type,
+ MlirLocation loc) {
+ return wrap(unwrap(dialect)->materializeConstant(
+ *unwrap(rewriter), unwrap(value), unwrap(type), unwrap(loc)));
+}
+
//===----------------------------------------------------------------------===//
/// RewritePatternSet and FrozenRewritePatternSet API
//===----------------------------------------------------------------------===//
diff --git a/mlir/test/CAPI/rewrite.c b/mlir/test/CAPI/rewrite.c
index 60f5dca31b9ef..3d2fa8fb85b82 100644
--- a/mlir/test/CAPI/rewrite.c
+++ b/mlir/test/CAPI/rewrite.c
@@ -10,8 +10,10 @@
// RUN: mlir-capi-rewrite-test 2>&1 | FileCheck %s
#include "mlir-c/Rewrite.h"
+#include "mlir-c/BuiltinAttributes.h"
#include "mlir-c/BuiltinTypes.h"
#include "mlir-c/IR.h"
+#include "mlir-c/RegisterEverything.h"
#include <assert.h>
#include <inttypes.h>
@@ -1960,6 +1962,57 @@ void testTypeConverter1ToNConversionErasure(MlirContext ctx) {
fprintf(stderr, "testTypeConverter1ToNConversionErasure: PASSED\n");
}
+void testDialectMaterializeConstant(MlirContext ctx) {
+ // CHECK-LABEL: @testDialectMaterializeConstant
+ fprintf(stderr, "@testDialectMaterializeConstant\n");
+
+ MlirDialectRegistry registry = mlirDialectRegistryCreate();
+ mlirRegisterAllDialects(registry);
+ mlirContextAppendDialectRegistry(ctx, registry);
+ mlirDialectRegistryDestroy(registry);
+
+ MlirDialect arith =
+ mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("arith"));
+ mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("func"));
+
+ const char *moduleString = "func.func @f() {\n"
+ " return\n"
+ "}\n";
+ MlirModule module =
+ mlirModuleCreateParse(ctx, mlirStringRefCreateFromCString(moduleString));
+ MlirBlock body = mlirModuleGetBody(module);
+ MlirOperation funcOp = mlirBlockGetFirstOperation(body);
+ MlirRegion funcRegion = mlirOperationGetRegion(funcOp, 0);
+ MlirBlock funcBody = mlirRegionGetFirstBlock(funcRegion);
+
+ MlirRewriterBase rewriter = mlirIRRewriterCreate(ctx);
+ mlirRewriterBaseSetInsertionPointToStart(rewriter, funcBody);
+
+ // Materialize an i32 constant of value 42 using the arith dialect's hook.
+ MlirType i32 = mlirIntegerTypeGet(ctx, 32);
+ MlirAttribute value = mlirIntegerAttrGet(i32, 42);
+ MlirLocation loc = mlirLocationUnknownGet(ctx);
+ MlirOperation constOp =
+ mlirDialectMaterializeConstant(arith, rewriter, value, i32, loc);
+ assert(!mlirOperationIsNull(constOp));
+ mlirOperationDump(constOp);
+ // CHECK: arith.constant 42 : i32
+
+ // A dialect that does not materialize the given constant returns null. The
+ // func dialect has no constant materializer, so it returns a null operation.
+ MlirDialect func =
+ mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("func"));
+ MlirOperation none =
+ mlirDialectMaterializeConstant(func, rewriter, value, i32, loc);
+ assert(mlirOperationIsNull(none));
+
+ mlirIRRewriterDestroy(rewriter);
+ mlirModuleDestroy(module);
+
+ // CHECK: testDialectMaterializeConstant: PASSED
+ fprintf(stderr, "testDialectMaterializeConstant: PASSED\n");
+}
+
int main(void) {
MlirContext ctx = mlirContextCreate();
mlirContextSetAllowUnregisteredDialects(ctx, true);
@@ -1988,6 +2041,7 @@ int main(void) {
testConversionReplaceOpWithMultipleRanges(ctx);
testTypeConverter1ToNOperandRequires1ToNCallback(ctx);
testTypeConverter1ToNConversionErasure(ctx);
+ testDialectMaterializeConstant(ctx);
mlirContextDestroy(ctx);
return 0;
>From 25e5964385ecde126cc9809fb658b1f94dbf2a03 Mon Sep 17 00:00:00 2001
From: makslevental <maksim.levental at gmail.com>
Date: Wed, 23 Sep 2026 20:44:32 -0700
Subject: [PATCH 2/2] [mlir-c] Fix testDialectMaterializeConstant review
comments
Correct the misleading comment about the func dialect (it does have a
constant materializer; it just declines an i32 IntegerAttr), and assert
the documented insertion-point contract: the op lands in the current
insertion block and the rewriter's insertion point is preserved.
---
mlir/test/CAPI/rewrite.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/mlir/test/CAPI/rewrite.c b/mlir/test/CAPI/rewrite.c
index 3d2fa8fb85b82..4ae0f99dc24f9 100644
--- a/mlir/test/CAPI/rewrite.c
+++ b/mlir/test/CAPI/rewrite.c
@@ -1995,11 +1995,16 @@ void testDialectMaterializeConstant(MlirContext ctx) {
MlirOperation constOp =
mlirDialectMaterializeConstant(arith, rewriter, value, i32, loc);
assert(!mlirOperationIsNull(constOp));
+ // The op is created at the current insertion point without changing it: it
+ // lands in funcBody, and the rewriter still points there afterwards.
+ assert(mlirBlockEqual(mlirOperationGetBlock(constOp), funcBody));
+ assert(mlirBlockEqual(mlirRewriterBaseGetInsertionBlock(rewriter), funcBody));
mlirOperationDump(constOp);
// CHECK: arith.constant 42 : i32
- // A dialect that does not materialize the given constant returns null. The
- // func dialect has no constant materializer, so it returns a null operation.
+ // A dialect whose materializer declines the given attribute/type returns
+ // null. The func dialect has a constant materializer, but it only builds
+ // func.constant from a symbol ref, so an i32 IntegerAttr yields null.
MlirDialect func =
mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("func"));
MlirOperation none =
More information about the Mlir-commits
mailing list