[llvm] [mlir] [MLIR][IR] Add ConstantLikeInterface for extensible constant creation (PR #177740)

Ryan Kim via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 24 03:26:36 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",
+      /*args=*/(ins "::mlir::OpBuilder &":$builder,
+                    "::mlir::Location":$loc,
+                    "::mlir::TypedAttr":$attr)
+    >,
+    InterfaceMethod<
+      /*desc=*/[{
+        Allows custom types to override the shaped type (tensor/vector) used for
+        constant creation. This is useful when a custom element type needs to
+        substitute the shaped type with a different representation (e.g., using
+        a storage type instead of the semantic type).
+        Returns the potentially modified shaped type.
+      }],
+      /*retTy=*/"::mlir::ShapedType",
+      /*methodName=*/"overrideShapedType",
----------------
chokobole wrote:

Yes we're using MLIR for cryptography. Take a look at [ModArithOps.td#mod_arith.constant](https://github.com/fractalyze/prime-ir/blob/a596e13b82321d9cabed546666cb0efb0f9baaaa/prime_ir/Dialect/ModArith/IR/ModArithOps.td#L56-L75) and [ModArithTypes.td#mod_arith.ModArithType](https://github.com/fractalyze/prime-ir/blob/a596e13b82321d9cabed546666cb0efb0f9baaaa/prime_ir/Dialect/ModArith/IR/ModArithTypes.td#L32-L98) for more details!

Here, we define a type for modular integer and an operation to create a constant of modular integer that uses `IntegerAttribute` for scalar and `DenseIntElementsAttr` for tensor. Then I have some issues because MLIR internally assumes that `DenseElementsAttr` must have one of either integer, floating point or string as an element type. But our tensor type is `mod_arith::ModArithType`, so there's a lot of crashes because of this assumption.

Temporarily,  we add a [patch](https://github.com/fractalyze/prime-ir/blob/main/third_party/llvm-project/tensor_type_support.patch), but it'd be nice to have an official solution for this!

https://github.com/llvm/llvm-project/pull/177740


More information about the llvm-commits mailing list