https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99998
Bug ID: 99998
Summary: Unnecessary jump instruction
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 50539
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=50539&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 smp_rmb() __asm__ __volatile__("": : :"memory")
#define unlikely(x) __builtin_expect(!!(x), 0)
enum { PG_uptodate = 2 };
struct page {
unsigned long flags;
unsigned long compound_head; /* Bit zero is set */
};
static inline bool constant_test_bit(unsigned int nr, const void *addr)
{
const unsigned int *p = (const unsigned int *)addr;
return ((1UL << (nr & 31)) & (p[nr >> 5])) != 0;
}
static inline struct page *compound_head(struct page *page)
{
unsigned long head = page->compound_head;
if (unlikely(head & 1))
return (struct page *) (head - 1);
return page;
}
bool PageUptodate(struct page *page)
{
bool ret;
page = compound_head(page);
ret = constant_test_bit(PG_uptodate, &page->flags);
if (ret)
smp_rmb();
return ret;
}
with "gcc -Os" I get the following assembly excerpt:
PageUptodate:
.LFB2:
.cfi_startproc
movq 8(%rdi), %rax
testb $1, %al
je .L2
leaq -1(%rax), %rdi
.L2:
movl (%rdi), %eax
shrq $2, %rax
andb $1, %al
je .L1
.L1:
ret
.cfi_endproc
There's a superfluous jump, JE, at the end jumping to the next instruction with
label .L1. This corresponds to the smp_rmb() which is just a compiler barrier.
This also happens with other optimisation levels.