[Bug target/82259] missed optimization: use LEA to add 1 to flip the low bit when copying before AND with 1

ubizjak at gmail dot com gcc-bugzilla@gcc.gnu.org
Tue Sep 19 16:47:00 GMT 2017


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

--- Comment #2 from Uroš Bizjak <ubizjak at gmail dot com> ---
(In reply to Peter Cordes from comment #0)

> Related:
> 
> bool bt_unsigned(unsigned x, unsigned bit) {
>         //bit = 13;
>         return !(x & (1<<bit));  // 1U avoids test/set
> }
> 
>         movl    %esi, %ecx
>         movl    $1, %eax
>         sall    %cl, %eax
>         testl   %edi, %eax
>         sete    %al
>         ret
> 
> This is weird.  The code generated with  1U << bit  is like the bt_signed
> code above and has identical results, so gcc should emit whatever is optimal
> for both cases.  There are similar differences on ARM32.
> 
> (With a fixed count, it just makes the difference between NOT vs. XOR $1.)
> 
> If we're going to use setcc, it's definitely *much* better to use  bt 
> instead of a variable-count shift + test.
> 
>         bt      %esi, %edi
>         setz    %al
>         ret

A couple of *scc_bt patterns are missing. These are similar to already existing
*jcc_bt patterns. Combine wants:

Failed to match this instruction:
(set (reg:QI 97)
    (eq:QI (zero_extract:SI (reg/v:SI 91 [ x ])
            (const_int 1 [0x1])
            (zero_extend:SI (subreg:QI (reg/v:SI 92 [ bit ]) 0)))
        (const_int 0 [0])))


More information about the Gcc-bugs mailing list