=== Cut === static const double coeff[] = { 1.0l/42 }; === Cut === gives: testcase.c:1: error: initializer element is not constant testcase.c:1: error: (near initialization for ‘coeff[0]’)
This is actually because the middle-end does not constant fold 128bit IBM long double. I am assuming you are using -mlong-double-128.
Which is PR 19779.
I'm not sure 1.0l/42 is a valid constant initializer.
yes, full configure line: Target: powerpc64-suse-linux Configured with: ../configure --enable-threads=posix --prefix=/usr --with-local-prefix=/usr/local --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64 --enable-languages=c,c++,objc,fortran,java --enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.1.0 --enable-ssp --disable-libssp --enable-java-awt=gtk --disable-libjava-multilib --with-slibdir=/lib64 --with-system-zlib --enable-shared --enable-__cxa_atexit --enable-libstdcxx-allocator=new --without-system-libunwind --enable-secureplt --with-long-double-128 --host=powerpc64-suse-linux
hmm, I guess I'm find with resolving this as duplicate to 19779, even though I don't understand why this is only an issue on PPC for me..
(In reply to comment #5) > hmm, I guess I'm find with resolving this as duplicate to 19779, even though I > don't understand why this is only an issue on PPC for me.. It is because the long double format used on PPC is IBM's 128bit long double which is two doubles basicially added together.
Confirmed.
*** Bug 26462 has been marked as a duplicate of this bug. ***
*** Bug 27054 has been marked as a duplicate of this bug. ***
Any progress on this?
(In reply to comment #10) > Any progress on this? There are two way of fixing this as far as I can see: teach real.c about how to fold IBM 128bit long double format use MPFR instead I would use the latter if I got any time but I don't have any time to do either.
*** Bug 31321 has been marked as a duplicate of this bug. ***
*** Bug 260998 has been marked as a duplicate of this bug. *** Seen from the domain http://volichat.com Page where seen: http://volichat.com/adult-chat-rooms Marked for reference. Resolved as fixed @bugzilla.
>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=26374 That is a really old one, from early 2006; I would have hoped that it had long since been repaired in gcc. However, I just checked my VM for CentOS 7 on PowerPC, and found this: % cat foo.c static const double x = 1.0L / 42 ; % /usr/bin/gcc -c foo.c foo.c:1:1: error: initializer element is not computable at load time static const double x = 1.0L / 42 ; That is gcc-4.8.5 (20150623 (Red Hat 4.8.5-44)). I recently built gcc-8.5.0 on that system, and it raises the same error. Changing 42 to 42.0L to have a pure long-double expression does not eliminate the error with either compiler. The assignment is perfectly legal in all ISO Standards for C from 1989 to date, and the expression must be evaluated to IEEE 754 requirements by the compiler, producing a correctly rounded result. That latter would not be possible if it were expressed as a fractional value, because the C Standards do not require correct conversion of decimal fractions to binary fractions. The build of gcc-8.5.0 took five days on this qemu-emulated CPU, so it really is not practical for me to try the test file with gcc-9 through gcc-12 versions. I needed 8.5.0 to be able to build TeX Live 2022: see http://www.math.utah.edu/pub/texlive-utah/#centos-7-ppc64be for my report (and many others elsewhere in that Web page). ------------------------------------------------------------------------------- - Nelson H. F. Beebe Tel: +1 801 581 5254 - - University of Utah FAX: +1 801 581 4148 - - Department of Mathematics, 110 LCB Internet e-mail: beebe@math.utah.edu - - 155 S 1400 E RM 233 beebe@acm.org beebe@computer.org - - Salt Lake City, UT 84112-0090, USA URL: http://www.math.utah.edu/~beebe/ - -------------------------------------------------------------------------------
(In reply to beebe from comment #14) > >> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=26374 > > That is a really old one, from early 2006; I would have hoped that it > had long since been repaired in gcc. > > However, I just checked my VM for CentOS 7 on PowerPC, and found this: Well powerpc currently uses what is called double double for 128bit long double. GCC does not know how to constant fold that nicely. But powerpc linux targets are moving over to use standard 128bit IEEE long double and IIRC for GCC 12 (or is it 13) will default to IEEE long double so this will be less of an issue.
(In reply to Andrew Pinski from comment #15) > (In reply to beebe from comment #14) > > >> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=26374 > > > > That is a really old one, from early 2006; I would have hoped that it > > had long since been repaired in gcc. > > > > However, I just checked my VM for CentOS 7 on PowerPC, and found this: > > Well powerpc currently uses what is called double double for 128bit long > double. GCC does not know how to constant fold that nicely. But powerpc > linux targets are moving over to use standard 128bit IEEE long double and > IIRC for GCC 12 (or is it 13) will default to IEEE long double so this will > be less of an issue. Will not default to unless configured so, but e.g. in Fedora 36 GCC 12 is configured to default to long double being IEEE quad on powerpc64 little endian. As for constant folding, even with double double gcc is able to fold some constant arithmetics in that format, but because the emulation is only approximate (it pretends it is 106-bit precision format while in reality it is variable precision up to some thousands depending on the exact values). As has been said elsewhere, the emulation would be implementable if gcc handled double double in all the arithmetics as a pair of doubles with all the rules for it. But e.g. mpfr/libmpc isn't able to do something like that, so we'd need to compute everything with much bigger precision etc. In any case, I think nobody is going to work on it now that ppc64le is switching to IEEE quad.
>> ... powerpc currently uses what is called double double for 128bit >> long double. GCC does not know how to constant fold that nicely. Yes, I know about the double double format that IBM, SGI, and possibly others introduced in the 1990s for implementing long double. I strongly disapprove of that decision, and wrote about it extensively in my big book The Mathematical-Function Computation Handbook https://doi.org/10.1007/978-3-319-64110-2 http://www.math.utah.edu/pub/tex/bib/master.html#Beebe:2017:MFC that addresses accurate computation in binary and decimal arithmetic, for IEEE 754, and also for some important historical floating-point designs. >> GCC does not know how to constant fold that nicely. Because gcc has used gmp for several years now for correctly rounded conversions of decimal numbers to binary IEEE 754 formats, I would have thought that handling a constant expression like "1.0L / 42.0L" would have been relatively trivial. >> powerpc linux targets are moving over to use standard 128bit IEEE >> long double and IIRC for GCC 12 (or is it 13) will default to IEEE >> long double so this will be less of an issue. Thanks for that interesting news! It is a big change, because it affects both -lc and -lm libraries, plus lots of user code. The IBM POWER architecture was introduced to the world in February 1990, and we here in Utah had some of the earliest models available, so now that we are 2**5 years later, it is high time to conform to IEEE 754. POWER made a big impact for those who learned how to exploit its interesting features. I wrote about it here: High-Performance Matrix Multiplication http://www.math.utah.edu/pub/benchmarks/usirep.pdf That document showed there that a 44x performance boost was possible in some cases, without leaving standard programming languages for assembly code fragments. I wrote a lot more about the importance of understanding architecture and memory designs it here: The Impact of Memory and Architecture on Computer Performance http://www.math.utah.edu/~beebe/memperf.pdf ------------------------------------------------------------------------------- - Nelson H. F. Beebe Tel: +1 801 581 5254 - - University of Utah FAX: +1 801 581 4148 - - Department of Mathematics, 110 LCB Internet e-mail: beebe@math.utah.edu - - 155 S 1400 E RM 233 beebe@acm.org beebe@computer.org - - Salt Lake City, UT 84112-0090, USA URL: http://www.math.utah.edu/~beebe/ - -------------------------------------------------------------------------------
Note, for the time being only little endian powerpc64 can switch (I think only power9 and later have hw support for IEEE quad and in the ABI it is passed in Altivec/VSX registers. ppc64le only supports power8 and later CPUs.
Thanks for the further comments on PowerPC, double double as fake long double, and the news of gcc-12 on Fedora 36 for that CPU. I'll soon build a VM to get access to that combination. I have VMs already for PowerPC on CentOS 7 (big endian), CentOS 8 (little endian), and Debian 10 (little endian). Let's consider the initializer bug an "unfixed (mis)feature" of gcc history, and move on to better arithmetic! ------------------------------------------------------------------------------- - Nelson H. F. Beebe Tel: +1 801 581 5254 - - University of Utah FAX: +1 801 581 4148 - - Department of Mathematics, 110 LCB Internet e-mail: beebe@math.utah.edu - - 155 S 1400 E RM 233 beebe@acm.org beebe@computer.org - - Salt Lake City, UT 84112-0090, USA URL: http://www.math.utah.edu/~beebe/ - -------------------------------------------------------------------------------
Double-double has advantages and disadvantages. You're welcome to debate William Kahan about the choice instead of making snarky comments here.
(In reply to Jakub Jelinek from comment #16) > As for constant folding, even with double double gcc is able to fold some > constant arithmetics in that format, but because the emulation is only > approximate (it pretends it is 106-bit precision format while in reality it > is variable precision up to some thousands depending on the exact values). > As has been said elsewhere, the emulation would be implementable if gcc > handled double double in all the arithmetics as a pair of doubles with all > the rules for it. But e.g. mpfr/libmpc isn't able to do something like > that, so we'd need to compute everything with much bigger precision etc. Well, the C standard does not require correct rounding, and while correct rounding is important for the IEEE formats, it is rather useless for the double-double format, whose goal was just to provide more precision than double, but still be rather fast (compared to quad emulation). The main drawback would be that results could be different whether a FP expression is evaluated at run time or at compile time, but unless users seek to control everything (e.g. with IEEE formats), they should get use to that (FYI, you can have the same kind of issues with the contraction of FP expressions, such as FMA generation from mul-add, which GCC enable by default). So, in short, doing the compile-time evaluation at a 106-bit precision or more would be acceptable IMHO, at least better than a compiler error. Note: Even though double-double can be very interesting as a compromise between performance and accuracy, there exist various algorithms and which algorithm should be chosen depends on the context, which only the author of the program can know in general. Thus it was a bad idea to implement double-double as a native FP type (here, long double); instead, the selection of the algorithms should be left to the developer. So the switch to IEEE quad is a good thing. But for how long will old ABIs be around?
Yesterday, I got a Fedora 36 PPC64LE VM up, and left it installing hundreds of packages overnight. QEMU 4.2.1 on Ubuntu 20.04 picks a default CPU type of POWER9. Alas, the ISO installation gets nicely into a normal boot, then dies with a kernel panic. I changed the default CPU type to POWER8, and that led to a successful installation. This morning, I built my feature test package http://www.math.utah.edu/pub/features/ and got this nice report back: LDBL_DECIMAL_DIG = 36 LDBL_DIG = 33 LDBL_EPSILON = 0x1p-112 LDBL_HAS_SUBNORM = 1 LDBL_MANT_DIG = 113 LDBL_MAX = 0x1.ffffffffffffffffffffffffffffp+16383 LDBL_MAX_10_EXP = 4932 LDBL_MAX_EXP = 16384 LDBL_MIN = 0x1p-16382 LDBL_MIN_10_EXP = -4931 LDBL_MIN_EXP = -16381 LDBL_NORM_MAX = [not defined] LDBL_TRUE_MIN = 0x0.0000000000000000000000000001p-16382 HUGE_VALL = inf ... Computed long double limits: smallest floating-point number: 0.00000000e+00 == 2^(-16494) [IEEE 754 smallest 128-bit subnormal] machine epsilon: 1.92592994e-34 == 2^(-112) [IEEE 754 128-bit conformant] long double appears to be 128-bit value stored in 128-bit (16-byte) field That indicates that long double implemented as doubled double is now history on this platform, and that is good news for me. Thanks for telling me about this change for Fedora on PowePC. ------------------------------------------------------------------------------- - Nelson H. F. Beebe Tel: +1 801 581 5254 - - University of Utah FAX: +1 801 581 4148 - - Department of Mathematics, 110 LCB Internet e-mail: beebe@math.utah.edu - - 155 S 1400 E RM 233 beebe@acm.org beebe@computer.org - - Salt Lake City, UT 84112-0090, USA URL: http://www.math.utah.edu/~beebe/ - -------------------------------------------------------------------------------
Dup. *** This bug has been marked as a duplicate of bug 19779 ***