[llvm] ARM: Start moving runtime libcall configuration out of TargetLowering (PR #142617)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 9 06:03:53 PDT 2025
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/142617
>From b03650006a21db2601edbcfac7bf270f650e652d Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Tue, 3 Jun 2025 03:55:53 +0200
Subject: [PATCH] ARM: Start moving runtime libcall configuration out of
TargetLowering
These Module level triple checks implemented in the Subtarget are kind of
a pain and we should probably get rid of all of them in across all targets,
and stick to a consistent set of names.
---
llvm/include/llvm/TargetParser/Triple.h | 28 +++++++++++++
llvm/lib/IR/RuntimeLibcalls.cpp | 55 ++++++++++++++++++++++++-
llvm/lib/Target/ARM/ARMISelLowering.cpp | 44 --------------------
llvm/lib/Target/ARM/ARMSubtarget.h | 30 +++-----------
4 files changed, 86 insertions(+), 71 deletions(-)
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index 7fd5278f1ed53..351da0d6598c2 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -917,6 +917,34 @@ class Triple {
isOSBinFormatELF();
}
+ // ARM EABI is the bare-metal EABI described in ARM ABI documents and
+ // can be accessed via -target arm-none-eabi. This is NOT GNUEABI.
+ // FIXME: Add a flag for bare-metal for that target and set Triple::EABI
+ // even for GNUEABI, so we can make a distinction here and still conform to
+ // the EABI on GNU (and Android) mode. This requires change in Clang, too.
+ // FIXME: The Darwin exception is temporary, while we move users to
+ // "*-*-*-macho" triples as quickly as possible.
+ bool isTargetAEABI() const {
+ return (getEnvironment() == Triple::EABI ||
+ getEnvironment() == Triple::EABIHF) &&
+ !isOSDarwin() && !isOSWindows();
+ }
+
+ bool isTargetGNUAEABI() const {
+ return (getEnvironment() == Triple::GNUEABI ||
+ getEnvironment() == Triple::GNUEABIT64 ||
+ getEnvironment() == Triple::GNUEABIHF ||
+ getEnvironment() == Triple::GNUEABIHFT64) &&
+ !isOSDarwin() && !isOSWindows();
+ }
+
+ bool isTargetMuslAEABI() const {
+ return (getEnvironment() == Triple::MuslEABI ||
+ getEnvironment() == Triple::MuslEABIHF ||
+ getEnvironment() == Triple::OpenHOS) &&
+ !isOSDarwin() && !isOSWindows();
+ }
+
/// Tests whether the target is T32.
bool isArmT32() const {
switch (getSubArch()) {
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index 54227deddc53d..cffbd54f5bc84 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -31,6 +31,56 @@ static void setAArch64LibcallNames(RuntimeLibcallsInfo &Info,
}
}
+static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT) {
+ // Register based DivRem for AEABI (RTABI 4.2)
+ if (TT.isTargetAEABI() || TT.isAndroid() || TT.isTargetGNUAEABI() ||
+ TT.isTargetMuslAEABI() || TT.isOSWindows()) {
+ if (TT.isOSWindows()) {
+ const struct {
+ const RTLIB::Libcall Op;
+ const char *const Name;
+ const CallingConv::ID CC;
+ } LibraryCalls[] = {
+ {RTLIB::SDIVREM_I8, "__rt_sdiv", CallingConv::ARM_AAPCS},
+ {RTLIB::SDIVREM_I16, "__rt_sdiv", CallingConv::ARM_AAPCS},
+ {RTLIB::SDIVREM_I32, "__rt_sdiv", CallingConv::ARM_AAPCS},
+ {RTLIB::SDIVREM_I64, "__rt_sdiv64", CallingConv::ARM_AAPCS},
+
+ {RTLIB::UDIVREM_I8, "__rt_udiv", CallingConv::ARM_AAPCS},
+ {RTLIB::UDIVREM_I16, "__rt_udiv", CallingConv::ARM_AAPCS},
+ {RTLIB::UDIVREM_I32, "__rt_udiv", CallingConv::ARM_AAPCS},
+ {RTLIB::UDIVREM_I64, "__rt_udiv64", CallingConv::ARM_AAPCS},
+ };
+
+ for (const auto &LC : LibraryCalls) {
+ Info.setLibcallName(LC.Op, LC.Name);
+ Info.setLibcallCallingConv(LC.Op, LC.CC);
+ }
+ } else {
+ const struct {
+ const RTLIB::Libcall Op;
+ const char *const Name;
+ const CallingConv::ID CC;
+ } LibraryCalls[] = {
+ {RTLIB::SDIVREM_I8, "__aeabi_idivmod", CallingConv::ARM_AAPCS},
+ {RTLIB::SDIVREM_I16, "__aeabi_idivmod", CallingConv::ARM_AAPCS},
+ {RTLIB::SDIVREM_I32, "__aeabi_idivmod", CallingConv::ARM_AAPCS},
+ {RTLIB::SDIVREM_I64, "__aeabi_ldivmod", CallingConv::ARM_AAPCS},
+
+ {RTLIB::UDIVREM_I8, "__aeabi_uidivmod", CallingConv::ARM_AAPCS},
+ {RTLIB::UDIVREM_I16, "__aeabi_uidivmod", CallingConv::ARM_AAPCS},
+ {RTLIB::UDIVREM_I32, "__aeabi_uidivmod", CallingConv::ARM_AAPCS},
+ {RTLIB::UDIVREM_I64, "__aeabi_uldivmod", CallingConv::ARM_AAPCS},
+ };
+
+ for (const auto &LC : LibraryCalls) {
+ Info.setLibcallName(LC.Op, LC.Name);
+ Info.setLibcallCallingConv(LC.Op, LC.CC);
+ }
+ }
+ }
+}
+
/// Set default libcall names. If a target wants to opt-out of a libcall it
/// should be placed here.
void RuntimeLibcallsInfo::initLibcalls(const Triple &TT) {
@@ -264,8 +314,9 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT) {
if (TT.getArch() == Triple::ArchType::aarch64)
setAArch64LibcallNames(*this, TT);
-
- if (TT.getArch() == Triple::ArchType::avr) {
+ else if (TT.isARM() || TT.isThumb())
+ setARMLibcallNames(*this, TT);
+ else if (TT.getArch() == Triple::ArchType::avr) {
// Division rtlib functions (not supported), use divmod functions instead
setLibcallName(RTLIB::SDIV_I8, nullptr);
setLibcallName(RTLIB::SDIV_I16, nullptr);
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 574281d12e3cb..785c8f779ea5d 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -1275,50 +1275,6 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::UREM, MVT::i64, Custom);
HasStandaloneRem = false;
- if (Subtarget->isTargetWindows()) {
- const struct {
- const RTLIB::Libcall Op;
- const char * const Name;
- const CallingConv::ID CC;
- } LibraryCalls[] = {
- { RTLIB::SDIVREM_I8, "__rt_sdiv", CallingConv::ARM_AAPCS },
- { RTLIB::SDIVREM_I16, "__rt_sdiv", CallingConv::ARM_AAPCS },
- { RTLIB::SDIVREM_I32, "__rt_sdiv", CallingConv::ARM_AAPCS },
- { RTLIB::SDIVREM_I64, "__rt_sdiv64", CallingConv::ARM_AAPCS },
-
- { RTLIB::UDIVREM_I8, "__rt_udiv", CallingConv::ARM_AAPCS },
- { RTLIB::UDIVREM_I16, "__rt_udiv", CallingConv::ARM_AAPCS },
- { RTLIB::UDIVREM_I32, "__rt_udiv", CallingConv::ARM_AAPCS },
- { RTLIB::UDIVREM_I64, "__rt_udiv64", CallingConv::ARM_AAPCS },
- };
-
- for (const auto &LC : LibraryCalls) {
- setLibcallName(LC.Op, LC.Name);
- setLibcallCallingConv(LC.Op, LC.CC);
- }
- } else {
- const struct {
- const RTLIB::Libcall Op;
- const char * const Name;
- const CallingConv::ID CC;
- } LibraryCalls[] = {
- { RTLIB::SDIVREM_I8, "__aeabi_idivmod", CallingConv::ARM_AAPCS },
- { RTLIB::SDIVREM_I16, "__aeabi_idivmod", CallingConv::ARM_AAPCS },
- { RTLIB::SDIVREM_I32, "__aeabi_idivmod", CallingConv::ARM_AAPCS },
- { RTLIB::SDIVREM_I64, "__aeabi_ldivmod", CallingConv::ARM_AAPCS },
-
- { RTLIB::UDIVREM_I8, "__aeabi_uidivmod", CallingConv::ARM_AAPCS },
- { RTLIB::UDIVREM_I16, "__aeabi_uidivmod", CallingConv::ARM_AAPCS },
- { RTLIB::UDIVREM_I32, "__aeabi_uidivmod", CallingConv::ARM_AAPCS },
- { RTLIB::UDIVREM_I64, "__aeabi_uldivmod", CallingConv::ARM_AAPCS },
- };
-
- for (const auto &LC : LibraryCalls) {
- setLibcallName(LC.Op, LC.Name);
- setLibcallCallingConv(LC.Op, LC.CC);
- }
- }
-
setOperationAction(ISD::SDIVREM, MVT::i32, Custom);
setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
setOperationAction(ISD::SDIVREM, MVT::i64, Custom);
diff --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h
index 7329d3f2055f0..890a22f574a6b 100644
--- a/llvm/lib/Target/ARM/ARMSubtarget.h
+++ b/llvm/lib/Target/ARM/ARMSubtarget.h
@@ -348,31 +348,11 @@ class ARMSubtarget : public ARMGenSubtargetInfo {
bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
- // ARM EABI is the bare-metal EABI described in ARM ABI documents and
- // can be accessed via -target arm-none-eabi. This is NOT GNUEABI.
- // FIXME: Add a flag for bare-metal for that target and set Triple::EABI
- // even for GNUEABI, so we can make a distinction here and still conform to
- // the EABI on GNU (and Android) mode. This requires change in Clang, too.
- // FIXME: The Darwin exception is temporary, while we move users to
- // "*-*-*-macho" triples as quickly as possible.
- bool isTargetAEABI() const {
- return (TargetTriple.getEnvironment() == Triple::EABI ||
- TargetTriple.getEnvironment() == Triple::EABIHF) &&
- !isTargetDarwin() && !isTargetWindows();
- }
- bool isTargetGNUAEABI() const {
- return (TargetTriple.getEnvironment() == Triple::GNUEABI ||
- TargetTriple.getEnvironment() == Triple::GNUEABIT64 ||
- TargetTriple.getEnvironment() == Triple::GNUEABIHF ||
- TargetTriple.getEnvironment() == Triple::GNUEABIHFT64) &&
- !isTargetDarwin() && !isTargetWindows();
- }
- bool isTargetMuslAEABI() const {
- return (TargetTriple.getEnvironment() == Triple::MuslEABI ||
- TargetTriple.getEnvironment() == Triple::MuslEABIHF ||
- TargetTriple.getEnvironment() == Triple::OpenHOS) &&
- !isTargetDarwin() && !isTargetWindows();
- }
+ bool isTargetAEABI() const { return TargetTriple.isTargetAEABI(); }
+
+ bool isTargetGNUAEABI() const { return TargetTriple.isTargetGNUAEABI(); }
+
+ bool isTargetMuslAEABI() const { return TargetTriple.isTargetMuslAEABI(); }
// ARM Targets that support EHABI exception handling standard
// Darwin uses SjLj. Other targets might need more checks.
More information about the llvm-commits
mailing list