[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