Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FP constant expressions evaluated incorrectly with FLT_EVAL_METHOD == 2 #89128

Open
jcranmer-intel opened this issue Apr 17, 2024 · 2 comments
Open
Labels
c99 clang:frontend Language frontend issues, e.g. anything involving "Sema" floating-point Floating-point math

Comments

@jcranmer-intel
Copy link
Contributor

On systems with FLT_EVAL_METHOD == 2 (i.e., x87-based floating-point computation), arithmetic expressions using float and double should be evaluated using long double instead. Clang isn't doing this:

#include <float.h>
#include <stdio.h>

static double const_init = 1.0 + (DBL_EPSILON/2) + (DBL_EPSILON/2);
int main() {
    double nonconst_init = 1.0;
    nonconst_init = nonconst_init + (DBL_EPSILON/2) + (DBL_EPSILON/2);
    printf("FLT_EVAL_METHOD = %d\n", FLT_EVAL_METHOD);
    printf("const: %g\n", const_init - 1.0);
    printf("nonconst: %g\n", (double)nonconst_init - 1.0);
}

When compiled on an x86 system with -m32 -mno-sse, the correct result should be that the two lines both output 2.22045e-16, which icc is able to successfully do. However clang and gcc both report 0 for the first line and 2.22045e-16 for the second: https://godbolt.org/z/4xGoaaoKP.

(At first glance, this sounds exactly like #88956, but that is about constants and this is about constant expressions).

C99 section 6.6p5 says

If a floating expression is evaluated in the translation environment, the arithmetic precision and range shall be at least as great as if the expression were being evaluated in the execution environment.

C11 adds a footnote explicitly saying that FLT_EVAL_METHOD also applies to the translation environment, and C23 adds DEC_EVAL_METHOD to the footnote, but otherwise the text remains the same in all versions of C.

@jcranmer-intel jcranmer-intel added clang:frontend Language frontend issues, e.g. anything involving "Sema" c99 floating-point Floating-point math labels Apr 17, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Apr 17, 2024

@llvm/issue-subscribers-clang-frontend

Author: Joshua Cranmer (jcranmer-intel)

On systems with FLT_EVAL_METHOD == 2 (i.e., x87-based floating-point computation), arithmetic expressions using `float` and `double` should be evaluated using `long double` instead. Clang isn't doing this:
#include &lt;float.h&gt;
#include &lt;stdio.h&gt;

static double const_init = 1.0 + (DBL_EPSILON/2) + (DBL_EPSILON/2);
int main() {
    double nonconst_init = 1.0;
    nonconst_init = nonconst_init + (DBL_EPSILON/2) + (DBL_EPSILON/2);
    printf("FLT_EVAL_METHOD = %d\n", FLT_EVAL_METHOD);
    printf("const: %g\n", const_init - 1.0);
    printf("nonconst: %g\n", (double)nonconst_init - 1.0);
}

When compiled on an x86 system with -m32 -mno-sse, the correct result should be that the two lines both output 2.22045e-16, which icc is able to successfully do. However clang and gcc both report 0 for the first line and 2.22045e-16 for the second: https://godbolt.org/z/4xGoaaoKP.

(At first glance, this sounds exactly like #88956, but that is about constants and this is about constant expressions).

C99 section 6.6p5 says
> If a floating expression is evaluated in the translation environment, the arithmetic precision and range shall be at least as great as if the expression were being evaluated in the execution environment.

C11 adds a footnote explicitly saying that FLT_EVAL_METHOD also applies to the translation environment, and C23 adds DEC_EVAL_METHOD to the footnote, but otherwise the text remains the same in all versions of C.

@vinc17fr
Copy link

vinc17fr commented Apr 17, 2024

When compiled on an x86 system with -m32 -mno-sse, the correct result should be that the two lines both output 2.22045e-16, which icc is able to successfully do. However clang and gcc both report 0 for the first line and 2.22045e-16 for the second: https://godbolt.org/z/4xGoaaoKP.

For GCC, you need an option either like -std=c17 or -fexcess-precision=standard to tell it to conform to the ISO C standard. For instance, with -std=c17, I get 2.22045e-16 on both lines, which is correct.

That said, I would regard the GCC behavior without -std=c17 or -fexcess-precision=standard as a bug (similar to the one for constants).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c99 clang:frontend Language frontend issues, e.g. anything involving "Sema" floating-point Floating-point math
Projects
None yet
Development

No branches or pull requests

3 participants