Change powerpc64le's long double from 64-bit double to IEEE 754
binary128 (quad, 113-bit mantissa), matching aarch64 and riscv64.
Gated on FreeBSD 16 and powerpc64le only.
Differential D57388
powerpc64le: switch long double to IEEE binary128 Authored by pkubaj on Mon, Jun 1, 7:17 PM. Tags None Referenced Files
Details
Diff Detail
Event TimelineComment Actions I think it would be useful if you could upstream the clang and compiler-rt parts of this. Otherwise it becomes a bit of a drag when updating to new versions. Comment Actions The clang part will be upstreamed once this patch will go in here. Comment Actions (a) ouch, a flag day for ports heh Comment Actions i appreciate that powerpc64 is a tier 2 port, but even so, i'm a little unsure about breaking ABI compatibility like this. do we have any idea how widespread use of long double is? Comment Actions Basically dropping support for anything below POWER7. IEEE long double is implemented using VSX instructions, so at least using long double on pre-POWER7 will result with SIGILL.
OK, I'll write a mail later. Comment Actions powerpc64 is not affected at all, it will stay forever on 64-bit long double. Only powerpc64le is affected. I scanned bootstraps for rust, ghc, sbcl and openjdk{8,11,17,21,24,25} and all of them should work post-switch. Comment Actions Bump FREEBSD_CC_VERSION, the compiler must be first bootstrapped to Comment Actions ok, the hardware deprecation is more important. you should have mentioned that in your commit message :-) So what's the minimum that ppc64le will support with this change? POWER7? What's the motivation for this change? Comment Actions No, why? The baseline for powerpc64le is currently POWER8 and that won't change. You asked about powerpc64 and I simply answered that doing the same for powerpc64 would raise the baseline to at least POWER7. Comment Actions oh i didn't realise our minimum platform for ppc64le is POWER8. Ok, that makes more sense! Please email -ppc with this review first, let's get the discussion going. I'm ok with a flag day for ports but we will definitely want to give people plenty of warning! Comment Actions LLVM review: https://github.com/llvm/llvm-project/pull/201298 Comment Actions So I asked AI about the possible ports fallout and it seems pretty small in practice: # Ports affected by the powerpc64le IEEE-128 long double switch
Scope: FreeBSD 16, powerpc64le only. The flag-day changes C/C++ `long double`
from 64-bit (== double) to IEEE 754 binary128 (16 bytes, 113-bit mantissa).
Default action for the whole tree is the flag-day **rebuild**; the lists below
are the exceptions that need more than a rebuild, plus the false alarms.
Guiding rule: a port needs an *actual change* only if it either (a) EMITS code
that links base (a compiler), (b) INTROSPECTS the long-double size/format at
build time, or (c) MARSHALS long double across an ABI boundary. A naive
"uses quad / uses float128" scan over-counts, because `__float128` is a
VSX-gated type that is unchanged by this switch -- only what `long double`
aliases changes.
------------------------------------------------------------------------------
## 1. Needs source/config CHANGES (rebuild is NOT enough)
------------------------------------------------------------------------------
- devel/llvmNN, devel/llvm-devel
The 3 clang patches (PPC.h long-double width/format, CGBuiltin.cpp GNU-env
guard, ToolChain.cpp defaultToIEEELongDouble), gated on FreeBSD >= 16 +
ppc64le. Keep the runtime OSMajorVersion gate: one ports tree serves
14/15/16, and CONFIGURE_TARGET embeds the host OSREL, so the gate is what
keeps ports-clang-on-15 at 64-bit and ports-clang-on-16 at binary128.
compiler-rt needs NO ports patch: ports clang links base -lgcc by default,
and base libgcc/libcompiler_rt already carries the __*kf* helpers post
flag-day. (Bundled libclang_rt is only used with -rtlib=compiler-rt.)
- lang/gccNN
Configure with IEEE-128 long double (--with-long-double-format=ieee, or
equivalent) so gcc-built objects match base. This ALSO enables gfortran
real(16) = IEEE binary128, which is currently absent on ppc64le
("Invalid real kind 16").
- lang/flang (LLVM Fortran)
Needs the same IEEE-128 long double / real(16) lowering as clang; verify it
picks up 128-bit rather than riding only the clang change.
- devel/gdb
Verify / patch gdbarch long_double_format so it prints ppc64le-freebsd16
long double as IEEE-128 (existing ppc patches are target-registration, not
float-format).
------------------------------------------------------------------------------
## 2. VERIFY build-time detection (recent versions likely OK; patch only if it
## mis-fires)
------------------------------------------------------------------------------
These detect long double size/format in their own configure/build and are
recent enough to take the generic IEEE-quad path -- confirm, don't pre-patch.
- math/py-numpy 2.4.6 (np.longdouble flips 64->128; format-signature table)
- math/mpfr 4.2.2 (mpfr_set_ld/get_ld; PPC double-double special path)
- math/gmp 6.3.0
- devel/libffi 3.5.1 (3.5.x handles ppc64le IEEE-128 upstream -> rebuild)
- devel/boost-libs 1.89.0 (Boost.Math / Multiprecision)
- lang/R (LDOUBLE accumulators, SIZEOF_LONG_DOUBLE)
- lang/perl5.* (only if built -Duselongdouble)
------------------------------------------------------------------------------
## 3. Flagged by source grep but UNAFFECTED (orthogonal: __float128, not LD)
------------------------------------------------------------------------------
`__float128` is the same VSX-gated IEEE-128 type before and after the switch,
so ports reaching for quad via __float128 do not notice the long-double flip.
- math/givaro (configure.ac: clang __float128 needs -std=c++11)
- devel/libddwaf (vendored {fmt} __float128 formatting toggle)
- misc/free42 (Intel BID decimal-float128 lib; arch-enumeration already
lists powerpc64le -- rebuild only)
------------------------------------------------------------------------------
## 4. Compat libffi: theoretical source gap, NO practical exposure on ppc64le
------------------------------------------------------------------------------
- devel/libffi321 (libffi.so.6) and devel/libffi33 (libffi.so.7)
Predate libffi's ppc64le IEEE-128 long-double marshalling
(__LONG_DOUBLE_IEEE128__, added in 3.4.x); rebuilding does NOT fix this
because the code path is not in their source. They DO build on ppc64le.
BUT their only in-tree ppc64le consumer is:
- devel/stack (built from source; RUN_DEPENDS the old sonames
in lib/compat/ for prebuilt GHC tooling it runs)
(java/bootstrap-openjdk8 also pulls an old libffi soname, but only on arm --
it is NOT a ppc64le consumer.)
Haskell never puts an ffi_type_longdouble in a libffi cif (CLDouble is not
usably implemented), so the gap is never exercised. Patch only if a real
ppc64le consumer ever marshals long double through libffi.so.6/.7 --
realistically none will.
------------------------------------------------------------------------------
## Everything else
------------------------------------------------------------------------------
Flag-day REBUILD only (UPDATING + __FreeBSD_version bump + "rebuild all
ports"). long double is rarely in a library's public ABI; where it is,
recompilation under the new ABI is sufficient. Many C/C++ ports that use long
double for extra precision silently gain true 113-bit quad on ppc64le (vs. the
old 64-bit alias) -- a tree-wide upside, but not an enumerable change-set.
Net edit-needing set: ~4 ports (llvm, gcc, flang, gdb) + a short verify-list.
The rebuild-needing set is the whole tree.Comment Actions So there's just no way to really make stable/15 binaries run on a stable/16 once this is done? Comment Actions Well, just as I wrote above. I have tested bootstraps for all the major languages and they all work - because they don't interact with libc's long double. Anything that doesn't use long double, will continue to work just as before. The only issues will be software actually using long double. It's likely mostly scientific / mathematical software that does some actual computation on large numbers (bigger than 64-bits). But to be safe, everything should be rebuilt. Also, there are some ports that use specifically float128. They will also work fine without rebuilding because they expliclitly point to float128 as opposed to anything that long double resolves to. Comment Actions Also, there is a way to make 100% of binaries work - bump so version and provide the old library in misc/compat15x. |