[Mlir-commits] [clang] [mlir] [mlir][ABI] Add indirect address space to ArgClassification (PR #229991)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Oct 21 01:19:29 PDT 2026
https://github.com/skc7 updated https://github.com/llvm/llvm-project/pull/229991
>From 79140f62f2d989f14210436d021210466aaaabd4 Mon Sep 17 00:00:00 2001
From: skc7 <Krishna.Sankisa at amd.com>
Date: Thu, 8 Oct 2026 10:54:57 +0530
Subject: [PATCH] [mlir][ABI] Add indirect address space to ArgClassification
---
.../Transforms/CallConvLoweringPass.cpp | 3 +-
mlir/include/mlir/ABI/ABIRewriteContext.h | 12 +++++--
.../mlir/ABI/Targets/Test/TestTarget.h | 15 +++++----
mlir/lib/ABI/Targets/Test/TestTarget.cpp | 18 +++++++---
mlir/unittests/ABI/ABIRewriteContextTest.cpp | 8 +++++
mlir/unittests/ABI/TestTargetTest.cpp | 33 +++++++++++++++++++
6 files changed, 76 insertions(+), 13 deletions(-)
diff --git a/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp b/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp
index e0ae978b0db8f4..9f736b920fcc02 100644
--- a/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp
@@ -640,7 +640,8 @@ convertABIArgInfo(const llvm::abi::ArgInfo &info, MLIRContext *ctx,
}
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..fb94cb5559fbcf 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 = true,
+ unsigned addrSpace = 0) {
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..eb831a95a63971 100644
--- a/mlir/lib/ABI/Targets/Test/TestTarget.cpp
+++ b/mlir/lib/ABI/Targets/Test/TestTarget.cpp
@@ -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..47875b3d84100a 100644
--- a/mlir/unittests/ABI/ABIRewriteContextTest.cpp
+++ b/mlir/unittests/ABI/ABIRewriteContextTest.cpp
@@ -60,6 +60,7 @@ TEST(ABIRewriteContextTest, ArgClassificationIndirect) {
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) {
@@ -69,6 +70,13 @@ TEST(ABIRewriteContextTest, ArgClassificationIndirectNoByVal) {
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));
+}
+
TEST(ABIRewriteContextTest, ArgClassificationExtend) {
MLIRContext mlirCtx;
auto i8 = IntegerType::get(&mlirCtx, 8);
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