[Bug rtl-optimization/111101] New: -finline-small-functions may invert FP arguments breaking FP bit accuracy in case of NaNs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=01 Bug ID: 01 Summary: -finline-small-functions may invert FP arguments breaking FP bit accuracy in case of NaNs Product: gcc Version: 11.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: pavel.morozkin at gmail dot com Target Milestone: --- Notes: 1. This may not be a bug. 2. This may be a duplicate. 3. I don't have MRE. Brief: -finline-small-functions may invert FP arguments breaking FP bit accuracy in case of NaNs Demo: $ gcc t1.c -O1 -std=c11 && ./a r nan 7fe5ed65 r_ref nan 7fe5ed65 $ gcc t1.c -O1 -std=c11 -finline-small-functions && ./a r -nan fffe r_ref nan 7fe5ed65 Description: In my code I add two FP values (represented in "raw hex"): 0x7fa5ed65 (sNaN) with 0xfffe (qNaN). x86_64 instruction addss returns 0x7fe5ed65 (sNaN). However, under -finline-small-functions gcc, I guess, rewrites A+B to B+A, resulting in 0xfffe (qNaN), which breaks FP bit accuracy. I examined generated assembly code: -O1: add(x, y) x => ecx => ebp => xmm0 y => edx => edi => xmm1 addss xmm1, xmm0 (at syntax) -O1 -finline-small-functions: add(x, y) x => ecx => esi => xmm1 y => edx => ebx => xmm0 addss xmm1, xmm0 (at syntax) Here we see that in case of -finline-small-functions x and y are inverted. Notes: 1. Some software may rely on FP bit accuracy in case of NaNs (NaN boxing, etc.). 2. I'm not sure which "Component:" to select: rtl-optimization or tree-optimization.
[Bug target/110105] ARM GCC: underoptimization: expected vfma.f16, actual vcvtb-vfma.f32-vcvtb
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110105 --- Comment #4 from Pavel M --- To: rsand...@gcc.gnu.org Thanks! I confused __fp16 with _Float16. However, if __fp16 is only a “storage type”, then why this code: __fp16 mul(__fp16 x, __fp16 y) { return x * y; } compiled with -O3 -mfpu=fp-armv8 -march=armv8.2-a+fp16 leads to this code: mul: vmul.f16s0, s0, s1 bx lr Here we see vmul.f16 instead of half->float->vmul.f32->float->half. As a user, I expect half->float->vmul.f32->float->half (because __fp16 is only a “storage type”). Where is the conversions and mul.f32? P.S. If optimizer does this, then as I remember, half->float->op->float->half does not always produce the same result as half->op->half. The difference in result may be +/-1 (last) bit. Any comments?
[Bug target/110105] ARM GCC: underoptimization: expected vfma.f16, actual vcvtb-vfma.f32-vcvtb
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110105 --- Comment #1 from Pavel M --- Demo: https://godbolt.org/z/9s7eb9b1K.
[Bug target/110105] New: ARM GCC: underoptimization: expected vfma.f16, actual vcvtb-vfma.f32-vcvtb
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110105 Bug ID: 110105 Summary: ARM GCC: underoptimization: expected vfma.f16, actual vcvtb-vfma.f32-vcvtb Product: gcc Version: 13.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: pavel.morozkin at gmail dot com Target Milestone: --- This code: __fp16 mul(__fp16 x, __fp16 y, __fp16 z) { return x * y + z; } compiled as: gcc -O3 -mfpu=fp-armv8 -march=armv8.2-a+fp16 produces the following assembler code: mul: vcvtb.f32.f16 s0, s0 vcvtb.f32.f16 s1, s1 vcvtb.f32.f16 s2, s2 vfma.f32s2, s0, s1 vcvtb.f16.f32 s0, s2 bx lr Here we see vcvtb-vfma.f32-vcvtb while a single vfma.f16 is expected.
[Bug c/51437] GCC should warn on the use of reserved identifier/macro names
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51437 --- Comment #18 from Pavel M --- (In reply to Jonathan Wakely from comment #17) > (In reply to Josh Triplett from comment #5) > > I'd like to see this as well. While issuing such a warning by default would > > cause numerous warnings with existing code, having it as an opt-in > > -Wreserved-identifiers would help greatly. > > Clang does this now, with -Wreserved-identifier (N.B. singular, not > "identifiers") Note that in Clang -Wreserved-identifier is not part of -Wall nor -Wextra. The reason is "chattiness of the diagnostic in practice". Full answer: https://github.com/llvm/llvm-project/issues/57913#issuecomment-1255493025.
[Bug c/106797] Improvement: diagnose undefined behavior: not all declarations that refer to the same object or function have compatible type
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106797 --- Comment #2 from Pavel M --- Observation: if "static" is removed, then GCC generates: : In function 'f2': :10:18: error: conflicting types for 'x'; have 'int (*)[5]' 10 | extern int (*x)[5]; | ^ :5:18: note: previous declaration of 'x' with type 'int (*)[3]' 5 | extern int (*x)[3]; |
[Bug c/106797] New: Improvement: diagnose undefined behavior: not all declarations that refer to the same object or function have compatible type
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106797 Bug ID: 106797 Summary: Improvement: diagnose undefined behavior: not all declarations that refer to the same object or function have compatible type Product: gcc Version: 12.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: pavel.morozkin at gmail dot com Target Milestone: --- This code: static int (*x)[]; void f1(void) { extern int (*x)[3]; } void f2(void) { extern int (*x)[5]; } compiled with -std=c11 -pedantic -Wall -Wextra -Wno-unused-variable triggers UB (see below) and leads to no diagnostics. It is proposed to produce this (or similar) diagnostics: "not all declarations that refer to the same object x have compatible type" OR "declarations that refer to the same object x have types 'int (*)[5]' and 'int (*)[3]' which are not compatible". Relevant quote from C11, 6.2.7 Compatible type and composite type, 2: > All declarations that refer to the same object or function shall have > compatible type; otherwise, the behavior is undefined. In the program above types 'int (*)[5]' and 'int (*)[3]' are not compatible. It is useful to diagnose that.
[Bug c/51437] GCC should warn on the use of reserved identifier/macro names
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51437 Pavel M changed: What|Removed |Added CC||pavel.morozkin at gmail dot com --- Comment #16 from Pavel M --- To remind: macros that begin with an underscore, followed by a lowercase letter are not reserved.
[Bug tree-optimization/106138] Inefficient code generation: logical AND of disjoint booleans from equal and bitwise AND not optimized to constant false
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106138 --- Comment #7 from Pavel M --- May be useful: https://devblogs.microsoft.com/cppblog/new-code-optimizer. Search for "Bit Estimator" section containing "Folding comparisons and branches".
[Bug c/106138] New: Inefficient code generation for cases when results can be deduced at compile time
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106138 Bug ID: 106138 Summary: Inefficient code generation for cases when results can be deduced at compile time Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: pavel.morozkin at gmail dot com Target Milestone: --- _Bool f(char x) { _Bool b1 = x == 4; _Bool b2 = x & 0x3; return b1 && b2; } Invocation: gcc -O3 Actual generated code: f: testdil, 3 setne al cmp dil, 4 setedl and eax, edx ret Expected generated code: f: xor eax, eax ret The Summary needs to be adjusted perhaps.
[Bug c/3885] Incorrect "invalid suffix on integer constant" error
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3885 Pavel M changed: What|Removed |Added CC||pavel.morozkin at gmail dot com --- Comment #15 from Pavel M --- Please add to "Duplicates" list: - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=33547 - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=45184
[Bug c/105488] Function definition is not generated OR function is not inlined
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105488 --- Comment #3 from Pavel M --- To: Andrew Pinski Indeed, per C11: > It is unspecified whether a call to the function uses the inline definition > or the external definition. Thanks!
[Bug c/105488] New: Function definition is not generated OR function is not inlined
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105488 Bug ID: 105488 Summary: Function definition is not generated OR function is not inlined Product: gcc Version: 11.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: pavel.morozkin at gmail dot com Target Milestone: --- Note: probably this is a duplicate. This code: inline void f(void) { } int main(void) { f(); } leads to this code: .file "t609.c" .text .def__main; .scl2; .type 32; .endef .globl main .defmain; .scl2; .type 32; .endef .seh_proc main main: pushq %rbp .seh_pushreg%rbp movq%rsp, %rbp .seh_setframe %rbp, 0 subq$32, %rsp .seh_stackalloc 32 .seh_endprologue call__main callf movl$0, %eax addq$32, %rsp popq%rbp ret .seh_endproc .ident "GCC: (GNU) 11.1.0" .deff; .scl2; .type 32; .endef Here we see that "call f" is present, while "f:" is absent. As a result: $ gcc t609.c ld: /tmp/cc8z1GjU.o:t609.c:(.text+0xe): undefined reference to `f' collect2: error: ld returned 1 exit status I think that: - either function definition is not generated, - either function is not inlined.
[Bug preprocessor/105362] Improvement: diagnose undefined behavior in preprocessing directives
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105362 --- Comment #2 from Pavel M --- I do believe that evaluation of constant expressions in conditional inclusion is done according to the rules of constant expressions ("except that ...", see C11, 6.10.1/1). Hence, I expect the same diagnostics in all the places where constant expressions may be used.
[Bug c/105362] New: Improvement: diagnose undefined behavior in preprocessing directives
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105362 Bug ID: 105362 Summary: Improvement: diagnose undefined behavior in preprocessing directives Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: pavel.morozkin at gmail dot com Target Milestone: --- #if 1 << -1 #endif $ gcc -std=c11 -pedantic -Wall -Wextra -O3 -c Expected diagnostics: warning: left shift count is negative [-Wshift-count-negative] Actual diagnostics:
[Bug preprocessor/105207] Translation phase 2: splicing physical source lines to form logical source lines may not work
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105207 --- Comment #4 from Pavel M --- To: Andrew Pinski At the 1st glance I expected to see that -E produces the output after splicing is done (i.e. xxx #error). However, the "preprocessing only" is out of scope of the C11. As stackoverflow.com user rici said: "Serializing the stream of tokens back into a character string, which is what gcc -E does, is not required or even mentioned by the standard, and does not form part of the translation process specified by the standard". Hence, per C11 the 105207 is "not a problem". However, per quality-of-implementation matter maybe it will be useful to make -E produce the output after splicing is done (i.e. xxx #error). What do you think?
[Bug c/105207] Translation phase 2: splicing physical source lines to form logical source lines may not work
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105207 Pavel M changed: What|Removed |Added Summary|C preprocessor: splicing|Translation phase 2: |physical source lines to|splicing physical source |form logical source lines |lines to form logical |may not work|source lines may not work --- Comment #2 from Pavel M --- Actually the issue is not related to the preprocessor. It is relayed to the translation phase 2. Please
[Bug c/105207] C preprocessor: splicing physical source lines to form logical source lines may not work
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105207 --- Comment #1 from Pavel M --- The same behavior with: xxx \ error Expected: xxx error Actual: xxx error
[Bug c/105207] New: C preprocessor: splicing physical source lines to form logical source lines may not work
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105207 Bug ID: 105207 Summary: C preprocessor: splicing physical source lines to form logical source lines may not work Product: gcc Version: 11.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: pavel.morozkin at gmail dot com Target Milestone: --- Sample code: xxx \ #error Invocation: $ gcc t6.c -E Actual output: xxx #error Expected output: xxx #error
[Bug c/104147] New: C preprocessor may remove the standard required whitespace between the preprocessing tokens
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104147 Bug ID: 104147 Summary: C preprocessor may remove the standard required whitespace between the preprocessing tokens Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: pavel.morozkin at gmail dot com Target Milestone: --- Sample code: #define X(x,y) x y #define STR_(x) #x #define STR(x) STR_(x) STR(X(Y,Y)) Invocations: $ gcc t222.c -std=c11 -pedantic -Wall -Wextra -E -P "Y Y" $ gcc t222.c -std=c11 -pedantic -Wall -Wextra -E -P -D"Y()" "YY" Also 1: Somehow gcc takes into account the whitespace between `,` and `Y`: $ gcc t222.c -std=c11 -pedantic -Wall -Wextra -E -P -D"Y()" -D"Z=STR(X(Y,Y))" "YY" $ gcc t222.c -std=c11 -pedantic -Wall -Wextra -E -P -D"Y()" -D"Z=STR(X(Y, Y))" "Y Y" Also 2: This: STR(X(Y, Y)) leads to: $ gcc t222.c -std=c11 -pedantic -Wall -Wextra -E -P -D"Y()" "Y Y" However, this: STR(X(Y ,Y)) leads to: $ gcc t222.c -std=c11 -pedantic -Wall -Wextra -E -P -D"Y()" "YY" The whitespace is required by the standard.
[Bug c++/104095] New: g++ diagnosis may use non-standard terminology: "constant" instead of "literal", "integer" instead of "integral"
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104095 Bug ID: 104095 Summary: g++ diagnosis may use non-standard terminology: "constant" instead of "literal", "integer" instead of "integral" Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: pavel.morozkin at gmail dot com Target Milestone: --- $ g++ t589.cpp -std=c++17 -pedantic -Wall -Wextra -c t589.cpp:24:22: error: overflow in constant expression [-fpermissive] 24 | enum { y = (int)(1e10) }; | ^ t589.cpp:24:22: error: overflow in constant expression [-fpermissive] t589.cpp:24:22: error: enumerator value for ‘y’ is not an integer constant С++ standard does not have "integer constant". С++ standard has "integral constant". $ g++ t589.cpp -std=c++11 -pedantic -c t589.cpp:25:11: warning: use of C++17 hexadecimal floating constant 25 | float f = 0x0.123p-1f; С++ standard does not have "hexadecimal floating constant". С++ standard has "hexadecimal floating literal". $ g++ t589.cpp -std=c++17 -pedantic -c t589.cpp:25:1: warning: floating constant truncated to zero [-Woverflow] 25 | float f = 0x0.12p-1000f; С++ standard does not have "floating constant". С++ standard has "floating literal".
[Bug c/83584] "ISO C forbids conversion of object pointer to function pointer type" -- no, not really
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83584 Pavel M changed: What|Removed |Added CC||pavel.morozkin at gmail dot com --- Comment #21 from Pavel M --- FYI: Rationale for C, Revision 5.10, April-2003: > Even with an explicit cast, it is invalid to convert a function pointer to an > object pointer or a pointer to void, or vice versa.
[Bug tree-optimization/103491] nextafter does not raise "overflow" and "inexact" floating-point exceptions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103491 --- Comment #4 from Pavel M --- To: jos...@codesourcery.com Re: This testcase is incorrect. Indeed. The F.10.8.3 was misunderstood.
[Bug c/103491] New: nextafter does not raise "overflow" and "inexact" floating-point exceptions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103491 Bug ID: 103491 Summary: nextafter does not raise "overflow" and "inexact" floating-point exceptions Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: pavel.morozkin at gmail dot com Target Milestone: --- Sample code (t0.c): #include #include #pragma STDC FENV_ACCESS ON int main(void) { #if __STDC_IEC_559__ == 1 double d = 1.0; d = nextafter(d, INFINITY); return (fetestexcept(FE_INEXACT | FE_INVALID) & (FE_INEXACT | FE_INVALID)) ? 0 : 1; #else return 0; #endif } Invocation: gcc -std=c11 -pedantic -Wall -Wextra -lm Expected a.out exit status: 0 Actual a.out exit status: 1 C11, F.10.8.3 The nextafter functions: > nextafter(x, y) raises the ‘‘overflow’’ and ‘‘inexact’’ floating-point > exceptions for x finite and the function value infinite. Yes, Pragma STDC * (C99 FP) is unimplemented (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=20785). However, __STDC_IEC_559__ is already 1.
[Bug c/20785] Pragma STDC * (C99 FP) unimplemented
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=20785 --- Comment #16 from Pavel M --- Note: The #pragma STDC FENV_ACCESS is unknown and ignored (leading to FP issues), however, the __STDC_IEC_559__ is defined to 1. Confused.
[Bug c/103193] New: gcc for x86_64: wrong code generation: ucomiss instead of comiss
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103193 Bug ID: 103193 Summary: gcc for x86_64: wrong code generation: ucomiss instead of comiss Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: pavel.morozkin at gmail dot com Target Milestone: --- This code: #pragma STDC FENV_ACCESS ON float f; _Bool b; f = NAN; b = f >= f; // ucomiss (wrong), comiss (correct) results in: ucomiss xmm0, DWORD PTR [rbp-4] Per IEEE 754-2008 the ">=" is compareSignalingGreaterEqual, which can be implemented using comiss. Notes: 1. Yes, the #pragma STDC FENV_ACCESS ON is not yet supported. Just wanted to point out that under #pragma STDC FENV_ACCESS ON gcc needs to generate comiss (not ucomiss). 2. Adding volatile to float f; results in generation of comiss (expected).
[Bug c/20785] Pragma STDC * (C99 FP) unimplemented
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=20785 --- Comment #14 from Pavel M --- 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 #include #include #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 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
[Bug c/20785] Pragma STDC * (C99 FP) unimplemented
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=20785 Pavel M changed: What|Removed |Added CC||pavel.morozkin at gmail dot com --- Comment #12 from Pavel M --- 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.
[Bug c/102821] Tentative definition of variable with internal linkage has incomplete non-array type: missing diagnostics
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102821 --- Comment #2 from Pavel M --- Addition to "Notes" above. 3. C11, 5.1.1.3 Diagnostics, 1: > A conforming implementation shall produce at least one diagnostic message > (identified in an implementation-defined manner) if a preprocessing > translation unit or translation unit contains a violation of any syntax rule > or constraint, even if the behavior is also explicitly specified as undefined > or implementation-defined.
[Bug c/102821] New: Tentative definition of variable with internal linkage has incomplete non-array type: missing diagnostics
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102821 Bug ID: 102821 Summary: Tentative definition of variable with internal linkage has incomplete non-array type: missing diagnostics Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: pavel.morozkin at gmail dot com Target Milestone: --- Sample code (t940.c): static struct s foo; static struct s {int a;} foo; Invocation: $ gcc t940.c -c -std=c11 -pedantic -Wall -Wextra -Wno-unused-variable Expected diagnostics: t940.c:1:17: warning: tentative definition of variable with internal linkage has incomplete non-array type 'struct s' [-Wtentative-definition-incomplete-type] Actual diagnostics: Notes: 1. C11, 6.9.2 External object definitions, 3: > If the declaration of an identifier for an object is a tentative definition > and has internal linkage, the declared type shall not be an incomplete type. 2. C11, 4. Conformance, 1: > In this International Standard, ‘‘shall’’ is to be interpreted as a > requirement on an implementation or on a program; conversely, ‘‘shall not’’ > is to be interpreted as a prohibition.
[Bug middle-end/101063] New: #pragma STDC FENV_ACCESS ON: wrong code generation: instructions leading to side effects may not be generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101063 Bug ID: 101063 Summary: #pragma STDC FENV_ACCESS ON: wrong code generation: instructions leading to side effects may not be generated Product: gcc Version: 11.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: pavel.morozkin at gmail dot com Target Milestone: --- Bug-triggering code (t0.c): #include #include #include #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 feclearexcept( FE_ALL_EXCEPT ); ( void )( d1 * d2 ); if ( fetestexcept( FE_OVERFLOW ) ) { return 0; } printf("error: no FE_OVERFLOW is raised\n"); return 1; } Invocation: gcc t0.c -lm && ./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 Note 1: Under -Wall gcc generates warning: :5: warning: ignoring '#pragma STDC FENV_ACCESS' [-Wunknown-pragmas] 5 | #pragma STDC FENV_ACCESS ON Note 2: Comparison with clang: https://godbolt.org/z/6GnqTYvaa. Brief difference: gcc: callfeclearexcept movsd xmm0, QWORD PTR [rbp-8] movsd xmm0, QWORD PTR [rbp-16] mov edi, 8 callfetestexcept clang: callfeclearexcept movsd xmm0, qword ptr [rbp - 16] # xmm0 = mem[0],zero movsd xmm1, qword ptr [rbp - 24] # xmm1 = mem[0],zero mulsd xmm0, xmm1 mov edi, 8 callfetestexcept Here we see that gcc does not generate "mulsd", which is a bug, because execution of "mulsd" leads to side effects.