[Bug c/106379] New: DCE depends on order
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106379 Bug ID: 106379 Summary: DCE depends on order Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: tmayerl at student dot ethz.ch Target Milestone: --- In some cases, the compiler's ability to eliminate dead code depends on the order of the sub-expressions within the if. GCC detects that the if expression in the following code snippet evaluates to false and thus removes the dead code: #include #include static void __attribute__ ((noinline)) DCEMarker0_() {printf("DCE2.0");} void f(bool c, bool s) { if (((!c == !s) && !(c) && s)) { DCEMarker0_(); } } In the following snippet the expressions are swapped (the semantics stay the same). However, GCC cannot eliminate the dead code anymore: #include #include static void __attribute__ ((noinline)) DCEMarker0_() {printf("DCE2.0");} void f(bool c, bool s) { if ((!s == !c) && s && !(c)) { DCEMarker0_(); } } This can also be seen via the following Compiler Explorer link: https://godbolt.org/z/vTqhc46qY
[Bug c/106380] New: DCE depends on datatype used (bool vs unsigned)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106380 Bug ID: 106380 Summary: DCE depends on datatype used (bool vs unsigned) Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: tmayerl at student dot ethz.ch Target Milestone: --- In some cases, the compiler's ability to eliminate dead code depends on the datatype used (bool vs unsigned). GCC detects that the if expression in the following code snippet evaluates to false and thus removes the dead code: #include #include static void __attribute__ ((noinline)) DCEMarker0_() {printf("DCE2.0");} void f(bool s, bool c) { if (((!s == !c) && c && !(s))) { DCEMarker0_(); } } In the following snippet the datatype is switched to unsigned (the semantics stay the same). However, GCC cannot eliminate the dead code anymore: #include #include static void __attribute__ ((noinline)) DCEMarker0_() {printf("DCE2.0");} void f(unsigned s, unsigned c) { if (((!s == !c) && c && !(s))) { DCEMarker0_(); } } This can also be seen via the following Compiler Explorer link: https://godbolt.org/z/aMcEvEaYa (Might be related to 106379)
[Bug c/106381] New: DCE depends on used programming language (C vs C++)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106381 Bug ID: 106381 Summary: DCE depends on used programming language (C vs C++) Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: tmayerl at student dot ethz.ch Target Milestone: --- In some cases, the compiler's ability to eliminate dead code depends on the used language (C vs C++). GCC detects that the if expression in the following code snippet evaluates to false and thus removes the dead code. The code is compiled as C++ code: #include #include static void __attribute__ ((noinline)) DCEMarker0_() {printf("DCE2.0");} void f(unsigned s, unsigned c) { if (((!s == !c) && c && !(s))) { DCEMarker0_(); } } However, if the same code is compiled as C code, GCC cannot eliminate the dead code anymore. This can also be seen via the following Compiler Explorer link: https://godbolt.org/z/a9ned9Exb (Might be related to 106379 and 106380)
[Bug c/106474] New: DCE depends on how if expressions are nested
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106474 Bug ID: 106474 Summary: DCE depends on how if expressions are nested Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: tmayerl at student dot ethz.ch Target Milestone: --- In some cases, the compiler's ability to eliminate dead code depends on how if expressions are nested. GCC detects that the if expressions in the following code snippet evaluate to false and thus removes the dead code: #include #include static void __attribute__ ((noinline)) DCEMarker0_() {printf("DCE2.0");} void f(bool s, bool c) { if (!c == !s) { if (!c && s) { DCEMarker0_(); } } } In the following snippet the !c term is moved into the outer if expression. However, GCC cannot eliminate the dead code anymore: #include #include static void __attribute__ ((noinline)) DCEMarker0_() {printf("DCE2.0");} void f(bool s, bool c) { if ((!c == !s) && !c) { if (s) { DCEMarker0_(); } } } In the following snippet, only the outer if statement is kept and all terms are moved there. GCC is now able to eliminate the code again: #include #include static void __attribute__ ((noinline)) DCEMarker0_() {printf("DCE2.0");} void f(bool s, bool c) { if (((!c == !s) && !c) && s) { DCEMarker0_(); } } This can also be seen via the following Compiler Explorer link: https://godbolt.org/z/9WPn5cG1W
[Bug tree-optimization/106505] New: DCE depends on whether if or else is used
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106505 Bug ID: 106505 Summary: DCE depends on whether if or else is used Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: tmayerl at student dot ethz.ch Target Milestone: --- In some cases, the compiler's ability to eliminate dead code depends on whether the if expression is left as it is or negated and the body moved to the else block. GCC detects that the if expressions in the following code snippet evaluate to false and thus removes the dead code: #include #include void DCEMarker0_(); void f(bool s, bool c) { if (!c == !s) { if (s && !c) { DCEMarker0_(); } } } In the following snippet, the inner if has been negated and the body has been moved to the else block. However, GCC cannot eliminate the dead code anymore: #include #include void DCEMarker0_(); void f(bool s, bool c) { if (!c == !s) { if (!(s && !c)) {} else { DCEMarker0_(); } } } This can also be seen via the following Compiler Explorer link: https://godbolt.org/z/P4a61nsdq If s and c in the inner if expression are swapped, it is the other way round. Without the else, the compiler cannot eliminate the dead code: #include #include void DCEMarker0_(); void f(bool s, bool c) { if (!c == !s) { if (c && !s) { DCEMarker0_(); } } } However, it suddenly can optimise the code when the if expression is negated and the body is moved to the else: #include #include void DCEMarker0_(); void f(bool s, bool c) { if (!c == !s) { if (!(c && !s)) {} else { DCEMarker0_(); } } } This can also be seen via the following Compiler Explorer link: https://godbolt.org/z/95jo3Gv45 Due to the order issue this might be related to the following bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106379 However, this example only works with C as a source language. With C++, it is fine. Thus, this might be related to the following bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106381 Another example is given below. In this case, only one variable is needed. However, this only works with the datatype unsigned instead of bool. Therefore, it might be related to the following bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106380 Version with dead code eliminated: #include #include void DCEMarker0_(); void f(unsigned s) { if (!s == !!s) { DCEMarker0_(); } } Version with dead code not eliminated: #include #include void DCEMarker0_(); void f(unsigned s) { if (!(!s == !!s)) {} else { DCEMarker0_(); } } This can also be seen via the following Compiler Explorer link: https://godbolt.org/z/zYfoTs3PE
[Bug tree-optimization/106570] New: DCE sometimes fails with depending if statements
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106570 Bug ID: 106570 Summary: DCE sometimes fails with depending if statements Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: tmayerl at student dot ethz.ch Target Milestone: --- Sometimes, DCE fails when multiple if statements are used. For example, GCC detects that the following if statements always evaluate to false and thus removes the dead code: #include #include void DCEMarker0_(); void f(bool s, bool c) { if (!c == !s) { if (s && !c) { DCEMarker0_(); } } } In the next snippet, the if statements are used to set a variable. This variable is then used in the next if statement. However, GCC now fails to detect and eliminate the dead code: #include #include void DCEMarker0_(); void f(bool s, bool c) { int intermediate_result = 0; if (!c == !s) { if (s && !c) { intermediate_result = 1; } } if (((!c == !s) && (s && !c)) || intermediate_result) { DCEMarker0_(); } } This is actually a regression: It works fine until GCC 11.3. This can also be seen via the following Compiler Explorer link: https://godbolt.org/z/n9dKMfqsd