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

llvmlistbot at llvm.org llvmlistbot at llvm.org
Fri Jan 23 22:59:09 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir-core

Author: Ryan Kim (chokobole)

<details>
<summary>Changes</summary>

Introduces a new type interface `ConstantLikeInterface` that allows custom types to define their own constant creation logic. This is particularly useful for domain-specific types (e.g., finite field elements, custom numeric types) that need special handling for constant attributes and ops.

Interface methods:
- `createConstantAttr(int64_t)`: Create a TypedAttr from a scalar value
- `createConstantAttrFromValues(ArrayRef<APInt>)`: Create a TypedAttr from multiple APInt values (useful for composite types like extension fields)
- `createConstantOp(OpBuilder&, Location, TypedAttr)`: Create a dialect- specific constant operation instead of relying on arith.constant
- `overrideShapedType(ShapedType)`: Override the shaped type used for tensor/vector constants (e.g., to use a storage type for the elements)

Integration points:
- `Builder::getZeroAttr` and `Builder::getOneAttr` now check for this interface first, enabling custom types to provide their own constant creation logic before falling back to built-in type handling.
- ElementwiseOpFusion uses this interface to create scalar constants when fusing splat operands into linalg.generic operations.

---

Patch is 34.82 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/177740.diff


10 Files Affected:

- (modified) mlir/include/mlir/IR/CMakeLists.txt (+5) 
- (added) mlir/include/mlir/IR/ConstantLikeInterface.h (+34) 
- (added) mlir/include/mlir/IR/ConstantLikeInterface.td (+82) 
- (modified) mlir/lib/Dialect/Linalg/Transforms/ElementwiseOpFusion.cpp (+23-6) 
- (modified) mlir/lib/IR/Builders.cpp (+33-2) 
- (modified) mlir/lib/IR/CMakeLists.txt (+2) 
- (added) mlir/lib/IR/ConstantLikeInterface.cpp (+15) 
- (modified) mlir/unittests/IR/CMakeLists.txt (+4-1) 
- (added) mlir/unittests/IR/ConstantLikeInterfaceTest.cpp (+511) 
- (modified) utils/bazel/llvm-project-overlay/mlir/BUILD.bazel (+19) 


``````````diff
diff --git a/mlir/include/mlir/IR/CMakeLists.txt b/mlir/include/mlir/IR/CMakeLists.txt
index 0b3079cde568d..d7d1f116987a4 100644
--- a/mlir/include/mlir/IR/CMakeLists.txt
+++ b/mlir/include/mlir/IR/CMakeLists.txt
@@ -55,6 +55,11 @@ mlir_tablegen(BuiltinTypeInterfaces.h.inc -gen-type-interface-decls)
 mlir_tablegen(BuiltinTypeInterfaces.cpp.inc -gen-type-interface-defs)
 add_mlir_generic_tablegen_target(MLIRBuiltinTypeInterfacesIncGen)
 
+set(LLVM_TARGET_DEFINITIONS ConstantLikeInterface.td)
+mlir_tablegen(ConstantLikeInterface.h.inc -gen-type-interface-decls)
+mlir_tablegen(ConstantLikeInterface.cpp.inc -gen-type-interface-defs)
+add_public_tablegen_target(MLIRConstantLikeInterfaceIncGen)
+
 set(LLVM_TARGET_DEFINITIONS TensorEncoding.td)
 mlir_tablegen(TensorEncInterfaces.h.inc -gen-attr-interface-decls)
 mlir_tablegen(TensorEncInterfaces.cpp.inc -gen-attr-interface-defs)
diff --git a/mlir/include/mlir/IR/ConstantLikeInterface.h b/mlir/include/mlir/IR/ConstantLikeInterface.h
new file mode 100644
index 0000000000000..e8d4a2794d2c1
--- /dev/null
+++ b/mlir/include/mlir/IR/ConstantLikeInterface.h
@@ -0,0 +1,34 @@
+//===- ConstantLikeInterface.h - Constant Creation Interface -------*- C++
+//-*-===//
+//
+// 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_H
+#define MLIR_IR_CONSTANTLIKEINTERFACE_H
+
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/Types.h"
+
+namespace llvm {
+class APInt;
+} // namespace llvm
+
+namespace mlir {
+class TypedAttr;
+class OpBuilder;
+class Location;
+class Operation;
+} // namespace mlir
+
+#include "mlir/IR/ConstantLikeInterface.h.inc"
+
+#endif // MLIR_IR_CONSTANTLIKEINTERFACE_H
diff --git a/mlir/include/mlir/IR/ConstantLikeInterface.td b/mlir/include/mlir/IR/ConstantLikeInterface.td
new file mode 100644
index 0000000000000..af5d948bc7260
--- /dev/null
+++ b/mlir/include/mlir/IR/ConstantLikeInterface.td
@@ -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",
+      /*args=*/(ins "::mlir::ShapedType":$shapedType)
+    >
+  ];
+}
+
+#endif // MLIR_IR_CONSTANTLIKEINTERFACE_TD_
diff --git a/mlir/lib/Dialect/Linalg/Transforms/ElementwiseOpFusion.cpp b/mlir/lib/Dialect/Linalg/Transforms/ElementwiseOpFusion.cpp
index 72acd02d0d13d..cff08755052ca 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/ElementwiseOpFusion.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/ElementwiseOpFusion.cpp
@@ -21,6 +21,7 @@
 #include "mlir/Dialect/Tensor/Transforms/Transforms.h"
 #include "mlir/IR/AffineExpr.h"
 #include "mlir/IR/AffineMap.h"
+#include "mlir/IR/ConstantLikeInterface.h"
 #include "mlir/IR/Matchers.h"
 #include "mlir/IR/PatternMatch.h"
 #include "mlir/Support/LLVM.h"
@@ -2307,8 +2308,27 @@ class FoldScalarOrSplatConstant : public OpRewritePattern<GenericOp> {
       }
 
       // Create a constant scalar value from the splat constant.
-      Value scalarConstant =
-          arith::ConstantOp::create(rewriter, def->getLoc(), constantAttr);
+      Value scalarConstant;
+      Region &region = genericOp->getRegion(0);
+      Block &entryBlock = *region.begin();
+      Value argument = entryBlock.getArgument(opOperand->getOperandNumber());
+      Type argType = argument.getType();
+
+      // Try to use ConstantLikeInterface for custom constant creation
+      if (auto constType = llvm::dyn_cast<ConstantLikeInterface>(argType)) {
+        if (Operation *constOp = constType.createConstantOp(
+                rewriter, def->getLoc(), constantAttr)) {
+          scalarConstant = constOp->getResult(0);
+        } else {
+          // Fallback to arith::ConstantOp
+          scalarConstant =
+              arith::ConstantOp::create(rewriter, def->getLoc(), constantAttr);
+        }
+      } else {
+        // Default to arith::ConstantOp for types without the interface
+        scalarConstant =
+            arith::ConstantOp::create(rewriter, def->getLoc(), constantAttr);
+      }
 
       SmallVector<Value> outputOperands = genericOp.getOutputs();
       auto fusedOp =
@@ -2323,11 +2343,8 @@ class FoldScalarOrSplatConstant : public OpRewritePattern<GenericOp> {
 
       // Map the block argument corresponding to the replaced argument with the
       // scalar constant.
-      Region &region = genericOp->getRegion(0);
-      Block &entryBlock = *region.begin();
       IRMapping mapping;
-      mapping.map(entryBlock.getArgument(opOperand->getOperandNumber()),
-                  scalarConstant);
+      mapping.map(argument, scalarConstant);
       Region &fusedRegion = fusedOp->getRegion(0);
       rewriter.cloneRegionBefore(region, fusedRegion, fusedRegion.begin(),
                                  mapping);
diff --git a/mlir/lib/IR/Builders.cpp b/mlir/lib/IR/Builders.cpp
index 8f199b60fccdc..d7b2d96c71a3c 100644
--- a/mlir/lib/IR/Builders.cpp
+++ b/mlir/lib/IR/Builders.cpp
@@ -10,6 +10,7 @@
 #include "mlir/IR/AffineExpr.h"
 #include "mlir/IR/AffineMap.h"
 #include "mlir/IR/BuiltinTypes.h"
+#include "mlir/IR/ConstantLikeInterface.h"
 #include "mlir/IR/Dialect.h"
 #include "mlir/IR/IRMapping.h"
 #include "mlir/IR/Matchers.h"
@@ -322,6 +323,14 @@ ArrayAttr Builder::getAffineMapArrayAttr(ArrayRef<AffineMap> values) {
 }
 
 TypedAttr Builder::getZeroAttr(Type type) {
+  // Check if the type implements ConstantLikeInterface for custom constant
+  // creation
+  if (auto constType = llvm::dyn_cast<ConstantLikeInterface>(type)) {
+    if (auto attr = constType.createConstantAttr(0))
+      return attr;
+  }
+
+  // Fallback to built-in type handling
   if (llvm::isa<FloatType>(type))
     return getFloatAttr(type, 0.0);
   if (llvm::isa<IndexType>(type))
@@ -331,15 +340,30 @@ TypedAttr Builder::getZeroAttr(Type type) {
                           APInt(llvm::cast<IntegerType>(type).getWidth(), 0));
   if (llvm::isa<RankedTensorType, VectorType>(type)) {
     auto vtType = llvm::cast<ShapedType>(type);
-    auto element = getZeroAttr(vtType.getElementType());
+    auto elementType = vtType.getElementType();
+
+    auto element = getZeroAttr(elementType);
     if (!element)
       return {};
+    // Check if element type implements ConstantLikeInterface for custom
+    // shaped constant creation
+    if (auto constType = llvm::dyn_cast<ConstantLikeInterface>(elementType)) {
+      vtType = constType.overrideShapedType(vtType);
+    }
     return DenseElementsAttr::get(vtType, element);
   }
   return {};
 }
 
 TypedAttr Builder::getOneAttr(Type type) {
+  // Check if the type implements ConstantLikeInterface for custom constant
+  // creation
+  if (auto constType = llvm::dyn_cast<ConstantLikeInterface>(type)) {
+    if (auto attr = constType.createConstantAttr(1))
+      return attr;
+  }
+
+  // Fallback to built-in type handling
   if (llvm::isa<FloatType>(type))
     return getFloatAttr(type, 1.0);
   if (llvm::isa<IndexType>(type))
@@ -349,9 +373,16 @@ TypedAttr Builder::getOneAttr(Type type) {
                           APInt(llvm::cast<IntegerType>(type).getWidth(), 1));
   if (llvm::isa<RankedTensorType, VectorType>(type)) {
     auto vtType = llvm::cast<ShapedType>(type);
-    auto element = getOneAttr(vtType.getElementType());
+    auto elementType = vtType.getElementType();
+
+    auto element = getOneAttr(elementType);
     if (!element)
       return {};
+    // Check if element type implements ConstantLikeInterface for custom
+    // shaped constant creation
+    if (auto constType = llvm::dyn_cast<ConstantLikeInterface>(elementType)) {
+      vtType = constType.overrideShapedType(vtType);
+    }
     return DenseElementsAttr::get(vtType, element);
   }
   return {};
diff --git a/mlir/lib/IR/CMakeLists.txt b/mlir/lib/IR/CMakeLists.txt
index d95bdc957e3c2..cf12cb5e53299 100644
--- a/mlir/lib/IR/CMakeLists.txt
+++ b/mlir/lib/IR/CMakeLists.txt
@@ -18,6 +18,7 @@ add_mlir_library(MLIRIR
   BuiltinDialectBytecode.cpp
   BuiltinTypes.cpp
   BuiltinTypeInterfaces.cpp
+  ConstantLikeInterface.cpp
   Diagnostics.cpp
   Dialect.cpp
   DialectResourceBlobManager.cpp
@@ -61,6 +62,7 @@ add_mlir_library(MLIRIR
   MLIRBuiltinTypeInterfacesIncGen
   MLIRCallInterfacesIncGen
   MLIRCastInterfacesIncGen
+  MLIRConstantLikeInterfaceIncGen
   MLIRDataLayoutInterfacesIncGen
   MLIROpAsmInterfaceIncGen
   MLIRRegionKindInterfaceIncGen
diff --git a/mlir/lib/IR/ConstantLikeInterface.cpp b/mlir/lib/IR/ConstantLikeInterface.cpp
new file mode 100644
index 0000000000000..028434eea5771
--- /dev/null
+++ b/mlir/lib/IR/ConstantLikeInterface.cpp
@@ -0,0 +1,15 @@
+//===- ConstantLikeInterface.cpp - Constant Creation Interface --*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/IR/ConstantLikeInterface.h"
+
+namespace mlir {
+
+#include "mlir/IR/ConstantLikeInterface.cpp.inc"
+
+} // namespace mlir
diff --git a/mlir/unittests/IR/CMakeLists.txt b/mlir/unittests/IR/CMakeLists.txt
index dd3b110dcd295..af04c8b5fd9ed 100644
--- a/mlir/unittests/IR/CMakeLists.txt
+++ b/mlir/unittests/IR/CMakeLists.txt
@@ -4,6 +4,7 @@ add_mlir_unittest(MLIRIRTests
   AffineMapTest.cpp
   AttributeTest.cpp
   AttrTypeReplacerTest.cpp
+  ConstantLikeInterfaceTest.cpp
   Diagnostic.cpp
   DialectTest.cpp
   DistinctAttributeAllocatorTest.cpp
@@ -14,7 +15,7 @@ add_mlir_unittest(MLIRIRTests
   MemrefLayoutTest.cpp
   OperationSupportTest.cpp
   PatternMatchTest.cpp
-  RemarkTest.cpp  
+  RemarkTest.cpp
   ShapedTypeTest.cpp
   SymbolTableTest.cpp
   TypeTest.cpp
@@ -24,9 +25,11 @@ add_mlir_unittest(MLIRIRTests
   BlobManagerTest.cpp
 
   DEPENDS
+  MLIRConstantLikeInterfaceIncGen
   MLIRTestInterfaceIncGen
 )
 target_include_directories(MLIRIRTests PRIVATE "${MLIR_BINARY_DIR}/test/lib/Dialect/Test")
 mlir_target_link_libraries(MLIRIRTests PRIVATE MLIRIR)
+target_link_libraries(MLIRIRTests PRIVATE MLIRArithDialect)
 target_link_libraries(MLIRIRTests PRIVATE MLIRTestDialect)
 target_link_libraries(MLIRIRTests PRIVATE MLIRRemarkStreamer)
diff --git a/mlir/unittests/IR/ConstantLikeInterfaceTest.cpp b/mlir/unittests/IR/ConstantLikeInterfaceTest.cpp
new file mode 100644
index 0000000000000..123e601872442
--- /dev/null
+++ b/mlir/unittests/IR/ConstantLikeInterfaceTest.cpp
@@ -0,0 +1,511 @@
+//===- ConstantLikeInterfaceTest.cpp - Test ConstantLikeInterface ---------===//
+//
+// 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 implements tests for the ConstantLikeInterface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/IR/ConstantLikeInterface.h"
+#include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/BuiltinAttributes.h"
+#include "mlir/IR/BuiltinDialect.h"
+#include "mlir/IR/BuiltinOps.h"
+#include "mlir/IR/BuiltinTypes.h"
+#include "mlir/IR/OwningOpRef.h"
+#include "gtest/gtest.h"
+
+using namespace mlir;
+
+namespace {
+
+//===----------------------------------------------------------------------===//
+// Test External Models
+//===----------------------------------------------------------------------===//
+
+/// External interface model for IntegerType that provides custom constant
+/// creation. This model multiplies values by 2 to demonstrate the interface
+/// is being used.
+struct TestConstantLikeIntegerModel
+    : public ConstantLikeInterface::ExternalModel<TestConstantLikeIntegerModel,
+                                                  IntegerType> {
+  /// Creates an IntegerAttr with the value multiplied by 2 (for testing).
+  TypedAttr createConstantAttr(Type type, int64_t value) const {
+    auto intType = llvm::cast<IntegerType>(type);
+    // Multiply by 2 to verify this method is called instead of the default.
+    return IntegerAttr::get(intType, value * 2);
+  }
+
+  /// Creates an IntegerAttr from APInt values.
+  /// For IntegerType, we expect exactly one APInt value and add 10 to it.
+  TypedAttr createConstantAttrFromValues(Type type,
+                                         ArrayRef<APInt> values) const {
+    if (values.size() != 1)
+      return {};
+    auto intType = llvm::cast<IntegerType>(type);
+    // Add 10 to verify this method is called.
+    APInt result = values[0] + 10;
+    return IntegerAttr::get(intType, result);
+  }
+
+  /// Creates an arith.constant operation for the integer type.
+  Operation *createConstantOp(Type type, OpBuilder &builder, Location loc,
+                              TypedAttr attr) const {
+    return arith::ConstantOp::create(builder, loc, attr);
+  }
+
+  /// Overrides the shaped type by changing the element type to i64.
+  /// This simulates types that need a different storage representation.
+  ShapedType overrideShapedType(Type type, ShapedType shapedType) const {
+    // Override to use i64 as storage type for demonstration.
+    IntegerType storageType = IntegerType::get(type.getContext(), 64);
+    return shapedType.clone(storageType);
+  }
+};
+
+/// External interface model for Float32Type with distinct behavior.
+struct TestConstantLikeFloatModel
+    : public ConstantLikeInterface::ExternalModel<TestConstantLikeFloatModel,
+                                                  Float32Type> {
+  /// Creates a FloatAttr with the value plus 100 (for testing).
+  TypedAttr createConstantAttr(Type type, int64_t value) const {
+    // Add 100 to verify this method is called.
+    return FloatAttr::get(type, static_cast<double>(value) + 100.0);
+  }
+
+  TypedAttr createConstantAttrFromValues(Type type,
+                                         ArrayRef<APInt> values) const {
+    if (values.size() != 1)
+      return {};
+    // Convert APInt to double and add 50.
+    double d = static_cast<double>(values[0].getSExtValue()) + 50.0;
+    return FloatAttr::get(type, d);
+  }
+
+  Operation *createConstantOp(Type type, OpBuilder &builder, Location loc,
+                              TypedAttr attr) const {
+    return arith::ConstantOp::create(builder, loc, attr);
+  }
+
+  ShapedType overrideShapedType(Type type, ShapedType shapedType) const {
+    // Keep unchanged for float.
+    return shapedType;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Basic Interface Tests
+//===----------------------------------------------------------------------===//
+
+TEST(ConstantLikeInterfaceTest, InterfaceNotAttached) {
+  // Without attaching the interface, types should not implement it.
+  MLIRContext context;
+  IntegerType i32 = IntegerType::get(&context, 32);
+  EXPECT_FALSE(isa<ConstantLikeInterface>(i32));
+
+  Float32Type f32 = Float32Type::get(&context);
+  EXPECT_FALSE(isa<ConstantLikeInterface>(f32));
+}
+
+TEST(ConstantLikeInterfaceTest, AttachInterfaceToIntegerType) {
+  MLIRContext context;
+
+  // Attach the interface to IntegerType.
+  IntegerType::attachInterface<TestConstantLikeIntegerModel>(context);
+
+  IntegerType i32 = IntegerType::get(&context, 32);
+  auto iface = dyn_cast<ConstantLikeInterface>(i32);
+  ASSERT_TRUE(iface != nullptr);
+
+  // Test createConstantAttr - our model multiplies by 2.
+  TypedAttr attr = iface.createConstantAttr(5);
+  ASSERT_TRUE(attr != nullptr);
+  auto intAttr = dyn_cast<IntegerAttr>(attr);
+  ASSERT_TRUE(intAttr != nullptr);
+  EXPECT_EQ(intAttr.getInt(), 10); // 5 * 2 = 10
+}
+
+TEST(ConstantLikeInterfaceTest, AttachInterfaceToFloatType) {
+  MLIRContext context;
+
+  // Attach the interface to Float32Type.
+  Float32Type::attachInterface<TestConstantLikeFloatModel>(context);
+
+  Float32Type f32 = Float32Type::get(&context);
+  auto iface = dyn_cast<ConstantLikeInterface>(f32);
+  ASSERT_TRUE(iface != nullptr);
+
+  // Test createConstantAttr - our model adds 100.
+  TypedAttr attr = iface.createConstantAttr(1);
+  ASSERT_TRUE(attr != nullptr);
+  auto floatAttr = dyn_cast<FloatAttr>(attr);
+  ASSERT_TRUE(floatAttr != nullptr);
+  EXPECT_DOUBLE_EQ(floatAttr.getValueAsDouble(), 101.0); // 1 + 100 = 101
+}
+
+TEST(ConstantLikeInterfaceTest, InterfaceNotSharedAcrossContexts) {
+  MLIRContext context1;
+  MLIRContext context2;
+
+  // Attach interface only to context1.
+  IntegerType::attachInterface<TestConstantLikeIntegerModel>(context1);
+
+  IntegerType i32Ctx1 = IntegerType::get(&context1, 32);
+  IntegerType i32Ctx2 = IntegerType::get(&context2, 32);
+
+  // context1 should have the interface.
+  EXPECT_TRUE(isa<ConstantLikeIn...
[truncated]

``````````

</details>


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


More information about the Mlir-commits mailing list