From 72a218056d68b7aa65ab3eda56837117bb59f11a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Fri, 20 Sep 2024 02:53:03 +0200 Subject: [PATCH] [llvm][Triple] Add `Environment` members and parsing for glibc/musl parity. (#107664) This adds support for: * `muslabin32` (MIPS N32) * `muslabi64` (MIPS N64) * `muslf32` (LoongArch ILP32F/LP64F) * `muslsf` (LoongArch ILP32S/LP64S) As we start adding glibc/musl cross-compilation support for these targets in Zig, it would make our life easier if LLVM recognized these triples. I'm hoping this'll be uncontroversial since the same has already been done for `musleabi`, `musleabihf`, and `muslx32`. I intentionally left out a musl equivalent of `gnuf64` (LoongArch ILP32D/LP64D); my understanding is that Loongson ultimately settled on simply `gnu` for this much more common case, so there doesn't *seem* to be a particularly compelling reason to add a `muslf64` that's basically deprecated on arrival. Note: I don't have commit access. --- clang/lib/Basic/Targets/Mips.h | 2 +- clang/lib/Driver/Driver.cpp | 6 + .../lib/Driver/ToolChains/Arch/LoongArch.cpp | 2 + clang/lib/Driver/ToolChains/Arch/Mips.cpp | 2 +- clang/lib/Driver/ToolChains/Gnu.cpp | 6 +- clang/lib/Driver/ToolChains/Linux.cpp | 3 + llvm/include/llvm/TargetParser/Triple.h | 14 +++ .../MCTargetDesc/LoongArchBaseInfo.cpp | 2 + .../Target/Mips/MCTargetDesc/MipsABIInfo.cpp | 3 +- llvm/lib/TargetParser/Triple.cpp | 12 ++ .../Instrumentation/AddressSanitizer.cpp | 2 +- llvm/unittests/TargetParser/TripleTest.cpp | 108 ++++++++++++++++++ 12 files changed, 153 insertions(+), 9 deletions(-) diff --git a/clang/lib/Basic/Targets/Mips.h b/clang/lib/Basic/Targets/Mips.h index b6f110249fa78e..45425db3ac27ad 100644 --- a/clang/lib/Basic/Targets/Mips.h +++ b/clang/lib/Basic/Targets/Mips.h @@ -70,7 +70,7 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo { if (Triple.isMIPS32()) setABI("o32"); - else if (Triple.getEnvironment() == llvm::Triple::GNUABIN32) + else if (Triple.isABIN32()) setABI("n32"); else setABI("n64"); diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index efe398dd531da7..1c64ceabad1bf4 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -667,11 +667,17 @@ static llvm::Triple computeTargetTriple(const Driver &D, if (Target.getEnvironment() == llvm::Triple::GNU || Target.getEnvironment() == llvm::Triple::GNUABI64) Target.setEnvironment(llvm::Triple::GNUABIN32); + else if (Target.getEnvironment() == llvm::Triple::Musl || + Target.getEnvironment() == llvm::Triple::MuslABI64) + Target.setEnvironment(llvm::Triple::MuslABIN32); } else if (ABIName == "64") { Target = Target.get64BitArchVariant(); if (Target.getEnvironment() == llvm::Triple::GNU || Target.getEnvironment() == llvm::Triple::GNUABIN32) Target.setEnvironment(llvm::Triple::GNUABI64); + else if (Target.getEnvironment() == llvm::Triple::Musl || + Target.getEnvironment() == llvm::Triple::MuslABIN32) + Target.setEnvironment(llvm::Triple::MuslABI64); } } } diff --git a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp index 1e8aac71dc9ba7..771adade93813f 100644 --- a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp +++ b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp @@ -103,8 +103,10 @@ StringRef loongarch::getLoongArchABI(const Driver &D, const ArgList &Args, // present, falling back to {ILP32,LP64}D otherwise. switch (Triple.getEnvironment()) { case llvm::Triple::GNUSF: + case llvm::Triple::MuslSF: return IsLA32 ? "ilp32s" : "lp64s"; case llvm::Triple::GNUF32: + case llvm::Triple::MuslF32: return IsLA32 ? "ilp32f" : "lp64f"; case llvm::Triple::GNUF64: // This was originally permitted (and indeed the canonical way) to diff --git a/clang/lib/Driver/ToolChains/Arch/Mips.cpp b/clang/lib/Driver/ToolChains/Arch/Mips.cpp index 79a00711e6f53c..6a2f7936fca39f 100644 --- a/clang/lib/Driver/ToolChains/Arch/Mips.cpp +++ b/clang/lib/Driver/ToolChains/Arch/Mips.cpp @@ -80,7 +80,7 @@ void mips::getMipsCPUAndABI(const ArgList &Args, const llvm::Triple &Triple, } } - if (ABIName.empty() && (Triple.getEnvironment() == llvm::Triple::GNUABIN32)) + if (ABIName.empty() && Triple.isABIN32()) ABIName = "n32"; if (ABIName.empty() && diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index 603d0468dd3f3c..09bb2df4391027 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -269,13 +269,11 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) { case llvm::Triple::mipsel: return "elf32ltsmip"; case llvm::Triple::mips64: - if (tools::mips::hasMipsAbiArg(Args, "n32") || - T.getEnvironment() == llvm::Triple::GNUABIN32) + if (tools::mips::hasMipsAbiArg(Args, "n32") || T.isABIN32()) return "elf32btsmipn32"; return "elf64btsmip"; case llvm::Triple::mips64el: - if (tools::mips::hasMipsAbiArg(Args, "n32") || - T.getEnvironment() == llvm::Triple::GNUABIN32) + if (tools::mips::hasMipsAbiArg(Args, "n32") || T.isABIN32()) return "elf32ltsmipn32"; return "elf64ltsmip"; case llvm::Triple::systemz: diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index 96680b3412a2db..59c048cd209c77 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -109,13 +109,16 @@ std::string Linux::getMultiarchTriple(const Driver &D, default: return TargetTriple.str(); case llvm::Triple::GNUSF: + case llvm::Triple::MuslSF: FPFlavor = "sf"; break; case llvm::Triple::GNUF32: + case llvm::Triple::MuslF32: FPFlavor = "f32"; break; case llvm::Triple::GNU: case llvm::Triple::GNUF64: + case llvm::Triple::Musl: // This was going to be "f64" in an earlier Toolchain Conventions // revision, but starting from Feb 2023 the F64 ABI variants are // unmarked in their canonical forms. diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h index e504128714c556..7c7bf785cee94c 100644 --- a/llvm/include/llvm/TargetParser/Triple.h +++ b/llvm/include/llvm/TargetParser/Triple.h @@ -257,8 +257,12 @@ class Triple { EABIHF, Android, Musl, + MuslABIN32, + MuslABI64, MuslEABI, MuslEABIHF, + MuslF32, + MuslSF, MuslX32, MSVC, @@ -783,8 +787,12 @@ class Triple { /// Tests whether the environment is musl-libc bool isMusl() const { return getEnvironment() == Triple::Musl || + getEnvironment() == Triple::MuslABIN32 || + getEnvironment() == Triple::MuslABI64 || getEnvironment() == Triple::MuslEABI || getEnvironment() == Triple::MuslEABIHF || + getEnvironment() == Triple::MuslF32 || + getEnvironment() == Triple::MuslSF || getEnvironment() == Triple::MuslX32 || getEnvironment() == Triple::OpenHOS || isOSLiteOS(); } @@ -1033,6 +1041,12 @@ class Triple { getSubArch() == Triple::AArch64SubArch_arm64e; } + // Tests whether the target is N32. + bool isABIN32() const { + EnvironmentType Env = getEnvironment(); + return Env == Triple::GNUABIN32 || Env == Triple::MuslABIN32; + } + /// Tests whether the target is X32. bool isX32() const { EnvironmentType Env = getEnvironment(); diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.cpp index 17bcacedfc5114..c24f416c2b6407 100644 --- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.cpp +++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.cpp @@ -55,9 +55,11 @@ static ABI getTripleABI(const Triple &TT) { ABI TripleABI; switch (TT.getEnvironment()) { case llvm::Triple::EnvironmentType::GNUSF: + case llvm::Triple::EnvironmentType::MuslSF: TripleABI = Is64Bit ? ABI_LP64S : ABI_ILP32S; break; case llvm::Triple::EnvironmentType::GNUF32: + case llvm::Triple::EnvironmentType::MuslF32: TripleABI = Is64Bit ? ABI_LP64F : ABI_ILP32F; break; // Let the fallback case behave like {ILP32,LP64}D. diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp index 3aa78224432d54..490765e7d09696 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp @@ -62,7 +62,7 @@ MipsABIInfo MipsABIInfo::computeTargetABI(const Triple &TT, StringRef CPU, return MipsABIInfo::N32(); if (Options.getABIName().starts_with("n64")) return MipsABIInfo::N64(); - if (TT.getEnvironment() == llvm::Triple::GNUABIN32) + if (TT.isABIN32()) return MipsABIInfo::N32(); assert(Options.getABIName().empty() && "Unknown ABI option for MIPS"); @@ -125,4 +125,3 @@ unsigned MipsABIInfo::GetEhDataReg(unsigned I) const { return IsN64() ? EhDataReg64[I] : EhDataReg[I]; } - diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp index 55911a7d71ac70..26ab1be4eb5a52 100644 --- a/llvm/lib/TargetParser/Triple.cpp +++ b/llvm/lib/TargetParser/Triple.cpp @@ -325,8 +325,16 @@ StringRef Triple::getEnvironmentTypeName(EnvironmentType Kind) { case MSVC: return "msvc"; case MacABI: return "macabi"; case Musl: return "musl"; + case MuslABIN32: + return "muslabin32"; + case MuslABI64: + return "muslabi64"; case MuslEABI: return "musleabi"; case MuslEABIHF: return "musleabihf"; + case MuslF32: + return "muslf32"; + case MuslSF: + return "muslsf"; case MuslX32: return "muslx32"; case Simulator: return "simulator"; case Pixel: return "pixel"; @@ -694,8 +702,12 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { .StartsWith("code16", Triple::CODE16) .StartsWith("gnu", Triple::GNU) .StartsWith("android", Triple::Android) + .StartsWith("muslabin32", Triple::MuslABIN32) + .StartsWith("muslabi64", Triple::MuslABI64) .StartsWith("musleabihf", Triple::MuslEABIHF) .StartsWith("musleabi", Triple::MuslEABI) + .StartsWith("muslf32", Triple::MuslF32) + .StartsWith("muslsf", Triple::MuslSF) .StartsWith("muslx32", Triple::MuslX32) .StartsWith("musl", Triple::Musl) .StartsWith("msvc", Triple::MSVC) diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index 8f1e3e0764a7f1..2ad89b5ba753a5 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -489,7 +489,7 @@ static ShadowMapping getShadowMapping(const Triple &TargetTriple, int LongSize, TargetTriple.getArch() == Triple::ppc64le; bool IsSystemZ = TargetTriple.getArch() == Triple::systemz; bool IsX86_64 = TargetTriple.getArch() == Triple::x86_64; - bool IsMIPSN32ABI = TargetTriple.getEnvironment() == Triple::GNUABIN32; + bool IsMIPSN32ABI = TargetTriple.isABIN32(); bool IsMIPS32 = TargetTriple.isMIPS32(); bool IsMIPS64 = TargetTriple.isMIPS64(); bool IsArmOrThumb = TargetTriple.isARM() || TargetTriple.isThumb(); diff --git a/llvm/unittests/TargetParser/TripleTest.cpp b/llvm/unittests/TargetParser/TripleTest.cpp index 0aecfc64da2080..f4d53e41b6c3a7 100644 --- a/llvm/unittests/TargetParser/TripleTest.cpp +++ b/llvm/unittests/TargetParser/TripleTest.cpp @@ -655,6 +655,18 @@ TEST(TripleTest, ParsedIDs) { EXPECT_EQ(Triple::Linux, T.getOS()); EXPECT_EQ(Triple::Musl, T.getEnvironment()); + T = Triple("loongarch32-unknown-linux-muslf32"); + EXPECT_EQ(Triple::loongarch32, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::MuslF32, T.getEnvironment()); + + T = Triple("loongarch32-unknown-linux-muslsf"); + EXPECT_EQ(Triple::loongarch32, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::MuslSF, T.getEnvironment()); + T = Triple("loongarch64-unknown-linux"); EXPECT_EQ(Triple::loongarch64, T.getArch()); EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); @@ -691,6 +703,18 @@ TEST(TripleTest, ParsedIDs) { EXPECT_EQ(Triple::Linux, T.getOS()); EXPECT_EQ(Triple::Musl, T.getEnvironment()); + T = Triple("loongarch64-unknown-linux-muslf32"); + EXPECT_EQ(Triple::loongarch64, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::MuslF32, T.getEnvironment()); + + T = Triple("loongarch64-unknown-linux-muslsf"); + EXPECT_EQ(Triple::loongarch64, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::MuslSF, T.getEnvironment()); + T = Triple("riscv32-unknown-unknown"); EXPECT_EQ(Triple::riscv32, T.getArch()); EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); @@ -926,6 +950,90 @@ TEST(TripleTest, ParsedIDs) { EXPECT_EQ(Triple::GNU, T.getEnvironment()); EXPECT_EQ(Triple::MipsSubArch_r6, T.getSubArch()); + T = Triple("mips64el-unknown-linux-muslabi64"); + EXPECT_EQ(Triple::mips64el, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::MuslABI64, T.getEnvironment()); + EXPECT_EQ(Triple::NoSubArch, T.getSubArch()); + + T = Triple("mips64-unknown-linux-muslabi64"); + EXPECT_EQ(Triple::mips64, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::MuslABI64, T.getEnvironment()); + EXPECT_EQ(Triple::NoSubArch, T.getSubArch()); + + T = Triple("mipsisa64r6el-unknown-linux-muslabi64"); + EXPECT_EQ(Triple::mips64el, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::MuslABI64, T.getEnvironment()); + EXPECT_EQ(Triple::MipsSubArch_r6, T.getSubArch()); + + T = Triple("mipsisa64r6-unknown-linux-muslabi64"); + EXPECT_EQ(Triple::mips64, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::MuslABI64, T.getEnvironment()); + EXPECT_EQ(Triple::MipsSubArch_r6, T.getSubArch()); + + T = Triple("mips64el-unknown-linux-muslabin32"); + EXPECT_EQ(Triple::mips64el, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::MuslABIN32, T.getEnvironment()); + EXPECT_EQ(Triple::NoSubArch, T.getSubArch()); + + T = Triple("mips64-unknown-linux-muslabin32"); + EXPECT_EQ(Triple::mips64, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::MuslABIN32, T.getEnvironment()); + EXPECT_EQ(Triple::NoSubArch, T.getSubArch()); + + T = Triple("mipsisa64r6el-unknown-linux-muslabin32"); + EXPECT_EQ(Triple::mips64el, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::MuslABIN32, T.getEnvironment()); + EXPECT_EQ(Triple::MipsSubArch_r6, T.getSubArch()); + + T = Triple("mipsisa64r6-unknown-linux-muslabin32"); + EXPECT_EQ(Triple::mips64, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::MuslABIN32, T.getEnvironment()); + EXPECT_EQ(Triple::MipsSubArch_r6, T.getSubArch()); + + T = Triple("mipsel-unknown-linux-musl"); + EXPECT_EQ(Triple::mipsel, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::Musl, T.getEnvironment()); + EXPECT_EQ(Triple::NoSubArch, T.getSubArch()); + + T = Triple("mips-unknown-linux-musl"); + EXPECT_EQ(Triple::mips, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::Musl, T.getEnvironment()); + EXPECT_EQ(Triple::NoSubArch, T.getSubArch()); + + T = Triple("mipsisa32r6el-unknown-linux-musl"); + EXPECT_EQ(Triple::mipsel, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::Musl, T.getEnvironment()); + EXPECT_EQ(Triple::MipsSubArch_r6, T.getSubArch()); + + T = Triple("mipsisa32r6-unknown-linux-musl"); + EXPECT_EQ(Triple::mips, T.getArch()); + EXPECT_EQ(Triple::UnknownVendor, T.getVendor()); + EXPECT_EQ(Triple::Linux, T.getOS()); + EXPECT_EQ(Triple::Musl, T.getEnvironment()); + EXPECT_EQ(Triple::MipsSubArch_r6, T.getSubArch()); + T = Triple("arm-oe-linux-gnueabi"); EXPECT_EQ(Triple::arm, T.getArch()); EXPECT_EQ(Triple::OpenEmbedded, T.getVendor());