For whatever reasons, gcc (g++ (Debian 14.2.0-7) 14.2.0
) on powerpc64le, cannot evaluate a constexpr
with a long double
division:
void test() {
constexpr auto oneThird = ((long double) 1)/ ((long double) 3);
}
While this works nicely on many CPU-architectures, on ppc64el (and afaict on all powerpc architectures) this fails with (e.g. on godbolt):
error: '(1.0e+0l / 3.0e+0l)' is not a constant expression
Is this simply a bug in gcc? (clang
seems to be able to handle this)
There have been similar questions, you may see this one.
The reason is PowerPC uses the ‘double-double’ type for long double
, whose format is not IEEE-compliant.
It's being stored like struct { double high; double low; }
Real floating-point type, usually mapped to an extended precision floating-point number format. Actual properties unspecified. It can be either x86 extended-precision floating-point format (80 bits, but typically 96 bits or 128 bits in memory with padding bytes), the non-IEEE "double-double" (128 bits), IEEE 754 quadruple-precision floating-point format (128 bits), or the same as double. See the article on long double for details.
Is this simply a bug in gcc? (clang seems to be able to handle this)
That's why GCC may not be able to handle this instruction.
As a workaround, you may pass the flag -mabi=ieeelongdouble
to GCC.
EDIT: Clang indeed supports this instruction.
As @umläute commented, it's also possible to pass the flags -ffast-math
or -funsafe-math-optimizations
as a workaround.