From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 062383858407; Wed, 11 Jan 2023 13:47:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 062383858407 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1673444857; bh=dj+/SE9fOiSMVoiTpdWtKimG1yxTQHcLZhDI8rSDuKM=; h=From:To:Subject:Date:From; b=jEpw15M3rIGotJpnDlIv4ua1glqfDnRnNv3wj/aj0IAF75yTQ41mobbRQ24Dlb7IZ YS/KekbOeMIaEzNBy2jOMV6cSj4sCnmqcKuFlbwM1cEBSKIgFw4eiVvU5n5ZcNrJmA fnKK5hBSipqU21ierLGIFooKA1ixxut5agXOIvBY= From: "dhowells at redhat dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug c/108370] New: gcc doesn't merge bitwise-AND if an explicit comparison against 0 is given Date: Wed, 11 Jan 2023 13:47:36 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c X-Bugzilla-Version: 12.2.1 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: dhowells at redhat dot com 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: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone attachments.created Message-ID: 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 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D108370 Bug ID: 108370 Summary: gcc doesn't merge bitwise-AND if an explicit comparison against 0 is given Product: gcc Version: 12.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: dhowells at redhat dot com Target Milestone: --- Created attachment 54245 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=3D54245&action=3Dedit Demo code If gcc sees a couple of calls to an inline function that does a bitwise-AND= and returns whether the result was zero or non-zero (e.g. a flag check helper),= gcc cannot merge them if the result of the AND is explicitly compared against 0, even if the function's return type is a bool (which would do that anyway). = For example: static inline bool bio_flagged(struct bio *bio, unsigned int bit) { return (bio->bi_flags & (1U << bit)) !=3D 0; } void bio_release_pages(struct bio *bio, bool mark_dirty) { if (bio_flagged(bio, BIO_PAGE_REFFED) || bio_flagged(bio, BIO_PAGE_PINNED)) __bio_release_pages(bio, mark_dirty); } compiles bio_release_pages() to: 0: 66 8b 07 mov (%rdi),%ax 3: a8 01 test $0x1,%al 5: 75 04 jne b 7: a8 02 test $0x2,%al 9: 74 09 je 14 b: 40 0f b6 f6 movzbl %sil,%esi f: e9 00 00 00 00 jmp 14 14: c3 ret=20=20=20=20 but: static inline bool bio_flagged(struct bio *bio, unsigned int bit) { return bio->bi_flags & (1U << bit); } gives: 0: f6 07 03 testb $0x3,(%rdi) 3: 74 09 je e 5: 40 0f b6 f6 movzbl %sil,%esi 9: e9 00 00 00 00 jmp e e: c3 ret=20=20=20=20 Possibly the comparison against 0 could be optimised away. I've attached some demo code that can be compiled with one of: gcc -Os -c gcc-bool-demo.c gcc -Os -c gcc-bool-demo.c -Dfix The gcc I used above is the Fedora 37 system compiler: gcc-12.2.1-4.fc37.x86_64 binutils-2.38-25.fc37.x86_64 but similar results can be seen with the Fedora arm cross-compiler: 0: e1d030b0 ldrh r3, [r0] 4: e3130001 tst r3, #1 8: 1a000001 bne 14 c: e3130002 tst r3, #2 10: 012fff1e bxeq lr 14: eafffffe b 0 <__bio_release_pages> vs 0: e1d030b0 ldrh r3, [r0] 4: e3130003 tst r3, #3 8: 012fff1e bxeq lr c: eafffffe b 0 <__bio_release_pages>=