diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h index cbf85b2ff74f5..657f4230379e8 100644 --- a/llvm/include/llvm/TargetParser/Triple.h +++ b/llvm/include/llvm/TargetParser/Triple.h @@ -20,6 +20,7 @@ #undef sparc namespace llvm { +enum class ExceptionHandling; class Twine; /// Triple - Helper class for working with autoconf configuration names. For @@ -1321,6 +1322,8 @@ class Triple { /// Returns whether an OS version is invalid and would not map to an Apple OS. LLVM_ABI static bool isValidVersionForOS(OSType OSKind, const VersionTuple &Version); + + LLVM_ABI ExceptionHandling getDefaultExceptionHandling() const; }; } // End llvm namespace diff --git a/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp b/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp index 125ffd597bf23..e54419758410a 100644 --- a/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp +++ b/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp @@ -80,6 +80,10 @@ void CodeGenTargetMachineImpl::initAsmInfo() { TmpAsmInfo->setFullRegisterNames(Options.MCOptions.PPCUseFullRegisterNames); + assert(TmpAsmInfo->getExceptionHandlingType() == + getTargetTriple().getDefaultExceptionHandling() && + "MCAsmInfo and Triple disagree on default exception handling type"); + if (Options.ExceptionModel != ExceptionHandling::None) TmpAsmInfo->setExceptionsType(Options.ExceptionModel); diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp index a348640d75f26..45ef8c1329759 100644 --- a/llvm/lib/TargetParser/Triple.cpp +++ b/llvm/lib/TargetParser/Triple.cpp @@ -11,6 +11,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/CodeGen.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/SwapByteOrder.h" #include "llvm/Support/VersionTuple.h" @@ -2255,6 +2256,55 @@ bool Triple::isValidVersionForOS(OSType OSKind, const VersionTuple &Version) { llvm_unreachable("unexpected or invalid os version"); } +ExceptionHandling Triple::getDefaultExceptionHandling() const { + if (isOSBinFormatCOFF()) { + if (getArch() == Triple::x86 && + (isOSCygMing() || isWindowsItaniumEnvironment())) + return ExceptionHandling::DwarfCFI; + return ExceptionHandling::WinEH; + } + + if (isOSBinFormatXCOFF()) + return ExceptionHandling::AIX; + if (isOSBinFormatGOFF()) + return ExceptionHandling::ZOS; + + if (isARM() || isThumb()) { + if (isOSBinFormatELF()) { + return getOS() == Triple::NetBSD ? ExceptionHandling::DwarfCFI + : ExceptionHandling::ARM; + } + + return isOSDarwin() && !isWatchABI() ? ExceptionHandling::SjLj + : ExceptionHandling::DwarfCFI; + } + + if (isAArch64() || isX86() || isPPC() || isMIPS() || isSPARC() || isBPF() || + isRISCV() || isLoongArch()) + return ExceptionHandling::DwarfCFI; + + switch (getArch()) { + case Triple::arc: + case Triple::csky: + case Triple::hexagon: + case Triple::lanai: + case Triple::msp430: + case Triple::systemz: + case Triple::xcore: + case Triple::xtensa: + return ExceptionHandling::DwarfCFI; + default: + break; + } + + // Explicitly none targets. + if (isWasm() || isAMDGPU() || isNVPTX() || isSPIROrSPIRV()) + return ExceptionHandling::None; + + // Default to none. + return ExceptionHandling::None; +} + // HLSL triple environment orders are relied on in the front end static_assert(Triple::Vertex - Triple::Pixel == 1, "incorrect HLSL stage order"); diff --git a/llvm/unittests/TargetParser/TripleTest.cpp b/llvm/unittests/TargetParser/TripleTest.cpp index 4d547011c1568..4fa7438e5cfc6 100644 --- a/llvm/unittests/TargetParser/TripleTest.cpp +++ b/llvm/unittests/TargetParser/TripleTest.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "llvm/TargetParser/Triple.h" +#include "llvm/Support/CodeGen.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/VersionTuple.h" #include "gtest/gtest.h" @@ -2757,6 +2758,151 @@ TEST(TripleTest, FileFormat) { EXPECT_EQ(Triple::DXContainer, Triple("dxil-apple-macosx").getObjectFormat()); } +TEST(TripleTest, DefaultExceptionHandling) { + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("i686-unknown-linux-gnu").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("i686-unknown-freebsd").getDefaultExceptionHandling()); + + EXPECT_EQ(ExceptionHandling::None, + Triple("wasm32-unknown-wasi-wasm").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::None, + Triple("wasm64-unknown-wasi-wasm").getDefaultExceptionHandling()); + + EXPECT_EQ( + ExceptionHandling::ARM, + Triple("arm-unknown-linux-android16").getDefaultExceptionHandling()); + + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("armv6-unknown-netbsd-eabi").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::ARM, + Triple("armv7-suse-linux-gnueabihf").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::ARM, + Triple("thumbv7-linux-gnueabihf").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("thumbv7-none-netbsd").getDefaultExceptionHandling()); + + EXPECT_EQ(ExceptionHandling::ZOS, + Triple("s390x-ibm-zos").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("systemz-ibm-linux").getDefaultExceptionHandling()); + + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("sparcel-unknown-unknown").getDefaultExceptionHandling()); + + EXPECT_EQ(ExceptionHandling::None, + Triple("amdgcn--").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::None, + Triple("nvptx64--").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::None, + Triple("spirv32--").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::None, + Triple("spirv64--").getDefaultExceptionHandling()); + + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("i686-pc-windows-msvc-elf").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::WinEH, + Triple("i686-pc-windows-msvc").getDefaultExceptionHandling()); + + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("i386-apple-darwin9").getDefaultExceptionHandling()); + + EXPECT_EQ(ExceptionHandling::WinEH, + Triple("x86_64-unknown-uefi").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::DwarfCFI, // ??? + Triple("x86_64-unknown-msvc").getDefaultExceptionHandling()); + + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("riscv32-unknown-unknown").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("riscv64-unknown-unknown").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("xcore-unknown-unknown").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("xtensa-unknown-unknown").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("lanai-unknown-unknown").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("arc-unknown-unknown").getDefaultExceptionHandling()); + EXPECT_EQ( + ExceptionHandling::DwarfCFI, + Triple("loongarch32-unknown-unknown").getDefaultExceptionHandling()); + EXPECT_EQ( + ExceptionHandling::DwarfCFI, + Triple("loongarch64-unknown-unknown").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("msp430-unknown-unknown").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("csky-unknown-unknown").getDefaultExceptionHandling()); + + EXPECT_EQ(ExceptionHandling::AIX, + Triple("powerpc-ibm-aix").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::AIX, + Triple("powerpc---xcoff").getDefaultExceptionHandling()); + + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("powerpc-apple-macosx").getDefaultExceptionHandling()); + + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("i686-pc-cygwin-elf").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("x86_64-pc-cygwin-elf").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::WinEH, + Triple("x86_64-pc-win32").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::WinEH, + Triple("x86_64-pc-windows-coreclr").getDefaultExceptionHandling()); + + EXPECT_EQ(ExceptionHandling::None, + Triple("ve-unknown-linux").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::None, + Triple("ve-unknown-unknown").getDefaultExceptionHandling()); + + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("armv7k-apple-watchos").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::SjLj, + Triple("armv7-apple-ios").getDefaultExceptionHandling()); + + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("mips64-mti-linux-gnu").getDefaultExceptionHandling()); + + EXPECT_EQ(ExceptionHandling::WinEH, + Triple("mipsel-windows--coff").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("mipsel-windows-msvc").getDefaultExceptionHandling()); + + EXPECT_EQ( + ExceptionHandling::WinEH, + Triple("aarch64-unknown-windows-msvc").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("aarch64-unknown-unknown").getDefaultExceptionHandling()); + + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("arm64_32-apple-ios").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("arm64-apple-macosx").getDefaultExceptionHandling()); + + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("xcore-xmos-elf").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::WinEH, + Triple("i386-pc-windows-msvc").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("i386-mingw32").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::WinEH, + Triple("i386-pc-win32").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("i386-pc-mingw32").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("i686-pc-cygwin").getDefaultExceptionHandling()); + + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("x86_64-pc-mingw64").getDefaultExceptionHandling()); + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("x86_64-win32-gnu").getDefaultExceptionHandling()); + + EXPECT_EQ(ExceptionHandling::DwarfCFI, + Triple("x86_64-scei-ps4").getDefaultExceptionHandling()); +} + TEST(TripleTest, NormalizeWindows) { EXPECT_EQ("i686-pc-windows-msvc", Triple::normalize("i686-pc-win32")); EXPECT_EQ("i686-unknown-windows-msvc", Triple::normalize("i686-win32"));