[Mlir-commits] [mlir] [mlir-c] Add DestinationStyleOpInterface C API bindings (PR #206561)
Maksim Levental
llvmlistbot at llvm.org
Mon Jun 29 11:51:51 PDT 2026
https://github.com/makslevental updated https://github.com/llvm/llvm-project/pull/206561
>From c5c2ce7256e041185531f866970f7061bf67ad50 Mon Sep 17 00:00:00 2001
From: makslevental <maksim.levental at gmail.com>
Date: Mon, 29 Jun 2026 11:34:10 -0700
Subject: [PATCH] [mlir-c] Add DestinationStyleOpInterface C API bindings
---
mlir/include/mlir-c/Interfaces.h | 40 +++++++++++++++++
mlir/lib/CAPI/Interfaces/CMakeLists.txt | 1 +
mlir/lib/CAPI/Interfaces/Interfaces.cpp | 42 ++++++++++++++++++
mlir/test/CAPI/ir.c | 58 +++++++++++++++++++++++++
4 files changed, 141 insertions(+)
diff --git a/mlir/include/mlir-c/Interfaces.h b/mlir/include/mlir-c/Interfaces.h
index a5251dc78471f..f7cd57b7d7462 100644
--- a/mlir/include/mlir-c/Interfaces.h
+++ b/mlir/include/mlir-c/Interfaces.h
@@ -165,6 +165,46 @@ MLIR_CAPI_EXPORTED void mlirMemoryEffectsOpInterfaceAttachFallbackModel(
MlirContext ctx, MlirStringRef opName,
MlirMemoryEffectsOpInterfaceCallbacks callbacks);
+//===---------------------------------------------------------------------===//
+// DestinationStyleOpInterface
+//===---------------------------------------------------------------------===//
+
+/// Returns the interface TypeID of the DestinationStyleOpInterface.
+MLIR_CAPI_EXPORTED MlirTypeID mlirDestinationStyleOpInterfaceTypeID(void);
+
+/// Returns the number of "init" (destination) operands of the given
+/// destination-style operation. The operation must implement
+/// DestinationStyleOpInterface.
+MLIR_CAPI_EXPORTED intptr_t
+mlirDestinationStyleOpInterfaceGetNumDpsInits(MlirOperation op);
+
+/// Returns the `i`-th "init" operand as an OpOperand. The operation must
+/// implement DestinationStyleOpInterface.
+MLIR_CAPI_EXPORTED MlirOpOperand
+mlirDestinationStyleOpInterfaceGetDpsInitOperand(MlirOperation op, intptr_t i);
+
+/// Returns the number of "input" operands of the given destination-style
+/// operation. The operation must implement DestinationStyleOpInterface.
+MLIR_CAPI_EXPORTED intptr_t
+mlirDestinationStyleOpInterfaceGetNumDpsInputs(MlirOperation op);
+
+/// Returns the `i`-th "input" operand as an OpOperand. The operation must
+/// implement DestinationStyleOpInterface.
+MLIR_CAPI_EXPORTED MlirOpOperand
+mlirDestinationStyleOpInterfaceGetDpsInputOperand(MlirOperation op, intptr_t i);
+
+/// Returns true if the given OpOperand is an "input" of the operation. The
+/// operation must implement DestinationStyleOpInterface.
+MLIR_CAPI_EXPORTED bool
+mlirDestinationStyleOpInterfaceIsDpsInput(MlirOperation op,
+ MlirOpOperand operand);
+
+/// Returns true if the given OpOperand is an "init" of the operation. The
+/// operation must implement DestinationStyleOpInterface.
+MLIR_CAPI_EXPORTED bool
+mlirDestinationStyleOpInterfaceIsDpsInit(MlirOperation op,
+ MlirOpOperand operand);
+
#ifdef __cplusplus
}
#endif
diff --git a/mlir/lib/CAPI/Interfaces/CMakeLists.txt b/mlir/lib/CAPI/Interfaces/CMakeLists.txt
index dbe3f33975980..3aa3edad26e5b 100644
--- a/mlir/lib/CAPI/Interfaces/CMakeLists.txt
+++ b/mlir/lib/CAPI/Interfaces/CMakeLists.txt
@@ -2,5 +2,6 @@ add_mlir_upstream_c_api_library(MLIRCAPIInterfaces
Interfaces.cpp
LINK_LIBS PUBLIC
+ MLIRDestinationStyleOpInterface
MLIRInferTypeOpInterface
MLIRSideEffectInterfaces)
diff --git a/mlir/lib/CAPI/Interfaces/Interfaces.cpp b/mlir/lib/CAPI/Interfaces/Interfaces.cpp
index 35a2bd562a8a1..4878ad79f7123 100644
--- a/mlir/lib/CAPI/Interfaces/Interfaces.cpp
+++ b/mlir/lib/CAPI/Interfaces/Interfaces.cpp
@@ -15,6 +15,7 @@
#include "mlir/CAPI/Support.h"
#include "mlir/CAPI/Wrap.h"
#include "mlir/IR/ValueRange.h"
+#include "mlir/Interfaces/DestinationStyleOpInterface.h"
#include "mlir/Interfaces/InferTypeOpInterface.h"
#include "llvm/ADT/ScopeExit.h"
#include <optional>
@@ -345,3 +346,44 @@ void mlirMemoryEffectsOpInterfaceAttachFallbackModel(
assert(model && "Failed to get MemoryEffectOpInterfaceFallbackModel");
model->setCallbacks(callbacks);
}
+
+//===---------------------------------------------------------------------===//
+// DestinationStyleOpInterface
+//===---------------------------------------------------------------------===//
+
+MlirTypeID mlirDestinationStyleOpInterfaceTypeID(void) {
+ return wrap(DestinationStyleOpInterface::getInterfaceID());
+}
+
+intptr_t mlirDestinationStyleOpInterfaceGetNumDpsInits(MlirOperation op) {
+ return cast<DestinationStyleOpInterface>(unwrap(op)).getNumDpsInits();
+}
+
+MlirOpOperand mlirDestinationStyleOpInterfaceGetDpsInitOperand(MlirOperation op,
+ intptr_t i) {
+ return wrap(
+ cast<DestinationStyleOpInterface>(unwrap(op)).getDpsInitOperand(i));
+}
+
+intptr_t mlirDestinationStyleOpInterfaceGetNumDpsInputs(MlirOperation op) {
+ return cast<DestinationStyleOpInterface>(unwrap(op)).getNumDpsInputs();
+}
+
+MlirOpOperand
+mlirDestinationStyleOpInterfaceGetDpsInputOperand(MlirOperation op,
+ intptr_t i) {
+ return wrap(
+ cast<DestinationStyleOpInterface>(unwrap(op)).getDpsInputOperand(i));
+}
+
+bool mlirDestinationStyleOpInterfaceIsDpsInput(MlirOperation op,
+ MlirOpOperand operand) {
+ return cast<DestinationStyleOpInterface>(unwrap(op))
+ .isDpsInput(unwrap(operand));
+}
+
+bool mlirDestinationStyleOpInterfaceIsDpsInit(MlirOperation op,
+ MlirOpOperand operand) {
+ return cast<DestinationStyleOpInterface>(unwrap(op))
+ .isDpsInit(unwrap(operand));
+}
diff --git a/mlir/test/CAPI/ir.c b/mlir/test/CAPI/ir.c
index 57ae8b9a2819b..498d92b07e784 100644
--- a/mlir/test/CAPI/ir.c
+++ b/mlir/test/CAPI/ir.c
@@ -2900,6 +2900,62 @@ int testDominanceInfo(MlirContext ctx) {
return 0;
}
+int testDestinationStyleOpInterface(MlirContext ctx) {
+ fprintf(stderr, "@testDestinationStyleOpInterface\n");
+ // CHECK-LABEL: @testDestinationStyleOpInterface
+
+ mlirContextGetOrLoadDialect(ctx, mlirStringRefCreateFromCString("linalg"));
+
+ // linalg.fill is a destination-style op: `ins(%val)` is the input operand
+ // (operand 0) and `outs(%init)` is the init/destination operand (operand 1).
+ const char *moduleStr =
+ "func.func @f(%val: f32, %init: tensor<4xf32>) -> tensor<4xf32> {\n"
+ " %0 = linalg.fill ins(%val : f32) outs(%init : tensor<4xf32>) -> "
+ "tensor<4xf32>\n"
+ " return %0 : tensor<4xf32>\n"
+ "}\n";
+ MlirModule module =
+ mlirModuleCreateParse(ctx, mlirStringRefCreateFromCString(moduleStr));
+
+ MlirBlock moduleBody = mlirModuleGetBody(module);
+ MlirOperation funcOp = mlirBlockGetFirstOperation(moduleBody);
+ MlirRegion funcRegion = mlirOperationGetRegion(funcOp, 0);
+ MlirBlock funcBody = mlirRegionGetFirstBlock(funcRegion);
+ MlirValue initArg = mlirBlockGetArgument(funcBody, 1);
+ MlirOperation fillOp = mlirBlockGetFirstOperation(funcBody);
+
+ // The linalg.fill op implements the interface.
+ MlirTypeID id = mlirDestinationStyleOpInterfaceTypeID();
+ assert(!mlirTypeIDIsNull(id));
+ assert(mlirOperationImplementsInterface(fillOp, id));
+
+ // One input, one init.
+ assert(mlirDestinationStyleOpInterfaceGetNumDpsInputs(fillOp) == 1);
+ assert(mlirDestinationStyleOpInterfaceGetNumDpsInits(fillOp) == 1);
+
+ MlirOpOperand inputOperand =
+ mlirDestinationStyleOpInterfaceGetDpsInputOperand(fillOp, 0);
+ MlirOpOperand initOperand =
+ mlirDestinationStyleOpInterfaceGetDpsInitOperand(fillOp, 0);
+
+ // Classification of operands as input vs. init.
+ assert(mlirDestinationStyleOpInterfaceIsDpsInput(fillOp, inputOperand));
+ assert(mlirDestinationStyleOpInterfaceIsDpsInit(fillOp, initOperand));
+ assert(!mlirDestinationStyleOpInterfaceIsDpsInput(fillOp, initOperand));
+ assert(!mlirDestinationStyleOpInterfaceIsDpsInit(fillOp, inputOperand));
+
+ // The input is operand 0; the init is operand 1 and matches the %init arg.
+ assert(mlirOpOperandGetOperandNumber(inputOperand) == 0);
+ assert(mlirOpOperandGetOperandNumber(initOperand) == 1);
+ assert(mlirValueEqual(mlirOpOperandGetValue(initOperand), initArg));
+
+ mlirModuleDestroy(module);
+
+ // CHECK: testDestinationStyleOpInterface: PASSED
+ fprintf(stderr, "testDestinationStyleOpInterface: PASSED\n");
+ return 0;
+}
+
int main(void) {
MlirContext ctx = mlirContextCreate();
registerAllUpstreamDialects(ctx);
@@ -2955,6 +3011,8 @@ int main(void) {
return 19;
if (testDominanceInfo(ctx))
return 20;
+ if (testDestinationStyleOpInterface(ctx))
+ return 21;
// CHECK: DESTROY MAIN CONTEXT
// CHECK: reportResourceDelete: resource_i64_blob
More information about the Mlir-commits
mailing list