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

--- Comment #4 from Xi Ruoyao <xry111 at gcc dot gnu.org> ---
(In reply to Andrew Pinski from comment #2)
> Interesting:
> int test(int a, int b)
> {
>   return (a & ~0x80000000) | (b & 0x80000000);
> }
> 
> Produces better code:
>         lu12i.w $r12,-2147483648>>12                  # 0xffffffff80000000
>         and     $r12,$r12,$r5
>         bstrpick.w      $r4,$r4,30,0
>         or      $r4,$r4,$r12
>         slli.w  $r4,$r4,0
>         jr      $r1

Hmm, this seems a separate issue.  The compiler knows to optimize (a & mask) if
mask is ((1 << a) - 1) << b iff a + b = 32 or b = 0, but not for any other
masks even if it's "expensive" to materialize the mask:

long test(long a, long b)
{
  return a & 0xfffff0000l;
}

compiles to:

        lu12i.w $r12,-65536>>12                 # 0xffffffffffff0000
        lu32i.d $r12,0xf00000000>>32
        and     $r4,$r4,$r12
        jr      $r1

But the following is better:

bstrpick.d $r12, $r12, 35, 16
slli.d     $r12, $r12, 16

Reply via email to