From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 9410E3858D29; Sun, 21 Mar 2021 12:28:17 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9410E3858D29 From: "rafal at bursig dot org" To: gcc-bugs@gcc.gnu.org Subject: [Bug c/99693] -O2 not move 'if' checks on const data outside the loops Date: Sun, 21 Mar 2021 12:28:17 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c X-Bugzilla-Version: 10.2.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: rafal at bursig dot org X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 21 Mar 2021 12:28:17 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D99693 --- 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 topi= c: 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 *dat= a" 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 =3D 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=20 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 ha= ve 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=