From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11808 invoked by alias); 12 Dec 2014 22:25:57 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 11794 invoked by uid 48); 12 Dec 2014 22:25:53 -0000 From: "gcc at breakpoint dot cc" To: gcc-bugs@gcc.gnu.org Subject: [Bug rtl-optimization/64294] New: invalid code, zero check gets optimized away Date: Fri, 12 Dec 2014 22:25:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: rtl-optimization X-Bugzilla-Version: 4.9.2 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: gcc at breakpoint dot cc X-Bugzilla-Status: UNCONFIRMED 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: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter attachments.created Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2014-12/txt/msg01508.txt.bz2 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64294 Bug ID: 64294 Summary: invalid code, zero check gets optimized away Product: gcc Version: 4.9.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: gcc at breakpoint dot cc Created attachment 34272 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=34272&action=edit the testcase The testcase is a minimized / cut-out of some code which basically does: if (!backsize) exit(11); while(backsize--) { *ddst=*(ddst+backbytes); ddst++; } gcc somehow assumes that backsize can't get zero which it can. I added an 'asm volatile("labele:");' statement so the check can be easy spotted. At -O2 gcc produces: 0000020a : 20a: 8b 44 24 20 mov 0x20(%esp),%eax 20e: 66 90 xchg %ax,%ax 210: 0f b6 54 0d 00 movzbl 0x0(%ebp,%ecx,1),%edx 215: 83 c5 01 add $0x1,%ebp 218: 88 55 ff mov %dl,-0x1(%ebp) 21b: 39 e8 cmp %ebp,%eax 21d: 75 f1 jne 210 So it copies the first byte before checking for equal/zero. With -O1 instead: 0000028a : 28a: 85 f6 test %esi,%esi 28c: 75 0a jne 298 28e: 83 ec 0c sub $0xc,%esp 291: 6a 0b push $0xb 293: e8 fc ff ff ff call 294 294: R_386_PC32 exit 298: 8b 5c 24 10 mov 0x10(%esp),%ebx 29c: 8b 54 24 2c mov 0x2c(%esp),%edx 2a0: 0f b6 0c 13 movzbl (%ebx,%edx,1),%ecx 2a4: 88 0b mov %cl,(%ebx) 2a6: 83 c3 01 add $0x1,%ebx 2a9: 39 d8 cmp %ebx,%eax 2ab: 75 f3 jne 2a0 There is the 0 check withint the first two opcodes including the exit(0) statement.