[llvm] [ABI] Thread alloca address space through getNaturalAlignIndirect (PR #225301)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 21 22:20:03 PDT 2026
https://github.com/skc7 created https://github.com/llvm/llvm-project/pull/225301
Summary:
- Indirect arguments were always emitted in address space 0, dropping the target's alloca address space.
- Mirror classic `ABIInfo::getNaturalAlignIndirect` by making the address space explicit and sourcing it from a target hook, so
targets whose stack lives in a non-default space (e.g. AMDGPU private) are lowered correctly.
Changes:
- `TargetInfo.h`: add `getAllocaAddrSpace()` (default 0), the ABI-library analogue of `DataLayout::getAllocaAddrSpace()`. Make AddrSpace a required parameter of `getNaturalAlignIndirect`.
- `TargetInfo.cpp`: pass AddrSpace into `ArgInfo::getIndirect`.
- X86/AArch64/BPF: pass `getAllocaAddrSpace()` at all `getNaturalAlignIndirect` call sites.
- X86/AArch64 unit tests: assert the indirect address space is 0.
Assisted by: claude opus 4.8
>From ef8bc0accb69a8c92d1d9b3871603728b5a0957a Mon Sep 17 00:00:00 2001
From: skc7 <Krishna.Sankisa at amd.com>
Date: Tue, 22 Sep 2026 10:41:45 +0530
Subject: [PATCH] [ABI] Thread alloca address space through
getNaturalAlignIndirect
---
llvm/include/llvm/ABI/TargetInfo.h | 6 +++++-
llvm/lib/ABI/TargetInfo.cpp | 5 +++--
llvm/lib/ABI/Targets/AArch64.cpp | 10 ++++++----
llvm/lib/ABI/Targets/BPF.cpp | 10 ++++++----
llvm/lib/ABI/Targets/X86.cpp | 9 +++++----
llvm/unittests/ABI/AArch64TargetInfoTest.cpp | 2 ++
llvm/unittests/ABI/X86TargetInfoTest.cpp | 2 ++
7 files changed, 29 insertions(+), 15 deletions(-)
diff --git a/llvm/include/llvm/ABI/TargetInfo.h b/llvm/include/llvm/ABI/TargetInfo.h
index 6f7f29e70bb3d..bf3104187cee3 100644
--- a/llvm/include/llvm/ABI/TargetInfo.h
+++ b/llvm/include/llvm/ABI/TargetInfo.h
@@ -80,11 +80,15 @@ class TargetInfo {
/// store a derived object and return that as an ABICompatInfo reference.
virtual const ABICompatInfo &getABICompatInfo() const = 0;
+ /// Address space in which indirect arguments are allocated (the target's
+ /// alloca/stack space).
+ virtual unsigned getAllocaAddrSpace() const { return 0; }
+
protected:
LLVM_ABI RecordArgABI getRecordArgABI(const RecordType *RT) const;
LLVM_ABI RecordArgABI getRecordArgABI(const Type *Ty) const;
LLVM_ABI bool isPromotableInteger(const IntegerType *IT) const;
- LLVM_ABI ArgInfo getNaturalAlignIndirect(const Type *Ty,
+ LLVM_ABI ArgInfo getNaturalAlignIndirect(const Type *Ty, unsigned AddrSpace,
bool ByVal = true) const;
LLVM_ABI bool isAggregateTypeForABI(const Type *Ty) const;
diff --git a/llvm/lib/ABI/TargetInfo.cpp b/llvm/lib/ABI/TargetInfo.cpp
index 9ad8cb8f5829a..cc146b8a335e4 100644
--- a/llvm/lib/ABI/TargetInfo.cpp
+++ b/llvm/lib/ABI/TargetInfo.cpp
@@ -41,8 +41,9 @@ bool TargetInfo::isPromotableInteger(const IntegerType *IT) const {
return BitWidth < 32;
}
-ArgInfo TargetInfo::getNaturalAlignIndirect(const Type *Ty, bool ByVal) const {
- return ArgInfo::getIndirect(Ty->getAlignment(), ByVal);
+ArgInfo TargetInfo::getNaturalAlignIndirect(const Type *Ty, unsigned AddrSpace,
+ bool ByVal) const {
+ return ArgInfo::getIndirect(Ty->getAlignment(), ByVal, AddrSpace);
}
RecordArgABI TargetInfo::getRecordArgABI(const RecordType *RT) const {
diff --git a/llvm/lib/ABI/Targets/AArch64.cpp b/llvm/lib/ABI/Targets/AArch64.cpp
index 42ba167a1ef5c..ac17773046108 100644
--- a/llvm/lib/ABI/Targets/AArch64.cpp
+++ b/llvm/lib/ABI/Targets/AArch64.cpp
@@ -88,7 +88,7 @@ ArgInfo AArch64TargetInfo::classifyReturnType(const Type *RetTy,
if (const auto *IntTy = dyn_cast<IntegerType>(RetTy)) {
if (IntTy->isBitInt())
if (RetTy->getSizeInBits().getFixedValue() > 128)
- return getNaturalAlignIndirect(RetTy);
+ return getNaturalAlignIndirect(RetTy, getAllocaAddrSpace());
if (isPromotableInteger(IntTy) && isDarwinPCS())
return ArgInfo::getExtend(IntTy);
@@ -126,7 +126,8 @@ ArgInfo AArch64TargetInfo::classifyArgumentType(
if (const auto *IntTy = dyn_cast<IntegerType>(Ty)) {
if (IntTy->isBitInt())
if (Ty->getSizeInBits().getFixedValue() > 128)
- return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
+ return getNaturalAlignIndirect(Ty, getAllocaAddrSpace(),
+ /*ByVal=*/false);
if (isPromotableInteger(IntTy) && isDarwinPCS())
return ArgInfo::getExtend(IntTy);
@@ -144,8 +145,9 @@ ArgInfo AArch64TargetInfo::classifyArgumentType(
// Structures with either a non-trivial destructor or a non-trivial
// copy constructor are always indirect.
if (auto RecordRAA = getRecordArgABI(Ty)) {
- return getNaturalAlignIndirect(Ty, RecordRAA ==
- RecordArgABI::RAA_DirectInMemory);
+ return getNaturalAlignIndirect(Ty, getAllocaAddrSpace(),
+ /*ByVal=*/RecordRAA ==
+ RecordArgABI::RAA_DirectInMemory);
}
TypeSize TySize = Ty->getSizeInBits();
diff --git a/llvm/lib/ABI/Targets/BPF.cpp b/llvm/lib/ABI/Targets/BPF.cpp
index ecaf44eed1960..0a525cf28d6f2 100644
--- a/llvm/lib/ABI/Targets/BPF.cpp
+++ b/llvm/lib/ABI/Targets/BPF.cpp
@@ -25,12 +25,14 @@ class BPFTargetInfo : public TargetInfo {
if (isAggregateTypeForABI(RetTy)) {
if (RetTy->isZeroSize())
return ArgInfo::getIgnore();
- return getNaturalAlignIndirect(RetTy, /*ByVal=*/false);
+ return getNaturalAlignIndirect(RetTy, getAllocaAddrSpace(),
+ /*ByVal=*/false);
}
if (const auto *IntTy = dyn_cast<IntegerType>(RetTy)) {
if (IntTy->isBitInt() && IntTy->getSizeInBits().getFixedValue() > 128)
- return getNaturalAlignIndirect(RetTy, /*ByVal=*/false);
+ return getNaturalAlignIndirect(RetTy, getAllocaAddrSpace(),
+ /*ByVal=*/false);
}
return ArgInfo::getDirect();
@@ -57,12 +59,12 @@ class BPFTargetInfo : public TargetInfo {
return ArgInfo::getDirect(CoerceTy);
}
- return getNaturalAlignIndirect(ArgTy, /*ByVal=*/true);
+ return getNaturalAlignIndirect(ArgTy, getAllocaAddrSpace());
}
if (const auto *IntTy = dyn_cast<IntegerType>(ArgTy)) {
if (IntTy->isBitInt() && IntTy->getSizeInBits().getFixedValue() > 128)
- return getNaturalAlignIndirect(ArgTy, /*ByVal=*/true);
+ return getNaturalAlignIndirect(ArgTy, getAllocaAddrSpace());
if (isPromotableInteger(IntTy))
return ArgInfo::getExtend(ArgTy);
diff --git a/llvm/lib/ABI/Targets/X86.cpp b/llvm/lib/ABI/Targets/X86.cpp
index 78aa9cd1a2519..3e47a37ca5bf7 100644
--- a/llvm/lib/ABI/Targets/X86.cpp
+++ b/llvm/lib/ABI/Targets/X86.cpp
@@ -1354,8 +1354,9 @@ ArgInfo X86_64TargetInfo::getIndirectResult(const Type *Ty,
// Check if this is a record type that needs special handling
if (auto RecordRAA = getRecordArgABI(Ty))
- return getNaturalAlignIndirect(Ty, RecordRAA ==
- RecordArgABI::RAA_DirectInMemory);
+ return getNaturalAlignIndirect(Ty, getAllocaAddrSpace(),
+ /*ByVal=*/RecordRAA ==
+ RecordArgABI::RAA_DirectInMemory);
// Compute the byval alignment. We specify the alignment of the byval in all
// cases so that the mid-level optimizer knows the alignment of the byval.
@@ -1405,14 +1406,14 @@ ArgInfo X86_64TargetInfo::getIndirectReturnResult(const Type *Ty) const {
// Bit-precise integers are returned indirectly regardless of size.
if (const auto *IntTy = dyn_cast<IntegerType>(Ty)) {
if (IntTy->isBitInt())
- return getNaturalAlignIndirect(IntTy, /*ByVal=*/true);
+ return getNaturalAlignIndirect(IntTy, getAllocaAddrSpace());
if (isPromotableInteger(IntTy))
return ArgInfo::getExtend(Ty);
}
return ArgInfo::getDirect();
}
- return getNaturalAlignIndirect(Ty, /*ByVal=*/true);
+ return getNaturalAlignIndirect(Ty, getAllocaAddrSpace());
}
void X86_64TargetInfo::computeInfo(FunctionInfo &FI) const {
diff --git a/llvm/unittests/ABI/AArch64TargetInfoTest.cpp b/llvm/unittests/ABI/AArch64TargetInfoTest.cpp
index 2c140d81c420e..ca61534660b43 100644
--- a/llvm/unittests/ABI/AArch64TargetInfoTest.cpp
+++ b/llvm/unittests/ABI/AArch64TargetInfoTest.cpp
@@ -131,6 +131,7 @@ static void expectAlignedIndirect(const ArgInfo &Info, llvm::Align Align,
EXPECT_TRUE(Info.isIndirect());
EXPECT_EQ(Info.getIndirectAlign(), Align);
EXPECT_EQ(Info.getIndirectByVal(), ByVal);
+ EXPECT_EQ(Info.getIndirectAddrSpace(), 0u);
}
TEST_F(AArch64TargetInfoTest, ClassifyReturnVoidIsIgnore) {
@@ -406,6 +407,7 @@ static void expectNaturalAlignIndirect(const ArgInfo &Info,
EXPECT_TRUE(Info.isIndirect());
EXPECT_EQ(Info.getIndirectAlign(), ExpectedAlign);
EXPECT_EQ(Info.getIndirectByVal(), ByVal);
+ EXPECT_EQ(Info.getIndirectAddrSpace(), 0u);
}
static void expectHFADirectArg(const ArgInfo &Info, const ABIType *Base,
diff --git a/llvm/unittests/ABI/X86TargetInfoTest.cpp b/llvm/unittests/ABI/X86TargetInfoTest.cpp
index 4cf5bc68cc213..021add1d8ac26 100644
--- a/llvm/unittests/ABI/X86TargetInfoTest.cpp
+++ b/llvm/unittests/ABI/X86TargetInfoTest.cpp
@@ -151,6 +151,7 @@ TEST_F(X86TargetInfoTest, AtomicRecordIsIndirect) {
ASSERT_TRUE(Info.isIndirect());
EXPECT_TRUE(Info.getIndirectByVal());
EXPECT_EQ(Info.getIndirectAlign(), llvm::Align(8));
+ EXPECT_EQ(Info.getIndirectAddrSpace(), 0u);
}
// Atomic fields classify Memory rather than inheriting the underlying float's
@@ -169,6 +170,7 @@ TEST_F(X86TargetInfoTest, RecordOfAtomicFloatsIsIndirect) {
ASSERT_TRUE(Info.isIndirect());
EXPECT_TRUE(Info.getIndirectByVal());
EXPECT_EQ(Info.getIndirectAlign(), llvm::Align(8));
+ EXPECT_EQ(Info.getIndirectAddrSpace(), 0u);
}
// Without the atomic wrappers, the same record is passed in an SSE register.
More information about the llvm-commits
mailing list