[llvm-branch-commits] [llvm] Triple: Add query for the default long double format (PR #211239)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Jul 22 04:45:09 PDT 2026
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
More information about the llvm-branch-commits
mailing list