Skip to content

__FLT_EVAL_METHOD__ is set to -1 with Ofast. #60781

Closed
llvm/llvm-project-release-prs
#360
@davemgreen

Description

@davemgreen

On Linux, math.h includes this:

/* Get __GLIBC_FLT_EVAL_METHOD.  */
#include <bits/flt-eval-method.h>

#ifdef __USE_ISOC99
/* Define the following typedefs.

    float_t	floating-point type at least as wide as `float' used
		to evaluate `float' expressions
    double_t	floating-point type at least as wide as `double' used
		to evaluate `double' expressions
*/
# if __GLIBC_FLT_EVAL_METHOD == 0 || __GLIBC_FLT_EVAL_METHOD == 16
typedef float float_t;
typedef double double_t;
# elif __GLIBC_FLT_EVAL_METHOD == 1
typedef double float_t;
typedef double double_t;
# elif __GLIBC_FLT_EVAL_METHOD == 2
typedef long double float_t;
typedef long double double_t;
# elif __GLIBC_FLT_EVAL_METHOD == 32
typedef _Float32 float_t;
typedef double double_t;
# elif __GLIBC_FLT_EVAL_METHOD == 33
typedef _Float32x float_t;
typedef _Float32x double_t;
# elif __GLIBC_FLT_EVAL_METHOD == 64
typedef _Float64 float_t;
typedef _Float64 double_t;
# elif __GLIBC_FLT_EVAL_METHOD == 65
typedef _Float64x float_t;
typedef _Float64x double_t;
# elif __GLIBC_FLT_EVAL_METHOD == 128
typedef _Float128 float_t;
typedef _Float128 double_t;
# elif __GLIBC_FLT_EVAL_METHOD == 129
typedef _Float128x float_t;
typedef _Float128x double_t;
# else
#  error "Unknown __GLIBC_FLT_EVAL_METHOD"
# endif
#endif

bits/flt-eval-method.h is this:

#ifdef __FLT_EVAL_METHOD__
# if __FLT_EVAL_METHOD__ == -1
#  define __GLIBC_FLT_EVAL_METHOD	2
# else
#  define __GLIBC_FLT_EVAL_METHOD	__FLT_EVAL_METHOD__
# endif
#elif defined __x86_64__
# define __GLIBC_FLT_EVAL_METHOD	0
#else
# define __GLIBC_FLT_EVAL_METHOD	2
#endif

After https://reviews.llvm.org/D109239 with Clang with -Ofast, __FLT_EVAL_METHOD__ gets a value of -1, meaning it is set by that to 2 and we end up using long double for float_t and double_t.
https://godbolt.org/z/PqsxrxYqn

From the comments in D109239 it doesn't appear it was expected to be used in this way. It created an ABI break for float_t and double_t types, along with using the very inefficient long double types on some architectures.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions