Bug 114742 - invalid use of '__ieee128' in <ext/numeric_traits.h> and <format>
Summary: invalid use of '__ieee128' in <ext/numeric_traits.h> and <format>
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 14.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-04-16 13:16 UTC by Matthias Kretz (Vir)
Modified: 2024-09-20 09:52 UTC (History)
6 users (show)

See Also:
Host:
Target: powerpc64le-unknown-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed: 2024-04-16 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Matthias Kretz (Vir) 2024-04-16 13:16:09 UTC
https://compiler-explorer.com/z/K3GYY7Msc

Testcase:

#include <bit>
#include <format>

Compile on power64le with -O2 -std=c++23 -mcpu=power6 and optionally with  -mlong-double-64
Comment 1 Jonathan Wakely 2024-04-16 13:19:15 UTC
I think we need something like this in <bits/c++config.h>

#ifndef __VSX__
# undef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT
#endif

Otherwise we might set the ALT128_COMPAT macro during configure, but then it becomes invalidated during compilation of user code if they "downgrade" to something that doesn't support ieee128, using -mcpu=power6 and/or -mlong-double-64
Comment 2 Jonathan Wakely 2024-04-16 13:22:50 UTC
Mathias noted that still fails with -mcpu=power7

Checking for _ARCH_PWR8 or __POWER8_VECTOR__ instead works.
Comment 3 Peter Bergner 2024-09-19 22:03:02 UTC
Adding Mike and Segher to correct me if I'm wrong on anything... :-)

The canonical method for determining whether a specific cpu has VSX enabled or not is checking for "#if defined(_ARCH_PWR*) && defined(__VSX__)".  I believe we're trying to move away from testing things like "__POWER8_VECTOR__".

I seem to be blanking on the minimum cpu required for __ieee128, so I'll let Mike or Segher comment on that.  I thought is was Power7, which would mean using _ARCH_PWR7 above, but given -mcpu=power7 still fails, maybe Power8 is the minimum needed for __ieee128 support?  Mike and Segher???
Comment 4 Michael Meissner 2024-09-20 01:56:15 UTC
The minimum architecture for IEEE 128-bit support is power7, because it needs the VSX registers to pass and return IEEE 128-bit values.

Now, in theory, IEEE 128-bit support could have required only Altivec support (i.e. power6 adding -maltivec), but it was decided that the minimum processor to support IEEE 128-bit would be power7.

Note, that the minimum CPU support for little endian is power8.  So, using -mcpu=power6 or -mcpu=power7 on a LE system is not supported.

On power8 systems, IEEE 128-bit is emulated in software.  On power9 systems, IEEE 128-bit has hardware support.

The macro __LONG_DOUBLE_IEEE128__ is defined if long double uses the IEEE 128-bit format, and __LONG_DOUBLE_IBM128__ is defined if long double uses the IBM 128-bit format that uses a pair of doubles.
Comment 5 Jonathan Wakely 2024-09-20 08:52:55 UTC
(In reply to Michael Meissner from comment #4)
> The macro __LONG_DOUBLE_IEEE128__ is defined if long double uses the IEEE
> 128-bit format, and __LONG_DOUBLE_IBM128__ is defined if long double uses
> the IBM 128-bit format that uses a pair of doubles.

Yes, and libstdc++ relies on those heavily. But they isn't useful here, because those macros say what the *active* long double format is. The point of the _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT macro is to say that the library needs to support two long double formats at the same time. That is independent of which one happens to be active during a given compilation.

There are files in libstdc++ which use both __ibm128 and __ieee128 in the same translation unit, but we need to not do that when __ieee128 is disabled by an option like -mlong-double-64


(In reply to Michael Meissner from comment #4)
> Note, that the minimum CPU support for little endian is power8.  So, using
> -mcpu=power6 or -mcpu=power7 on a LE system is not supported.

Ah! OK, so maybe this isn't an issue at all? The Compiler Explorer link in comment 0 is using power64le for both examples. If I switch the selected compilers to power64 (i.e. BE) there are no errors when using -mcpu=power6 or -mlong-double-64

But maybe that's because the compiler explorer VM for power64 BE has an old glibc without __float128 support in libm, and so in theory somebody could be running BE on a new glibc and need ALT128_COMPAT.
Comment 6 Jakub Jelinek 2024-09-20 09:05:02 UTC
At least glibc on powerpc64 be I think doesn't have any __float128/_Float128 support I think.
Comment 7 Jonathan Wakely 2024-09-20 09:52:51 UTC
OK, then ALT128_COMPAT is effectively only for LE.

So I think I'll make whatever change is needed so that ALT128_COMPAT isn't defined for power6 LE and power7 LE, so the errors Matthias found don't happen. But I won't spend time trying to actually make it work well on the unsupported power6 LE combo.