[llvm] [LLVMABI] Create a skeleton for AArch64 ABI handling (PR #216222)
Andy Kaylor via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 14 15:58:09 PDT 2026
https://github.com/andykaylor updated https://github.com/llvm/llvm-project/pull/216222
>From 0c07a1fb8f884e0e17bda20d0b3006349b938eb5 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akaylor at nvidia.com>
Date: Thu, 13 Aug 2026 10:57:26 -0700
Subject: [PATCH] [LLVMABI] Create a skeleton for AArch64 ABI handling
This change adds the most basic implementation of llvm::abi::TargetInfo for
AArch64 targets and establishes a unit test for it.
There was no isolated testing for previous targets implemented in the ABI
library. They were only tested through clang. My plan with AArch64 is to
create unit tests so that the library can be tested without building the
clang target, but also to have clang tests so that the handling can be
compared to clang's ABI handling as a meaningful point of reference for
correct behavior.
For this initial change, because no real handling is implemented yet, I am
not introducing the clang hook or any clang-based tests.
Assisted-by: Cursor / Grok 4.5 (test generation)
---
llvm/include/llvm/ABI/TargetInfo.h | 10 +++
llvm/lib/ABI/CMakeLists.txt | 1 +
llvm/lib/ABI/Targets/AArch64.cpp | 41 +++++++++
llvm/unittests/ABI/AArch64TargetInfoTest.cpp | 94 ++++++++++++++++++++
llvm/unittests/ABI/CMakeLists.txt | 9 ++
llvm/unittests/CMakeLists.txt | 1 +
6 files changed, 156 insertions(+)
create mode 100644 llvm/lib/ABI/Targets/AArch64.cpp
create mode 100644 llvm/unittests/ABI/AArch64TargetInfoTest.cpp
create mode 100644 llvm/unittests/ABI/CMakeLists.txt
diff --git a/llvm/include/llvm/ABI/TargetInfo.h b/llvm/include/llvm/ABI/TargetInfo.h
index 7d57893da0cf5..b3c1291e8ac94 100644
--- a/llvm/include/llvm/ABI/TargetInfo.h
+++ b/llvm/include/llvm/ABI/TargetInfo.h
@@ -97,6 +97,16 @@ LLVM_ABI std::unique_ptr<TargetInfo>
createX86_64TargetInfo(TypeBuilder &TB, X86AVXABILevel AVXLevel,
bool Has64BitPointers, const ABICompatInfo &Compat);
+enum class AArch64ABIKind {
+ AAPCS = 0,
+ DarwinPCS,
+ Win64,
+ AAPCSSoft,
+};
+
+LLVM_ABI std::unique_ptr<TargetInfo>
+createAArch64TargetInfo(TypeBuilder &TB, AArch64ABIKind Kind);
+
} // namespace abi
} // namespace llvm
diff --git a/llvm/lib/ABI/CMakeLists.txt b/llvm/lib/ABI/CMakeLists.txt
index 47ce5926e6039..39e725ca9fd3b 100644
--- a/llvm/lib/ABI/CMakeLists.txt
+++ b/llvm/lib/ABI/CMakeLists.txt
@@ -3,6 +3,7 @@ add_llvm_component_library(LLVMABI
FunctionInfo.cpp
TargetInfo.cpp
IRTypeMapper.cpp
+ Targets/AArch64.cpp
Targets/BPF.cpp
Targets/X86.cpp
diff --git a/llvm/lib/ABI/Targets/AArch64.cpp b/llvm/lib/ABI/Targets/AArch64.cpp
new file mode 100644
index 0000000000000..d26dec1ad3a0b
--- /dev/null
+++ b/llvm/lib/ABI/Targets/AArch64.cpp
@@ -0,0 +1,41 @@
+//===- AArch64.cpp - AArch64 ABI Implementation ---------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ABI/FunctionInfo.h"
+#include "llvm/ABI/TargetInfo.h"
+#include "llvm/ABI/Types.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+namespace abi {
+
+class AArch64TargetInfo : public TargetInfo {
+public:
+ AArch64TargetInfo(TypeBuilder &TB, AArch64ABIKind Kind)
+ : TB(TB), Kind(Kind) {}
+
+ void computeInfo(FunctionInfo &FI) const override {
+ FI.getReturnInfo() = ArgInfo::getDirect();
+ for (auto &I : FI.arguments())
+ I.Info = ArgInfo::getDirect();
+ }
+
+private:
+ [[maybe_unused]] TypeBuilder &TB;
+ [[maybe_unused]] AArch64ABIKind Kind;
+};
+
+std::unique_ptr<TargetInfo> createAArch64TargetInfo(TypeBuilder &TB,
+ AArch64ABIKind Kind) {
+ if (Kind == AArch64ABIKind::Win64)
+ llvm_unreachable("Win64 ABI not supported yet");
+ return std::make_unique<AArch64TargetInfo>(TB, Kind);
+}
+
+} // namespace abi
+} // namespace llvm
diff --git a/llvm/unittests/ABI/AArch64TargetInfoTest.cpp b/llvm/unittests/ABI/AArch64TargetInfoTest.cpp
new file mode 100644
index 0000000000000..0f4326b9d4d01
--- /dev/null
+++ b/llvm/unittests/ABI/AArch64TargetInfoTest.cpp
@@ -0,0 +1,94 @@
+//===- AArch64TargetInfoTest.cpp - AArch64 ABI unit tests -----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ABI/FunctionInfo.h"
+#include "llvm/ABI/TargetInfo.h"
+#include "llvm/ABI/Types.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/Support/Alignment.h"
+#include "llvm/Support/Allocator.h"
+#include "gtest/gtest.h"
+
+namespace {
+
+using ABIType = llvm::abi::Type;
+using llvm::abi::AArch64ABIKind;
+using llvm::abi::ArgEntry;
+using llvm::abi::ArgInfo;
+using llvm::abi::createAArch64TargetInfo;
+using llvm::abi::FunctionInfo;
+using llvm::abi::TargetInfo;
+using llvm::abi::TypeBuilder;
+
+class AArch64TargetInfoTest : public ::testing::Test {
+protected:
+ llvm::BumpPtrAllocator Alloc;
+ TypeBuilder TB;
+ const ABIType *I32;
+ const ABIType *F64;
+ const ABIType *Ptr;
+ const ABIType *Void;
+
+ AArch64TargetInfoTest()
+ : TB(Alloc), I32(TB.getIntegerType(32, llvm::Align(4), /*Signed=*/true)),
+ F64(TB.getFloatType(llvm::APFloat::IEEEdouble(), llvm::Align(8))),
+ Ptr(TB.getPointerType(64, llvm::Align(8))), Void(TB.getVoidType()) {}
+};
+
+static void expectAllDirect(const FunctionInfo &FI) {
+ EXPECT_TRUE(FI.getReturnInfo().isDirect());
+ EXPECT_EQ(FI.getReturnInfo().getCoerceToType(), nullptr);
+ for (const ArgEntry &Arg : FI.arguments()) {
+ EXPECT_TRUE(Arg.Info.isDirect());
+ EXPECT_EQ(Arg.Info.getCoerceToType(), nullptr);
+ }
+}
+
+TEST_F(AArch64TargetInfoTest, ComputeInfoMarksReturnAndArgsDirect) {
+ std::unique_ptr<TargetInfo> TI =
+ createAArch64TargetInfo(TB, AArch64ABIKind::AAPCS);
+ std::unique_ptr<FunctionInfo> FI =
+ FunctionInfo::create(llvm::CallingConv::C, I32, {I32, F64, Ptr});
+
+ // Poison the defaults so a no-op would fail the assertions below.
+ FI->getReturnInfo() = ArgInfo::getIgnore();
+ for (ArgEntry &Arg : FI->arguments())
+ Arg.Info = ArgInfo::getIgnore();
+
+ TI->computeInfo(*FI);
+ expectAllDirect(*FI);
+}
+
+TEST_F(AArch64TargetInfoTest, ComputeInfoVoidReturnNoArgs) {
+ std::unique_ptr<TargetInfo> TI =
+ createAArch64TargetInfo(TB, AArch64ABIKind::DarwinPCS);
+ std::unique_ptr<FunctionInfo> FI =
+ FunctionInfo::create(llvm::CallingConv::C, Void, {});
+
+ FI->getReturnInfo() = ArgInfo::getIgnore();
+ TI->computeInfo(*FI);
+
+ EXPECT_TRUE(FI->getReturnInfo().isDirect());
+ EXPECT_TRUE(FI->arguments().empty());
+}
+
+TEST_F(AArch64TargetInfoTest, ComputeInfoAAPCSSoftSameAsStub) {
+ std::unique_ptr<TargetInfo> TI =
+ createAArch64TargetInfo(TB, AArch64ABIKind::AAPCSSoft);
+ std::unique_ptr<FunctionInfo> FI =
+ FunctionInfo::create(llvm::CallingConv::C, F64, {I32});
+
+ FI->getReturnInfo() = ArgInfo::getIgnore();
+ FI->getArgInfo(0).Info = ArgInfo::getIgnore();
+
+ TI->computeInfo(*FI);
+ expectAllDirect(*FI);
+}
+
+} // namespace
diff --git a/llvm/unittests/ABI/CMakeLists.txt b/llvm/unittests/ABI/CMakeLists.txt
new file mode 100644
index 0000000000000..fe0431524c7c2
--- /dev/null
+++ b/llvm/unittests/ABI/CMakeLists.txt
@@ -0,0 +1,9 @@
+set(LLVM_LINK_COMPONENTS
+ ABI
+ Core
+ Support
+ )
+
+add_llvm_unittest(ABITests
+ AArch64TargetInfoTest.cpp
+ )
diff --git a/llvm/unittests/CMakeLists.txt b/llvm/unittests/CMakeLists.txt
index 5d507d577bb94..c6ce09b3d67f2 100644
--- a/llvm/unittests/CMakeLists.txt
+++ b/llvm/unittests/CMakeLists.txt
@@ -28,6 +28,7 @@ if (CMAKE_COMPILER_IS_GNUCXX)
list(APPEND LLVM_COMPILE_FLAGS "-Wno-dangling-else")
endif ()
+add_subdirectory(ABI)
add_subdirectory(ADT)
add_subdirectory(Analysis)
add_subdirectory(AsmParser)
More information about the llvm-commits
mailing list