On Tue, Jun 21, 2022 at 10:03:18AM +0800, Kewen.Lin wrote:
> This case also needs effective-target keyword lp64,
> that is /* { dg-require-effective-target lp64 } */

Good point.  Yes.

It would be nice to have just has_arch_ppc64 really.

> since with -m32, it gets:
>   mr 3,4
> 
> with -m32 -mpowerpc64, it gets:
>   rldicl 3,4,0,32

Yes, and that is not lp64 -- both longs and pointers are 32 bits when
you have -m32.

You get different code because parameter passing is different.  The
usual way to sidestep is to have the data in memory instead:

unsigned long long x;
void 
goo (void)
{
  unsigned long long value = x;
  value &= 0xffffffff;
  value |= value << 32;
  x = value;
}

but then the compiler tries to be smart and do code like
        addis 10,2,.LANCHOR0+4@toc@ha
        lwz 10,.LANCHOR0+4@toc@l(10)
        sldi 9,10,32
        add 9,9,10
        addis 10,2,.LANCHOR0@toc@ha
        std 9,.LANCHOR0@toc@l(10)
        blr
for -m64, and
        lis 9,x@ha
        la 10,x@l(9)
        lwz 10,4(10)
        stw 10,x@l(9)
        blr
for just -m32, but
        lis 10,x@ha
        la 9,x@l(10)
        la 10,x@l(10)
        ld 9,0(9)
        rldicl 8,9,0,32
        sldi 9,9,32
        add 9,9,8
        std 9,0(10)
        blr
for -m32 -mpowerpc64 (note it has not managed to do the splitter here;
it gets
Failed to match this instruction:
(set (reg:DI 128)
    (plus:DI (ashift:DI (reg/v:DI 117 [ value ])
            (const_int 32 [0x20]))
        (zero_extend:DI (subreg:SI (reg/v:DI 117 [ value ]) 4))))
and then
Failed to match this instruction:
(set (reg:DI 128)
    (plus:DI (and:DI (reg/v:DI 117 [ value ])
            (const_int 4294967295 [0xffffffff]))
        (ashift:DI (reg/v:DI 117 [ value ])
            (const_int 32 [0x20]))))
but that is not enough).

So let's just do lp64, at least for now :-)


Segher

Reply via email to