c++g++constexprpowerpc

constexpr with "long double" fails on ppc64el


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)


Solution

  • 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.

    Wikipedia - long double

    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.