public inbox for gcc-bugs@sourceware.org help / color / mirror / Atom feed
* [Bug c/99693] New: -O2 not move 'if' checks on const data outside the loops @ 2021-03-21 12:07 rafal at bursig dot org 2021-03-21 12:28 ` [Bug c/99693] " rafal at bursig dot org ` (4 more replies) 0 siblings, 5 replies; 6+ messages in thread From: rafal at bursig dot org @ 2021-03-21 12:07 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99693 Bug ID: 99693 Summary: -O2 not move 'if' checks on const data outside the loops Product: gcc Version: 10.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: rafal at bursig dot org Target Milestone: --- -g -o /tmp/compiler-explorer-compiler2021221-5538-b8yy15.yzw9n/output.s -masm=intel -S -fdiagnostics-color=always -O2 /tmp/compiler-explorer-compiler2021221-5538-b8yy15.yzw9n/example.c ^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug c/99693] -O2 not move 'if' checks on const data outside the loops 2021-03-21 12:07 [Bug c/99693] New: -O2 not move 'if' checks on const data outside the loops rafal at bursig dot org @ 2021-03-21 12:28 ` rafal at bursig dot org 2021-03-21 16:41 ` pinskia at gcc dot gnu.org ` (3 subsequent siblings) 4 siblings, 0 replies; 6+ messages in thread From: rafal at bursig dot org @ 2021-03-21 12:28 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99693 --- Comment #1 from rafal at bursig dot org --- I'm not saying that this is a regression because I see proper results on -O3 level but IMHO such results should be available in -O2 level... but to topic: I have such code: typedef struct Update { int m_update; //... } Update; extern void antagonizer( Update * ); void antagonize(Update *data, unsigned int n) { while(--n) { if (data->m_update) { antagonizer( data ); } } } then -O2 level give me such asm: antagonize: sub esi, 1 je .L10 push rbp mov rbp, rdi push rbx mov ebx, esi sub rsp, 8 jmp .L4 .L3: sub ebx, 1 je .L14 .L4: mov eax, DWORD PTR [rbp+0] test eax, eax je .L3 mov rdi, rbp call antagonizer sub ebx, 1 jne .L4 .L14: add rsp, 8 pop rbx pop rbp ret .L10: ret Which is OK because the "antagonizer( data );" call can change "Update *data" struct and the "if (data->m_update)" can't be moved outside loop. But when If I create local copy of "data->m_update" then this check could be moved outside loop without problem. But below code: typedef struct Update { int m_update; //... } Update; extern void antagonizer( Update * ); void antagonize(Update *data, unsigned int n) { const int _update = data->m_update; while(--n) { if (_update) { antagonizer( data ); } } } Do not move "if (_update)" outside the loop and asm looks like: antagonize: push r12 push rbp push rbx mov ebp, DWORD PTR [rdi] sub esi, 1 je .L1 mov r12, rdi mov ebx, esi jmp .L4 .L3: sub ebx, 1 je .L1 .L4: test ebp, ebp // the check je .L3 // is still in loop mov rdi, r12 call antagonizer sub ebx, 1 jne .L4 .L1: pop rbx pop rbp pop r12 ret When I build this code with -O3 level then the check is moved out the loop properly, but I got several others effects which I don't know if it will have proper impact in my application (I will prefer stay with -O2). The asm for -O3 level: antagonize: mov eax, DWORD PTR [rdi] sub esi, 1 je .L12 push rbp mov rbp, rdi push rbx mov ebx, esi sub rsp, 8 test eax, eax jne .L3 .L1: add rsp, 8 pop rbx pop rbp ret .L3: mov rdi, rbp call antagonizer sub ebx, 1 je .L1 mov rdi, rbp call antagonizer sub ebx, 1 jne .L3 jmp .L1 .L12: ret ^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug c/99693] -O2 not move 'if' checks on const data outside the loops 2021-03-21 12:07 [Bug c/99693] New: -O2 not move 'if' checks on const data outside the loops rafal at bursig dot org 2021-03-21 12:28 ` [Bug c/99693] " rafal at bursig dot org @ 2021-03-21 16:41 ` pinskia at gcc dot gnu.org 2021-03-22 9:04 ` rguenth at gcc dot gnu.org ` (2 subsequent siblings) 4 siblings, 0 replies; 6+ messages in thread From: pinskia at gcc dot gnu.org @ 2021-03-21 16:41 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99693 --- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> --- Loop unswitching is correctly only turned on at -O3+. So you want to move it to -O2. Note loop unswitching can cause performance problems due to increase of usage of the icache and such. ^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug c/99693] -O2 not move 'if' checks on const data outside the loops 2021-03-21 12:07 [Bug c/99693] New: -O2 not move 'if' checks on const data outside the loops rafal at bursig dot org 2021-03-21 12:28 ` [Bug c/99693] " rafal at bursig dot org 2021-03-21 16:41 ` pinskia at gcc dot gnu.org @ 2021-03-22 9:04 ` rguenth at gcc dot gnu.org 2021-03-22 9:23 ` rafal at bursig dot org 2021-03-22 9:43 ` rafal at bursig dot org 4 siblings, 0 replies; 6+ messages in thread From: rguenth at gcc dot gnu.org @ 2021-03-22 9:04 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99693 Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Resolution|--- |WONTFIX Status|UNCONFIRMED |RESOLVED --- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- Yes, if you want to stick to -O2 use -funswitch-loops. ^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug c/99693] -O2 not move 'if' checks on const data outside the loops 2021-03-21 12:07 [Bug c/99693] New: -O2 not move 'if' checks on const data outside the loops rafal at bursig dot org ` (2 preceding siblings ...) 2021-03-22 9:04 ` rguenth at gcc dot gnu.org @ 2021-03-22 9:23 ` rafal at bursig dot org 2021-03-22 9:43 ` rafal at bursig dot org 4 siblings, 0 replies; 6+ messages in thread From: rafal at bursig dot org @ 2021-03-22 9:23 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99693 --- Comment #4 from rafal at bursig dot org --- but using -O2 -funswitch-loops will bring me those problems why this flag is not in default -O2. Which is not a solution. Maybe -O2 may have weaken version of this optimization and will work only if one of if brock is empty. And -O3 will have full version. Example: form: for(...) { if (local_value) { logic; } } To: if (local_value) for(...) { logic; } I know that such code could be fixed by developer but gcc don't generate any diagnostic message about such constructions and for a large project it's difficult to find all of such places ^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug c/99693] -O2 not move 'if' checks on const data outside the loops 2021-03-21 12:07 [Bug c/99693] New: -O2 not move 'if' checks on const data outside the loops rafal at bursig dot org ` (3 preceding siblings ...) 2021-03-22 9:23 ` rafal at bursig dot org @ 2021-03-22 9:43 ` rafal at bursig dot org 4 siblings, 0 replies; 6+ messages in thread From: rafal at bursig dot org @ 2021-03-22 9:43 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99693 --- Comment #5 from rafal at bursig dot org --- Additional when I use c++ variant of this code and throw exception in else then in -O2 level the 'if' is removed outside loop: typedef struct Update { int m_update; //... } Update; extern void antagonizer( Update * ); void antagonize(Update *data, unsigned int n) { int _update = data->m_update; while(--n) { if (_update) { antagonizer( data ); } else throw std::runtime_error("error"); } } The asm looks like: .LC0: .string "error" antagonize(Update*, unsigned int): mov eax, DWORD PTR [rdi] sub esi, 1 je .L12 push r12 push rbp mov rbp, rdi push rbx mov ebx, esi test eax, eax je .L3 .L4: mov rdi, rbp call antagonizer(Update*) sub ebx, 1 jne .L4 pop rbx pop rbp pop r12 ret .L12: ret antagonize(Update*, unsigned int) [clone .cold]: .L3: mov edi, 16 call __cxa_allocate_exception mov esi, OFFSET FLAT:.LC0 mov rdi, rax mov rbp, rax call std::runtime_error::runtime_error(char const*) [complete object constructor] mov edx, OFFSET FLAT:_ZNSt13runtime_errorD1Ev mov esi, OFFSET FLAT:_ZTISt13runtime_error mov rdi, rbp call __cxa_throw mov r12, rax mov rdi, rbp call __cxa_free_exception mov rdi, r12 call _Unwind_Resume when I comment the "else throw ..." then the if check return int loop ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2021-03-22 9:43 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-03-21 12:07 [Bug c/99693] New: -O2 not move 'if' checks on const data outside the loops rafal at bursig dot org 2021-03-21 12:28 ` [Bug c/99693] " rafal at bursig dot org 2021-03-21 16:41 ` pinskia at gcc dot gnu.org 2021-03-22 9:04 ` rguenth at gcc dot gnu.org 2021-03-22 9:23 ` rafal at bursig dot org 2021-03-22 9:43 ` rafal at bursig dot org
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).