[Mlir-commits] [mlir] db6ee1e - [mlir][ABI] Add indirect address space to ArgClassification (#229991)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Thu Oct 22 03:15:38 PDT 2026


Author: Chaitanya
Date: 2026-10-22T15:45:33+05:30
New Revision: db6ee1eeb2c295b4a9dc48b43dd04e0a40465683

URL: https://github.com/llvm/llvm-project/commit/db6ee1eeb2c295b4a9dc48b43dd04e0a40465683
DIFF: https://github.com/llvm/llvm-project/commit/db6ee1eeb2c295b4a9dc48b43dd04e0a40465683.diff

LOG: [mlir][ABI] Add indirect address space to ArgClassification (#229991)

Summary:

- Added an `indirectAddrSpace` field to `ArgClassification` for the
addressspace of the pointer passed in place of an Indirect value.
- Forwarded `getIndirectAddrSpace()` from the LLVM ABI library in CIR
`CallConvLowering` and accept a matching `indirect_addr_space` key in
the `test_classify` attribute.
- Added a unit test to check for default value, equality and rejection
of negative values.

Related to issue: https://github.com/llvm/llvm-project/issues/220471

follow-up PR: #230415

Assisted by : claude opus 5.5

Added: 
    

Modified: 
    clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp
    mlir/include/mlir/ABI/ABIRewriteContext.h
    mlir/include/mlir/ABI/Targets/Test/TestTarget.h
    mlir/lib/ABI/Targets/Test/TestTarget.cpp
    mlir/unittests/ABI/ABIRewriteContextTest.cpp
    mlir/unittests/ABI/TestTargetTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp b/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp
index ddf60a1547f965..6981fc2c23d198 100644
--- a/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp
@@ -668,7 +668,8 @@ convertABIArgInfo(const llvm::abi::ArgInfo &info, MLIRContext *ctx,
     return std::nullopt;
   if (info.isIndirect())
     return ArgClassification::getIndirect(info.getIndirectAlign(),
-                                          info.getIndirectByVal());
+                                          info.getIndirectByVal(),
+                                          info.getIndirectAddrSpace());
   // AArch64 pure scalable aggregates use CoerceAndExpand. This bridge lowers
   // x86_64 classifications only.
   assert(!info.isCoerceAndExpand() &&

diff  --git a/mlir/include/mlir/ABI/ABIRewriteContext.h b/mlir/include/mlir/ABI/ABIRewriteContext.h
index 7760d015d89197..555561979c15a8 100644
--- a/mlir/include/mlir/ABI/ABIRewriteContext.h
+++ b/mlir/include/mlir/ABI/ABIRewriteContext.h
@@ -77,6 +77,10 @@ struct ArgClassification {
   /// For Indirect: whether the callee gets ownership (byval).
   bool byVal = false;
 
+  /// For Indirect: target address space of the pointer passed in place of
+  /// the value.  Zero is the default address space.
+  unsigned indirectAddrSpace = 0;
+
   /// For Direct with coercion: the byte offset within the original aggregate
   /// at which the coerced value lives.  Non-zero when the low eightbyte is
   /// NO_CLASS and the value is carried in a later eightbyte (x86-64 SysV).
@@ -100,7 +104,9 @@ struct ArgClassification {
     return kind == other.kind && coercedType == other.coercedType &&
            indirectAlign == other.indirectAlign &&
            signExtend == other.signExtend && canFlatten == other.canFlatten &&
-           byVal == other.byVal && directOffset == other.directOffset &&
+           byVal == other.byVal &&
+           indirectAddrSpace == other.indirectAddrSpace &&
+           directOffset == other.directOffset &&
            neededIntRegs == other.neededIntRegs &&
            neededSseRegs == other.neededSseRegs;
   }
@@ -127,11 +133,13 @@ struct ArgClassification {
     return c;
   }
 
-  static ArgClassification getIndirect(llvm::Align align, bool byVal = true) {
+  static ArgClassification getIndirect(llvm::Align align, bool byVal,
+                                       unsigned addrSpace) {
     ArgClassification c;
     c.kind = ArgKind::Indirect;
     c.indirectAlign = align;
     c.byVal = byVal;
+    c.indirectAddrSpace = addrSpace;
     return c;
   }
 

diff  --git a/mlir/include/mlir/ABI/Targets/Test/TestTarget.h b/mlir/include/mlir/ABI/Targets/Test/TestTarget.h
index 8bf949bf3b67f0..2036837b7d91a6 100644
--- a/mlir/include/mlir/ABI/Targets/Test/TestTarget.h
+++ b/mlir/include/mlir/ABI/Targets/Test/TestTarget.h
@@ -70,17 +70,20 @@ FunctionClassification classify(TypeRange argTypes, Type returnType,
 ///   coerced_type:  TypeAttr.  Required; the extended integer type.
 ///   sign_extend:   BoolAttr.  Defaults to false (zero-extend).
 ///
-/// For kind = "indirect" (indirect_align required, byval optional):
-///   indirect_align: IntegerAttr.  Required; alignment of the pointed-to
-///                   object in bytes.
-///   byval:          BoolAttr.  Defaults to true.
+/// For kind = "indirect" (indirect_align required, byval and
+/// indirect_addr_space optional):
+///   indirect_align:      IntegerAttr.  Required; alignment of the
+///                        pointed-to object in bytes.
+///   byval:               BoolAttr.  Defaults to true.
+///   indirect_addr_space: IntegerAttr.  Target address space of the
+///                        pointer.  Defaults to 0.
 ///
 /// For kind = "ignore" / "expand": no extra keys.
 ///
 /// Future schema additions tracked in projects/daily_log.md (Step 0c
 /// field-mapping table).  When we add new fields to ArgClassification
-/// (e.g. direct_offset, extend_kind tristate, indirect_addr_space,
-/// indirect_realign), the corresponding optional keys go here.
+/// (e.g. direct_offset, extend_kind tristate, indirect_realign), the
+/// corresponding optional keys go here.
 ///
 /// Unknown keys cause a parse error (no silent ignore — keeps schema
 /// honest as it grows).

diff  --git a/mlir/lib/ABI/Targets/Test/TestTarget.cpp b/mlir/lib/ABI/Targets/Test/TestTarget.cpp
index 19bcb83b63d5ea..7af383efbf5172 100644
--- a/mlir/lib/ABI/Targets/Test/TestTarget.cpp
+++ b/mlir/lib/ABI/Targets/Test/TestTarget.cpp
@@ -103,7 +103,7 @@ ArgClassification classifyOne(Type type, const DataLayout &dl) {
 
   uint64_t alignBytes = dl.getTypeABIAlignment(type);
   return ArgClassification::getIndirect(llvm::Align(alignBytes),
-                                        /*byVal=*/true);
+                                        /*byVal=*/true, /*addrSpace=*/0);
 }
 
 } // namespace
@@ -125,8 +125,8 @@ namespace {
 /// set causes a parse error (no silent ignore).  Updated when new
 /// optional keys are added to the schema.
 constexpr StringRef knownArgKeys[] = {
-    "kind",        "coerced_type",   "sign_extend",
-    "can_flatten", "indirect_align", "byval",
+    "kind",           "coerced_type", "sign_extend",         "can_flatten",
+    "indirect_align", "byval",        "indirect_addr_space",
 };
 
 bool isKnownArgKey(StringRef key) {
@@ -151,7 +151,7 @@ parseOne(DictionaryAttr argDict, function_ref<InFlightDiagnostic()> emitError) {
       emitError() << "unknown key '" << na.getName().getValue()
                   << "' in classification dictionary; allowed keys are "
                   << "kind, coerced_type, sign_extend, can_flatten, "
-                  << "indirect_align, byval";
+                  << "indirect_align, byval, indirect_addr_space";
       return std::nullopt;
     }
 
@@ -193,7 +193,17 @@ parseOne(DictionaryAttr argDict, function_ref<InFlightDiagnostic()> emitError) {
     bool byVal = true;
     if (auto bv = argDict.getAs<BoolAttr>("byval"))
       byVal = bv.getValue();
-    return ArgClassification::getIndirect(llvm::Align(align.getInt()), byVal);
+    unsigned addrSpace = 0;
+    if (auto as = argDict.getAs<IntegerAttr>("indirect_addr_space")) {
+      if (as.getInt() < 0) {
+        emitError() << "'indirect_addr_space' must be non-negative; got "
+                    << as.getInt();
+        return std::nullopt;
+      }
+      addrSpace = as.getInt();
+    }
+    return ArgClassification::getIndirect(llvm::Align(align.getInt()), byVal,
+                                          addrSpace);
   }
 
   if (kind == "ignore") {

diff  --git a/mlir/unittests/ABI/ABIRewriteContextTest.cpp b/mlir/unittests/ABI/ABIRewriteContextTest.cpp
index 789257d3186854..3d3fcbed31fdc5 100644
--- a/mlir/unittests/ABI/ABIRewriteContextTest.cpp
+++ b/mlir/unittests/ABI/ABIRewriteContextTest.cpp
@@ -56,19 +56,27 @@ TEST(ABIRewriteContextTest, ArgClassificationIgnore) {
 }
 
 TEST(ABIRewriteContextTest, ArgClassificationIndirect) {
-  auto c = ArgClassification::getIndirect(llvm::Align(8), true);
+  auto c = ArgClassification::getIndirect(llvm::Align(8), true, 0);
   EXPECT_EQ(c.kind, ArgKind::Indirect);
   EXPECT_EQ(c.indirectAlign, llvm::Align(8));
   EXPECT_TRUE(c.byVal);
+  EXPECT_EQ(c.indirectAddrSpace, 0u);
 }
 
 TEST(ABIRewriteContextTest, ArgClassificationIndirectNoByVal) {
-  auto c = ArgClassification::getIndirect(llvm::Align(16), false);
+  auto c = ArgClassification::getIndirect(llvm::Align(16), false, 0);
   EXPECT_EQ(c.kind, ArgKind::Indirect);
   EXPECT_EQ(c.indirectAlign, llvm::Align(16));
   EXPECT_FALSE(c.byVal);
 }
 
+TEST(ABIRewriteContextTest, ArgClassificationIndirectAddrSpace) {
+  auto c = ArgClassification::getIndirect(llvm::Align(8), true, 5);
+  EXPECT_EQ(c.kind, ArgKind::Indirect);
+  EXPECT_EQ(c.indirectAddrSpace, 5u);
+  EXPECT_FALSE(c == ArgClassification::getIndirect(llvm::Align(8), true, 0));
+}
+
 TEST(ABIRewriteContextTest, ArgClassificationExtend) {
   MLIRContext mlirCtx;
   auto i8 = IntegerType::get(&mlirCtx, 8);
@@ -86,7 +94,8 @@ TEST(ABIRewriteContextTest, FunctionClassificationHoldsReturnAndArgs) {
   FunctionClassification fc;
   fc.returnInfo = ArgClassification::getDirect();
   fc.argInfos.push_back(ArgClassification::getDirect());
-  fc.argInfos.push_back(ArgClassification::getIndirect(llvm::Align(8), true));
+  fc.argInfos.push_back(
+      ArgClassification::getIndirect(llvm::Align(8), true, 0));
   fc.argInfos.push_back(ArgClassification::getIgnore());
 
   EXPECT_EQ(fc.returnInfo.kind, ArgKind::Direct);

diff  --git a/mlir/unittests/ABI/TestTargetTest.cpp b/mlir/unittests/ABI/TestTargetTest.cpp
index a83f2290b0b589..c1438dd834a3c3 100644
--- a/mlir/unittests/ABI/TestTargetTest.cpp
+++ b/mlir/unittests/ABI/TestTargetTest.cpp
@@ -201,6 +201,23 @@ TEST_F(TestTargetParseTest, ParsesIndirectWithAlignAndByval) {
   EXPECT_EQ(fc.argInfos[0].kind, ArgKind::Indirect);
   EXPECT_EQ(fc.argInfos[0].indirectAlign, llvm::Align(16));
   EXPECT_FALSE(fc.argInfos[0].byVal);
+  EXPECT_EQ(fc.argInfos[0].indirectAddrSpace, 0u);
+}
+
+TEST_F(TestTargetParseTest, ParsesIndirectAddrSpace) {
+  auto indirect = makeArg({
+      builder.getNamedAttr("kind", builder.getStringAttr("indirect")),
+      builder.getNamedAttr("indirect_align", builder.getI64IntegerAttr(8)),
+      builder.getNamedAttr("indirect_addr_space", builder.getI64IntegerAttr(5)),
+  });
+  auto attr = builder.getDictionaryAttr({
+      builder.getNamedAttr("return", indirect),
+      builder.getNamedAttr("args", builder.getArrayAttr({})),
+  });
+
+  auto fc = parseOk(attr);
+  EXPECT_EQ(fc.returnInfo.kind, ArgKind::Indirect);
+  EXPECT_EQ(fc.returnInfo.indirectAddrSpace, 5u);
 }
 
 TEST_F(TestTargetParseTest, ParsesIgnoreAndExpand) {
@@ -301,6 +318,22 @@ TEST_F(TestTargetParseTest, RejectsIndirectWithNonPowerOfTwoAlign) {
   parseError(attr, "must be a positive power of 2");
 }
 
+TEST_F(TestTargetParseTest, RejectsNegativeIndirectAddrSpace) {
+  auto badIndirect = makeArg({
+      builder.getNamedAttr("kind", builder.getStringAttr("indirect")),
+      builder.getNamedAttr("indirect_align", builder.getI64IntegerAttr(8)),
+      builder.getNamedAttr("indirect_addr_space",
+                           builder.getI64IntegerAttr(-1)),
+  });
+  auto direct =
+      makeArg({builder.getNamedAttr("kind", builder.getStringAttr("direct"))});
+  auto attr = builder.getDictionaryAttr({
+      builder.getNamedAttr("return", direct),
+      builder.getNamedAttr("args", builder.getArrayAttr({badIndirect})),
+  });
+  parseError(attr, "'indirect_addr_space' must be non-negative");
+}
+
 TEST_F(TestTargetParseTest, RejectsUnknownKind) {
   auto bad = makeArg(
       {builder.getNamedAttr("kind", builder.getStringAttr("invalid_kind"))});


        


More information about the Mlir-commits mailing list