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