[Mlir-commits] [mlir] IntegerAttr accessor returning APInt by reference. (PR #187351)

Jacques Pienaar llvmlistbot at llvm.org
Wed Mar 18 11:46:12 PDT 2026


https://github.com/jpienaar created https://github.com/llvm/llvm-project/pull/187351

IntegerAttr accessor getValue() returns an APInt by value. This works well for the case where APInt is small, but leads to unnecessary copies for larger bitwidths. This change provides a getValueRef() accessor that returns a const APInt& directly.

I considered having the regular accessor return a const reference. This would similar to what we do for StringAttr. This would change the lifetime expectations of the existing attribute though.

>From e589c8036eb94f819e7f315e9fcc470a383ca329 Mon Sep 17 00:00:00 2001
From: Jacques Pienaar <jacques+gh at japienaar.info>
Date: Wed, 18 Mar 2026 18:27:17 +0000
Subject: [PATCH] IntegerAttr accessor returning APInt by reference.

IntegerAttr accessor getValue() returns an APInt by value. This works
well for the case where APInt is small, but leads to unnecessary copies
for larger bitwidths. This CL provides a new getValueRef() accessor that
returns a const APInt& directly from the internal storage.

I considered having the regular accessor return a const reference. This
would similar to what we do for StringAttr. This would change the
lifetime expectations of the existing attribute though.
---
 mlir/include/mlir/IR/BuiltinAttributes.td | 3 +++
 mlir/lib/CAPI/IR/BuiltinAttributes.cpp    | 2 +-
 mlir/lib/Dialect/Arith/IR/ArithOps.cpp    | 4 ++--
 mlir/lib/IR/BuiltinAttributes.cpp         | 4 +++-
 4 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/mlir/include/mlir/IR/BuiltinAttributes.td b/mlir/include/mlir/IR/BuiltinAttributes.td
index dced379d1f979..8a242b5127cc4 100644
--- a/mlir/include/mlir/IR/BuiltinAttributes.td
+++ b/mlir/include/mlir/IR/BuiltinAttributes.td
@@ -764,6 +764,9 @@ def Builtin_IntegerAttr : Builtin_Attr<"Integer", "integer",
     /// the attribute.  This traps on signless integers types!
     APSInt getAPSInt() const;
 
+    /// Return the integer value as a reference to an APInt.
+    const APInt &getValueRef() const;
+
   private:
     /// Return a boolean attribute. This is a special variant of the `get`
     /// method that is used by the MLIRContext to cache the boolean IntegerAttr
diff --git a/mlir/lib/CAPI/IR/BuiltinAttributes.cpp b/mlir/lib/CAPI/IR/BuiltinAttributes.cpp
index 65d72801889ec..08d57d6d3ee36 100644
--- a/mlir/lib/CAPI/IR/BuiltinAttributes.cpp
+++ b/mlir/lib/CAPI/IR/BuiltinAttributes.cpp
@@ -184,7 +184,7 @@ unsigned mlirIntegerAttrGetValueNumWords(MlirAttribute attr) {
 }
 
 void mlirIntegerAttrGetValueWords(MlirAttribute attr, uint64_t *words) {
-  const APInt &value = llvm::cast<IntegerAttr>(unwrap(attr)).getValue();
+  const APInt &value = llvm::cast<IntegerAttr>(unwrap(attr)).getValueRef();
   unsigned numWords = value.getNumWords();
   const uint64_t *rawData = value.getRawData();
   std::copy(rawData, rawData + numWords, words);
diff --git a/mlir/lib/Dialect/Arith/IR/ArithOps.cpp b/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
index f26aef625fd4a..b7bf29360c886 100644
--- a/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
+++ b/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
@@ -42,8 +42,8 @@ static IntegerAttr
 applyToIntegerAttrs(PatternRewriter &builder, Value res, Attribute lhs,
                     Attribute rhs,
                     function_ref<APInt(const APInt &, const APInt &)> binFn) {
-  APInt lhsVal = llvm::cast<IntegerAttr>(lhs).getValue();
-  APInt rhsVal = llvm::cast<IntegerAttr>(rhs).getValue();
+  const APInt &lhsVal = llvm::cast<IntegerAttr>(lhs).getValueRef();
+  const APInt &rhsVal = llvm::cast<IntegerAttr>(rhs).getValueRef();
   APInt value = binFn(lhsVal, rhsVal);
   return IntegerAttr::get(res.getType(), value);
 }
diff --git a/mlir/lib/IR/BuiltinAttributes.cpp b/mlir/lib/IR/BuiltinAttributes.cpp
index bbbc9198a68ab..5b0a65832e799 100644
--- a/mlir/lib/IR/BuiltinAttributes.cpp
+++ b/mlir/lib/IR/BuiltinAttributes.cpp
@@ -362,6 +362,8 @@ StringAttr SymbolRefAttr::getLeafReference() const {
 // IntegerAttr
 //===----------------------------------------------------------------------===//
 
+const APInt &IntegerAttr::getValueRef() const { return getImpl()->value; }
+
 int64_t IntegerAttr::getInt() const {
   assert((getType().isIndex() || getType().isSignlessInteger()) &&
          "must be signless integer");
@@ -383,7 +385,7 @@ uint64_t IntegerAttr::getUInt() const {
 APSInt IntegerAttr::getAPSInt() const {
   assert(!getType().isSignlessInteger() &&
          "Signless integers don't carry a sign for APSInt");
-  return APSInt(getValue(), getType().isUnsignedInteger());
+  return APSInt(getValueRef(), getType().isUnsignedInteger());
 }
 
 LogicalResult IntegerAttr::verify(function_ref<InFlightDiagnostic()> emitError,



More information about the Mlir-commits mailing list