https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108370
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=54245&action=edit 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)) != 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 <bio_release_pages+0xb> 7: a8 02 test $0x2,%al 9: 74 09 je 14 <bio_release_pages+0x14> b: 40 0f b6 f6 movzbl %sil,%esi f: e9 00 00 00 00 jmp 14 <bio_release_pages+0x14> 14: c3 ret 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 <bio_release_pages+0xe> 5: 40 0f b6 f6 movzbl %sil,%esi 9: e9 00 00 00 00 jmp e <bio_release_pages+0xe> e: c3 ret 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 <bio_release_pages+0x14> 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>