[Mlir-commits] [llvm] [mlir] [MLIR][IR] Add ConstantLikeInterface for extensible constant creation (PR #177740)
Ryan Kim
llvmlistbot at llvm.org
Sat Jan 24 03:35:24 PST 2026
================
@@ -0,0 +1,82 @@
+//===- ConstantLikeInterface.td - Constant creation interfaces -*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains definitions for type interfaces that allow types to
+// define how to create constant attributes and operations for themselves.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_IR_CONSTANTLIKEINTERFACE_TD_
+#define MLIR_IR_CONSTANTLIKEINTERFACE_TD_
+
+include "mlir/IR/OpBase.td"
+
+//===----------------------------------------------------------------------===//
+// ConstantLikeInterface
+//===----------------------------------------------------------------------===//
+
+def ConstantLikeInterface : TypeInterface<"ConstantLikeInterface"> {
+ let cppNamespace = "::mlir";
+ let description = [{
+ This interface allows types to define how to create constant attributes
+ and operations for their values. This decouples generic MLIR code from
+ specific constant operation types, enabling better layering and extensibility.
+
+ Types implementing this interface can provide custom constant creation logic,
+ which is particularly useful for domain-specific types (e.g., field elements,
+ custom numeric types) that need special constant handling.
+ }];
+
+ let methods = [
+ InterfaceMethod<
+ /*desc=*/[{
+ Creates a constant attribute for this type from the given int64 value.
+ Returns null if the type does not support this operation.
+ }],
+ /*retTy=*/"::mlir::TypedAttr",
+ /*methodName=*/"createConstantAttr",
+ /*args=*/(ins "int64_t ":$value)
+ >,
+ InterfaceMethod<
+ /*desc=*/[{
+ Creates a constant attribute for this type from the given APInt values.
+ The APInt should be compatible with this type's bit width and semantics.
+ Returns null if the type does not support this operation.
+ }],
+ /*retTy=*/"::mlir::TypedAttr",
+ /*methodName=*/"createConstantAttrFromValues",
+ /*args=*/(ins "::llvm::ArrayRef<APInt> ":$values)
+ >,
+ InterfaceMethod<
+ /*desc=*/[{
+ Creates a constant operation for this type with the given attribute.
+ The builder's insertion point should be set before calling this method.
+ Returns null if the type does not support constant operation creation.
+ }],
+ /*retTy=*/"::mlir::Operation *",
+ /*methodName=*/"createConstantOp",
----------------
chokobole wrote:
This function doesn't have to know what operation to create. That's what I want to achieve here. then do you think it's feasible to use `Dialect::materalizeConstant` instead of `arith::ConstantOp::create` in the change of `mlir/lib/Dialect/Linalg/Transforms/ElementwiseOpFusion.cpp`??
Without this patch, constant was materialized and moved out side as an integer constant, and this breaks type compatability. The below is an example code!
```
!pf_babybear = !field.pf<2013265921 : i32, true>
#map = affine_map<() -> ()>
func.func @fusion(%arg0: tensor<!pf_babybear>, %arg1: tensor<!pf_babybear>) -> tensor<!pf_babybear> {
// CHECK-LABEL: @fusion
// CHECK-SAME: (%[[ARG0:.*]]: tensor<!pf_babybear>, %[[ARG1:.*]]: tensor<!pf_babybear>) -> tensor<!pf_babybear>
// CHECK: %[[CST:.*]] = field.constant 536870908 : !pf_babybear
// CHECK: %[[EMPTY:.*]] = tensor.empty() : tensor<!pf_babybear>
// CHECK: %[[RESULT:.*]] = linalg.generic
// CHECK: ^bb0(%[[IN:.*]]: !pf_babybear, %[[IN_0:.*]]: !pf_babybear, %[[OUT:.*]]: !pf_babybear):
// CHECK: %[[ADD:.*]] = field.add %[[IN]], %[[IN_0]] : !pf_babybear
// CHECK: %[[MUL1:.*]] = field.mul %[[ADD]], %[[IN]] : !pf_babybear
// CHECK: %[[MUL2:.*]] = field.mul %[[MUL1]], %[[CST]] : !pf_babybear
// CHECK: linalg.yield %[[MUL2]] : !pf_babybear
// CHECK: return %[[RESULT]] : tensor<!pf_babybear>
%0 = linalg.generic {indexing_maps = [#map, #map, #map], iterator_types = []} ins(%arg0, %arg1 : tensor<!pf_babybear>, tensor<!pf_babybear>) outs(%arg0 : tensor<!pf_babybear>) {
^bb0(%in: !pf_babybear, %in_0: !pf_babybear, %out: !pf_babybear):
%ret = field.add %in, %in_0 : !pf_babybear
linalg.yield %ret : !pf_babybear
} -> tensor<!pf_babybear>
%1 = linalg.generic {indexing_maps = [#map, #map, #map], iterator_types = []} ins(%0, %arg0 : tensor<!pf_babybear>, tensor<!pf_babybear>) outs(%0 : tensor<!pf_babybear>) {
^bb0(%in: !pf_babybear, %in_0: !pf_babybear, %out: !pf_babybear):
%ret = field.mul %in, %in_0 : !pf_babybear
linalg.yield %ret : !pf_babybear
} -> tensor<!pf_babybear>
%2 = field.constant dense<536870908> : tensor<!pf_babybear>
%3 = linalg.generic {indexing_maps = [#map, #map, #map], iterator_types = []} ins(%1, %2 : tensor<!pf_babybear>, tensor<!pf_babybear>) outs(%1 : tensor<!pf_babybear>) {
^bb0(%in: !pf_babybear, %in_0: !pf_babybear, %out: !pf_babybear):
%ret = field.mul %in, %in_0 : !pf_babybear
linalg.yield %ret : !pf_babybear
} -> tensor<!pf_babybear>
return %3 : tensor<!pf_babybear>
}
```
https://github.com/llvm/llvm-project/pull/177740
More information about the Mlir-commits
mailing list