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