On Tue, 2025-01-21 at 22:14 +0800, Xi Ruoyao wrote:
> > > in GCC 13 the result is:
> > > 
> > >   or      $r12,$r4,$r0
> > 
> > Hmm, this strange move is caused by "&" in bstrpick_alsl_paired.  Is it
> > really needed for the fusion?
> 
> Never mind, it's needed or a = ((a & 0xffffffff) << 1) + a will blow up.
> Stupid I.

And my code is indeed broken due to the missing '&':

/* { dg-do run } */
/* { dg-options "-O2" } */

register long x asm ("s0");

#define TEST(x) (int)(((x & 0x114) << 3) + x)

[[gnu::noipa]] void
test (void)
{
  x = TEST (x);
}

int
main (void)
{
  x = 0xffff;
  test ();
  if (x != TEST (0xffff))
    __builtin_trap ();
}

ends up:

0000000000000760 <test>:
 760:   034452f7        andi            $s0, $s0, 0x114
 764:   00055ef7        alsl.w          $s0, $s0, $s0, 0x3
 768:   4c000020        ret

and fails.  The fix would be like https://gcc.gnu.org/r15-5074.

> > >   bstrpick.d      $r4,$r12,31,0
> > >   alsl.d  $r4,$r4,$r6,2
> > >   or      $r12,$r5,$r0
> > >   bstrpick.d      $r5,$r12,31,0
> > >   alsl.d  $r5,$r5,$r6,2
> > >   jr      $r1

-- 
Xi Ruoyao <xry...@xry111.site>
School of Aerospace Science and Technology, Xidian University

Reply via email to