------- Comment #2 from dann at godzilla dot ics dot uci dot edu 2005-11-13 02:47 ------- Simplified testcase: struct cpuinfo_x86 { unsigned char x86; unsigned char x86_vendor; unsigned char x86_model; unsigned char x86_mask; char wp_works_ok; char hlt_works_ok; char hard_math; char rfu; int cpuid_level; unsigned long x86_capability[7]; } __attribute__((__aligned__((1 << (7)))));
struct task_struct; extern void foo (struct task_struct *tsk); extern void bar (struct task_struct *tsk); extern struct cpuinfo_x86 boot_cpu_data; static inline __attribute__((always_inline)) int constant_test_bit(int nr, const volatile unsigned long *addr) { return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0; } void restore_fpu(struct task_struct *tsk) { if (constant_test_bit(24, boot_cpu_data.x86_capability)) foo (tsk); else bar (tsk); } The generated code for this simplified tescase shows one additional issue: restore_fpu: movl %eax, %edx movl boot_cpu_data+12, %eax ; edx could be used here testl $16777216, %eax ; and here je .L2 movl %edx, %eax ; then all the mov %eax, %edx and mov %edx, %eax jmp foo ; instructions could be eliminated. .p2align 4,,7 .L2: movl %edx, %eax jmp bar -- dann at godzilla dot ics dot uci dot edu changed: What |Removed |Added ---------------------------------------------------------------------------- Summary|mov + mov + testl generated |[4.1 Regression] mov + mov + |instead of testb |testl generated instead of | |testb http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24810