http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58400
--- Comment #6 from Jeffrey A. Law <law at redhat dot com> ---
Reduced testcase:
static __inline__ __attribute__((always_inline))
__attribute__((no_instrument_function)) int test_bit(int nr, const unsigned
long* addr)
{
return (*((volatile unsigned char *)addr +
((nr >> 3) ^ 3)) & (1UL << (nr & 7))) != 0;
}
static inline __attribute__((always_inline))
__attribute__((no_instrument_function)) int test_bit_le(int nr, const void
*addr)
{
return test_bit(nr ^ ((32 -1) & ~0x7), addr);
}
typedef int ext4_grpblk_t;
struct ext4_group_info {
unsigned long bb_state;
ext4_grpblk_t bb_counters[];
};
struct ext4_buddy {
struct super_block *bd_sb;
struct ext4_group_info *bd_info;
};
static inline __attribute__((always_inline))
__attribute__((no_instrument_function)) void *mb_correct_addr_and_bit(int *bit,
void *addr)
{
*bit += ((unsigned long) addr & 3UL) << 3;
return addr;
}
static inline __attribute__((always_inline))
__attribute__((no_instrument_function)) int mb_test_bit(int bit, void *addr)
{
addr = mb_correct_addr_and_bit(&bit, addr);
return test_bit_le(bit, addr);
}
static inline __attribute__((always_inline))
__attribute__((no_instrument_function)) void mb_clear_bit(int bit, void *addr)
{
addr = mb_correct_addr_and_bit(&bit, addr);
__clear_bit_le(bit, addr);
}
static inline __attribute__((always_inline))
__attribute__((no_instrument_function)) int mb_buddy_adjust_border(int* bit,
void* bitmap, int side)
{
if (mb_test_bit(*bit + side, bitmap)) {
mb_clear_bit(*bit, bitmap);
}
}
static void mb_buddy_mark_free(struct ext4_buddy *e4b, int first)
{
int max;
int order = 1;
void *buddy = bar ();
while (buddy) {
void *buddy2;
e4b->bd_info->bb_counters[order] += mb_buddy_adjust_border(&first, buddy,
-1);
order++;
buddy = buddy2;
}
}
void mb_free_blocks(struct inode *inode, struct ext4_buddy *e4b,
int first, int count)
{
int last = first + count - 1;
int block;
struct super_block *sb = e4b->bd_sb;
block = foo();
if (!!(block != -1))
mb_regenerate_buddy();
mb_buddy_mark_free(e4b, first >> 1);
}