#pragma STDC CX_LIMITED_RANGE off is currently unimplemented, and generates the warning: warning: ignoring #pragma STDC CX_LIMITED_RANGE
We know. I'm not sure how much use there is opening PRs for major points listed as Missing at <http://gcc.gnu.org/c99status.html> unless there are particular subtle points which might be missed in implementation which would be better noted in a PR. Stephen Moshier started a C99 pragma implementation some time ago. I have his code (version of June 2001, not a complete implementation, only does anything with FENV_ACCESS) and at least the testcases might be useful; I'll attach the files to this bug as we may as well use the bug now it's open.
Created attachment 8543 [details] Stephen Moshier's patch from 2001.
Created attachment 8544 [details] Stephen Moshier's testcases from 2001.
I opened the PR so I would have a tangible place to point to in a FIXME in some code, saying "when this bug is fixed, uncomment this." Perhaps though, for things of this sort, it would be better to point to the status page. However, one can add oneself to the CC list for a bug much easier than he can add himself to the "CC list" for a webpage.
*** Bug 29186 has been marked as a duplicate of this bug. ***
*** Bug 39036 has been marked as a duplicate of this bug. ***
For the STDC FENV_ACCESS pragma specifically, there is PR34678. For the STDC FP_CONTRACT pragma, there is PR37845, which was fixed by r204460, though things could be improved in the future as the pragma is actually ignored: it's just that the default is now OFF in standard modes to be C99/C11 conforming. In the non-standard modes, one now misses the warning: PR68499.
Concerning the STDC FP_CONTRACT pragma, implementing it would not be sufficient. GCC would also need to restrict how it does contraction, as it currently does not contract only expressions, but also sequences of expressions, which is invalid. Example: double foo (double a, double b, double c) { double p = a * b; return p + c; } Since a * b and p + c are separate expressions, contraction to FMA must not be done according to the C standard. But when contraction is allowed, GCC generates a FMA on my x86_64 processor: .cfi_startproc vfmadd132sd %xmm1, %xmm2, %xmm0 ret .cfi_endproc
Note fixin(In reply to Vincent Lefèvre from comment #8) > Concerning the STDC FP_CONTRACT pragma, implementing it would not be > sufficient. GCC would also need to restrict how it does contraction, as it > currently does not contract only expressions, but also sequences of > expressions, which is invalid. Example: > > double foo (double a, double b, double c) > { > double p = a * b; > return p + c; > } > > Since a * b and p + c are separate expressions, contraction to FMA must not > be done according to the C standard. But when contraction is allowed, GCC > generates a FMA on my x86_64 processor: > > .cfi_startproc > vfmadd132sd %xmm1, %xmm2, %xmm0 > ret > .cfi_endproc Note fixing that is as easy as wrapping FP expressions in PAREN_EXPR to denote which ones are separate. PAREN_EXPRs also serve as association barriers and the FE needs to decide what FP optimization flag elides them where exactly (the middle-end leaves them in place even with -ffast-math).
On Fri, 21 Feb 2020, vincent-gcc at vinc17 dot net wrote: > Concerning the STDC FP_CONTRACT pragma, implementing it would not be > sufficient. GCC would also need to restrict how it does contraction, as it > currently does not contract only expressions, but also sequences of > expressions, which is invalid. Example: Note that -ffp-contract=on is currently equivalent to -ffp-contract=off for this reason. It's only -ffp-contract=fast that contracts outside expressions (and C standards conformance modes disable contraction).
I have idea on how to fix the FENV_ACCESS issue (for gimple), basically you add an extra virtual use op for float gimples and virtual define for functions and inline-asm. Now I am not going to implement this but I want to record it somewhere.
As far as I understand, support of #pragma STDC xxx is required by the C standard for hosted implementation. If so, then it is worth reaching conformance to increase the priority of this issue. It is logical for the end users to expect the support of #pragma STDC xxx. Now they see: t888.c:3: warning: ignoring ‘#pragma STDC FP_CONTRACT’ [-Wunknown-pragmas] t888.c:4: warning: ignoring ‘#pragma STDC FENV_ACCESS’ [-Wunknown-pragmas] t888.c:5: warning: ignoring ‘#pragma STDC CX_LIMITED_RANGE’ [-Wunknown-pragmas] Invoked with: gcc t888.c -c -std=c11 -Wall.
If the default state of these pragmas (at least with options like -std=c11) is respectively "off", "on", "off", then changing the pragma state can safely be ignored by the implementation, as implementations are not obliged to optimize as allowed by the new pragma state. Thus, in such a case, the warnings are useless.
To: Vincent Lefèvre Re: the warnings are useless. The "warning: ignoring '#pragma STDC FENV_ACCESS' [-Wunknown-pragmas]" probably needs to be generated by default (i.e. not with -Wall) because now gcc silently miscompiles the following (though unusual) code: /* t0.c */ #include <stdio.h> #include <fenv.h> #include <float.h> #pragma STDC FENV_ACCESS ON int main( void ) { volatile double d1 = DBL_MAX; volatile double d2 = DBL_MAX; #ifdef __STDC__ printf("__STDC__ %d\n", __STDC__); #endif #ifdef __STDC_VERSION__ printf("__STDC_VERSION__ %ld\n", __STDC_VERSION__); #endif #ifdef __STDC_IEC_559__ printf("__STDC_IEC_559__ %d\n", __STDC_IEC_559__); #endif if (feclearexcept( FE_ALL_EXCEPT ) != 0) { printf("error: feclearexcept( FE_ALL_EXCEPT ) failed\n"); return 1; } ( void )( d1 * d2 ); if (fetestexcept( FE_OVERFLOW ) == 0) { printf("error: no FE_OVERFLOW is raised\n"); return 2; } return 0; } Invocation: gcc t0.c -std=c11 -pedantic -lm <nothing> Execution: ./a.out Expected output: __STDC__ 1 __STDC_VERSION__ 201710 __STDC_IEC_559__ 1 Actual output: __STDC__ 1 __STDC_VERSION__ 201710 __STDC_IEC_559__ 1 error: no FE_OVERFLOW is raised
(In reply to Pavel M from comment #14) > The "warning: ignoring '#pragma STDC FENV_ACCESS' [-Wunknown-pragmas]" > probably needs to be generated by default Getting the warning on "#pragma STDC FENV_ACCESS OFF" is useless. The issue comes from the fact that the FENV_ACCESS is OFF by default and you want to set it to ON; there should be a warning in this case, but only in this case. Concerning the other pragmas, this also depends on their default state. For instance, since commit 6dbe09581a1349498f6b4546f68cb9fd3205e120[*], the STDC FP_CONTRACT pragma is set to OFF by default when a standard mode is provided (e.g. -std=c17), so that the warning on this pragma is not needed in this case (whether the user sets it to ON or OFF). [*] https://gcc.gnu.org/git/?p=gcc.git&a=commit;h=6dbe09581a1349498f6b4546f68cb9fd3205e120
Note: The #pragma STDC FENV_ACCESS is unknown and ignored (leading to FP issues), however, the __STDC_IEC_559__ is defined to 1. Confused.
(In reply to Pavel M from comment #16) > Note: The #pragma STDC FENV_ACCESS is unknown and ignored (leading to FP > issues), however, the __STDC_IEC_559__ is defined to 1. Confused. Yes, and IMHO, with __STDC_IEC_559__ defined to 1, this is a much more severe issue. This PR should not be regarded as an enhancement, but as a real bug (this would be an enhancement only if when __STDC_IEC_559__ is defined to 1, there would be a lack of optimization).
(In reply to Vincent Lefèvre from comment #17) > (In reply to Pavel M from comment #16) > > Note: The #pragma STDC FENV_ACCESS is unknown and ignored (leading to FP > > issues), however, the __STDC_IEC_559__ is defined to 1. Confused. > > Yes, and IMHO, with __STDC_IEC_559__ defined to 1, this is a much more > severe issue. This PR should not be regarded as an enhancement, but as a > real bug OK, I put the importance back to "normal"
Regardless of the wider issue, it would be nice to get STDC CX_LIMITED_RANGE implemented. Is there something specific blocking this?