https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99997

            Bug ID: 99997
           Summary: Missed optimisation with -Os
           Product: gcc
           Version: 10.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 50538
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=50538&action=edit
Test source

Using the Fedora 33 x86_64 compiler:
gcc version 10.2.1 20201125 (Red Hat 10.2.1-9) (GCC) 

Building the following (see also attached file):

typedef _Bool bool;
#define __always_inline inline __attribute__((__always_inline__))
enum { PG_head = 16 };
struct page {
        unsigned long flags;
        unsigned long compound_head;    /* Bit zero is set */
};
static inline bool constant_test_bit(int nr, const void *addr)
{
        const unsigned int *p = (const unsigned int *)addr;
        return ((1UL << (nr & 31)) & (p[nr >> 5])) != 0;
}
static __always_inline bool PageTail(struct page *page)
{
        return page->compound_head & 1;
}
static __always_inline bool PageCompound(struct page *page)
{
        return constant_test_bit(PG_head, &page->flags) || PageTail(page);
}
bool PageTransCompound(struct page *page)
{
        return PageCompound(page);
}

with "gcc -Os" I get the following assembly:

PageTransCompound:
.LFB3:
        .cfi_startproc
        movl    (%rdi), %edx
        movl    $1, %eax
        btl     $16, %edx
        jc      .L2
        movq    8(%rdi), %rax
        andl    $1, %eax
.L2:
        andl    $1, %eax
        ret
        .cfi_endproc

There are two consecutive identical ANDL instructions, one of which is
superfluous.  The compile could eliminate the one that's immediately prior to
the .L2 instruction.

Reply via email to