llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-llvm-ir Author: Matt Arsenault (arsenm) <details> <summary>Changes</summary> The long double format changes the library call info, which needs to be computed independently of codegen. Implement this based on the clang target code. --- Full diff: https://github.com/llvm/llvm-project/pull/211239.diff 4 Files Affected: - (modified) llvm/include/llvm/Support/CodeGen.h (+9) - (modified) llvm/include/llvm/TargetParser/Triple.h (+4) - (modified) llvm/lib/TargetParser/Triple.cpp (+58) - (modified) llvm/unittests/TargetParser/TripleTest.cpp (+161) ``````````diff diff --git a/llvm/include/llvm/Support/CodeGen.h b/llvm/include/llvm/Support/CodeGen.h index 62be46ffb8bd3..d29b24101c723 100644 --- a/llvm/include/llvm/Support/CodeGen.h +++ b/llvm/include/llvm/Support/CodeGen.h @@ -70,6 +70,15 @@ namespace llvm { }; } + /// The floating-point format used for the target's "long double" type. + enum class LongDoubleFormat { + IEEEsingle, + IEEEdouble, + X87DoubleExtended, + IEEEquad, + PPCDoubleDouble, + }; + enum class EABI { Unknown, Default, // Default means not specified diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h index 141926473c9eb..18634a8bbe6ff 100644 --- a/llvm/include/llvm/TargetParser/Triple.h +++ b/llvm/include/llvm/TargetParser/Triple.h @@ -1257,6 +1257,10 @@ class Triple { /// Tests if the target's default floating-point ABI is hard float. bool isHardFloatABI() const { return getDefaultFloatABI() == FloatABI::Hard; } + /// Returns the default floating-point format for the "long double" type. A + /// particular module may override this default. + LLVM_ABI LongDoubleFormat getDefaultLongDoubleFormat() const; + /// Tests whether the target supports comdat bool supportsCOMDAT() const { return !(isOSBinFormatMachO() || isOSBinFormatXCOFF() || diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp index 333cd0d6d68aa..4710d1df40811 100644 --- a/llvm/lib/TargetParser/Triple.cpp +++ b/llvm/lib/TargetParser/Triple.cpp @@ -2581,6 +2581,64 @@ FloatABI::ABIType Triple::getDefaultFloatABI() const { return FloatABI::Hard; } +LongDoubleFormat Triple::getDefaultLongDoubleFormat() const { + switch (getArch()) { + case loongarch64: + case riscv32: + case riscv64: + case riscv32be: + case riscv64be: + case sparc: + case sparcel: + case sparcv9: + case systemz: + case ve: + case wasm32: + case wasm64: + return LongDoubleFormat::IEEEquad; + case ppc: + case ppcle: + case ppc64: + case ppc64le: + // PowerPC uses IBM double-double, except on a handful of OSes that use + // plain IEEE double. NetBSD only switches to IEEE double on 32-bit PowerPC. + if (isOSAIX() || isOSFreeBSD() || isOSOpenBSD() || isMusl() || + (isOSNetBSD() && isPPC32())) + return LongDoubleFormat::IEEEdouble; + return LongDoubleFormat::PPCDoubleDouble; + case x86: + case x86_64: + // Android and OHOS use IEEE double on 32-bit and IEEE quad on 64-bit. + if (isAndroid() || isOHOSFamily()) + return isX86_64() ? LongDoubleFormat::IEEEquad + : LongDoubleFormat::IEEEdouble; + // Windows-MSVC and UEFI use IEEE double. MinGW and Cygwin keep x87. + if (isWindowsMSVCEnvironment() || isUEFI()) + return LongDoubleFormat::IEEEdouble; + return LongDoubleFormat::X87DoubleExtended; + case aarch64: + case aarch64_be: + case aarch64_32: + // AArch64 uses IEEE quad, except on Windows, Darwin, and Android. + if (isOSWindows() || isOSDarwin() || isAndroid()) + return LongDoubleFormat::IEEEdouble; + return LongDoubleFormat::IEEEquad; + case mips64: + case mips64el: + return LongDoubleFormat::IEEEquad; + case avr: + case tce: + case tcele: + // AVR and 32-bit OpenASIP use IEEE single precision. + return LongDoubleFormat::IEEEsingle; + case tcele64: + // 64-bit OpenASIP uses IEEE double, unlike its 32-bit variants. + return LongDoubleFormat::IEEEdouble; + default: + return LongDoubleFormat::IEEEdouble; + } +} + // 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 28d541a703417..219e3ce9c0baf 100644 --- a/llvm/unittests/TargetParser/TripleTest.cpp +++ b/llvm/unittests/TargetParser/TripleTest.cpp @@ -1687,6 +1687,167 @@ TEST(TripleTest, DefaultFloatABI) { EXPECT_EQ(FloatABI::Hard, Triple("amdgpu-amd-amdhsa").getDefaultFloatABI()); } +TEST(TripleTest, DefaultLongDoubleFormat) { + // PowerPC defaults to IBM double-double, independent of the environment. + EXPECT_EQ( + LongDoubleFormat::PPCDoubleDouble, + Triple("powerpc64le-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::PPCDoubleDouble, + Triple("powerpc64le-unknown-linux").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::PPCDoubleDouble, + Triple("powerpc64-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::PPCDoubleDouble, + Triple("powerpc64-unknown-linux").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::PPCDoubleDouble, + Triple("powerpc-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::PPCDoubleDouble, + Triple("powerpc-unknown-linux").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::PPCDoubleDouble, + Triple("powerpcle-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::PPCDoubleDouble, + Triple("powerpcle-unknown-linux").getDefaultLongDoubleFormat()); + // ... except on AIX, FreeBSD, OpenBSD, and Musl, which use IEEE double. + EXPECT_EQ(LongDoubleFormat::IEEEdouble, + Triple("powerpc-ibm-aix").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEdouble, + Triple("powerpc64-ibm-aix").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEdouble, + Triple("powerpc64-unknown-freebsd").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEdouble, + Triple("powerpc64-unknown-openbsd").getDefaultLongDoubleFormat()); + EXPECT_EQ( + LongDoubleFormat::IEEEdouble, + Triple("powerpc64-unknown-linux-musl").getDefaultLongDoubleFormat()); + // NetBSD only switches to IEEE double on 32-bit PowerPC. + EXPECT_EQ(LongDoubleFormat::IEEEdouble, + Triple("powerpc-unknown-netbsd").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::PPCDoubleDouble, + Triple("powerpc64-unknown-netbsd").getDefaultLongDoubleFormat()); + + // X86 defaults to x87 80-bit extended precision, independent of environment. + EXPECT_EQ(LongDoubleFormat::X87DoubleExtended, + Triple("x86_64-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::X87DoubleExtended, + Triple("x86_64-unknown-linux").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::X87DoubleExtended, + Triple("i686-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::X87DoubleExtended, + Triple("i686-unknown-linux").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::X87DoubleExtended, + Triple("x86_64-apple-macosx").getDefaultLongDoubleFormat()); + // MinGW and Cygwin keep x87 extended precision. + EXPECT_EQ(LongDoubleFormat::X87DoubleExtended, + Triple("x86_64-pc-windows-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::X87DoubleExtended, + Triple("x86_64-pc-cygwin").getDefaultLongDoubleFormat()); + // Windows-MSVC and UEFI use IEEE double. + EXPECT_EQ(LongDoubleFormat::IEEEdouble, + Triple("x86_64-pc-windows-msvc").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEdouble, + Triple("i686-pc-windows-msvc").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEdouble, + Triple("x86_64-unknown-uefi").getDefaultLongDoubleFormat()); + // Android and OHOS use IEEE double on 32-bit and IEEE quad on 64-bit. + EXPECT_EQ(LongDoubleFormat::IEEEdouble, + Triple("i686-unknown-linux-android").getDefaultLongDoubleFormat()); + EXPECT_EQ( + LongDoubleFormat::IEEEquad, + Triple("x86_64-unknown-linux-android").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEdouble, + Triple("i686-unknown-linux-ohos").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEquad, + Triple("x86_64-unknown-linux-ohos").getDefaultLongDoubleFormat()); + + // AArch64 defaults to IEEE quad, for all AArch64 arch variants, independent + // of the environment. + EXPECT_EQ(LongDoubleFormat::IEEEquad, + Triple("aarch64-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEquad, + Triple("aarch64-unknown-linux").getDefaultLongDoubleFormat()); + EXPECT_EQ( + LongDoubleFormat::IEEEquad, + Triple("aarch64_be-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ( + LongDoubleFormat::IEEEquad, + Triple("aarch64_32-unknown-linux-gnu").getDefaultLongDoubleFormat()); + // ... except on Windows, Darwin, and Android, which use IEEE double. + EXPECT_EQ(LongDoubleFormat::IEEEdouble, + Triple("aarch64-pc-windows-msvc").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEdouble, + Triple("arm64-apple-macosx").getDefaultLongDoubleFormat()); + EXPECT_EQ( + LongDoubleFormat::IEEEdouble, + Triple("aarch64-unknown-linux-android").getDefaultLongDoubleFormat()); + + // ARM/Thumb use IEEE double. + EXPECT_EQ( + LongDoubleFormat::IEEEdouble, + Triple("armv7-unknown-linux-gnueabihf").getDefaultLongDoubleFormat()); + EXPECT_EQ( + LongDoubleFormat::IEEEdouble, + Triple("thumbv7-unknown-linux-gnueabi").getDefaultLongDoubleFormat()); + + // Targets that use IEEE quad, independent of the environment. + EXPECT_EQ(LongDoubleFormat::IEEEquad, + Triple("s390x-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEquad, + Triple("s390x-unknown-linux").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEquad, + Triple("sparc-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEquad, + Triple("sparcel-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEquad, + Triple("sparcv9-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEquad, + Triple("riscv32-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEquad, + Triple("riscv64-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEquad, + Triple("riscv32be-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEquad, + Triple("riscv64be-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ( + LongDoubleFormat::IEEEquad, + Triple("loongarch64-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEquad, + Triple("ve-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEquad, + Triple("wasm32-unknown-unknown").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEquad, + Triple("wasm64-unknown-unknown").getDefaultLongDoubleFormat()); + + // 64-bit MIPS uses IEEE quad; 32-bit MIPS uses IEEE double. Both are + // independent of the environment. + EXPECT_EQ(LongDoubleFormat::IEEEquad, + Triple("mips64-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEquad, + Triple("mips64-unknown-linux").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEquad, + Triple("mips64el-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEdouble, + Triple("mips-unknown-linux-gnu").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEdouble, + Triple("mips-unknown-linux").getDefaultLongDoubleFormat()); + + // AVR and 32-bit OpenASIP use IEEE single; the 64-bit tcele64 uses double. + EXPECT_EQ(LongDoubleFormat::IEEEsingle, + Triple("avr-unknown-unknown").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEsingle, + Triple("tce-unknown-unknown").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEsingle, + Triple("tcele-unknown-unknown").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEdouble, + Triple("tcele64-unknown-unknown").getDefaultLongDoubleFormat()); + + // Targets without a special case fall back to IEEE double. + EXPECT_EQ(LongDoubleFormat::IEEEdouble, + Triple("msp430-unknown-unknown").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEdouble, + Triple("amdgpu-unknown-unknown").getDefaultLongDoubleFormat()); + EXPECT_EQ(LongDoubleFormat::IEEEdouble, + Triple("nvptx64-unknown-unknown").getDefaultLongDoubleFormat()); +} + TEST(TripleTest, Normalization) { EXPECT_EQ("unknown", Triple::normalize("")); `````````` </details> https://github.com/llvm/llvm-project/pull/211239 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
