Hi, on 2024/2/26 13:43, jeevitha wrote: > Hi All, > > The following patch has been bootstrapped and regtested on powerpc64le-linux. > > PR110040 exposes an issue concerning moves from vector registers to GPRs. > There are two moves, one for upper 64 bits and the other for the lower > 64 bits. In the problematic test case, we are only interested in storing > the lower 64 bits. However, the instruction for copying the upper 64 bits > is still emitted and is dead code. This patch adds a splitter that splits > apart the two move instructions so that DCE can remove the dead code after > splitting. > > 2024-02-26 Jeevitha Palanisamy <jeevi...@linux.ibm.com> > > gcc/ > PR target/110040 > * config/rs6000/vsx.md (split pattern for V1TI to DI move): Defined. > > gcc/testsuite/ > PR target/110040 > * gcc.target/powerpc/pr110040-1.c: New testcase. > * gcc.target/powerpc/pr110040-2.c: New testcase. > > > diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md > index 6111cc90eb7..78457f8fb14 100644 > --- a/gcc/config/rs6000/vsx.md > +++ b/gcc/config/rs6000/vsx.md > @@ -6706,3 +6706,19 @@ > "vmsumcud %0,%1,%2,%3" > [(set_attr "type" "veccomplex")] > ) > + > +(define_split > + [(set (match_operand:V1TI 0 "int_reg_operand") > + (match_operand:V1TI 1 "vsx_register_operand"))] > + "reload_completed > + && TARGET_DIRECT_MOVE_64BIT" > + [(pc)] > +{ > + rtx op0 = gen_rtx_REG (DImode, REGNO (operands[0])); > + rtx op1 = gen_rtx_REG (V2DImode, REGNO (operands[1])); > + rtx op2 = gen_rtx_REG (DImode, REGNO (operands[0]) + 1); > + rtx op3 = gen_rtx_REG (V2DImode, REGNO (operands[1]));
Nit: op3 is the same as op1 (so useless and removable), just call it as src_op? Maybe op0 and op2 as dest_op0, dest_op1 to match the extracted index? > + emit_insn (gen_vsx_extract_v2di (op0, op1, GEN_INT (0))); > + emit_insn (gen_vsx_extract_v2di (op2, op3, GEN_INT (1))); Nit: GEN_INT ({0,1}) can be substituted with const{0,1}_rtx. > + DONE; > +}) > diff --git a/gcc/testsuite/gcc.target/powerpc/pr110040-1.c > b/gcc/testsuite/gcc.target/powerpc/pr110040-1.c > new file mode 100644 > index 00000000000..fb3bd254636 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/powerpc/pr110040-1.c > @@ -0,0 +1,14 @@ > +/* PR target/110040 */ > +/* { dg-do compile } */ > +/* { dg-require-effective-target powerpc_p9vector_ok } */ > +/* { dg-options "-O2 -mdejagnu-cpu=power9" } */ powerpc_p9vector_ok doesn't exist any more, you have to rebase. This also requires int128 effective target. Change it to: /* { dg-options "-O2" } */ /* { dg-require-effective-target int128 } */ /* { dg-require-effective-target powerpc_vsx } */ Since we just check no mfvsrd, I think we can even drop the "-mdejagnu-cpu=power9", could you test if it works on multiple environments? > +/* { dg-final { scan-assembler-not {\mmfvsrd\M} } } */ > + > +#include <altivec.h> > + > +void > +foo (signed long *dst, vector signed __int128 src) > +{ > + *dst = (signed long) src[0]; > +} > + > diff --git a/gcc/testsuite/gcc.target/powerpc/pr110040-2.c > b/gcc/testsuite/gcc.target/powerpc/pr110040-2.c > new file mode 100644 > index 00000000000..f3aa22be4e8 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/powerpc/pr110040-2.c > @@ -0,0 +1,13 @@ > +/* PR target/110040 */ > +/* { dg-do compile } */ > +/* { dg-require-effective-target power10_ok } */ > +/* { dg-options "-O2 -mdejagnu-cpu=power10" } */ > +/* { dg-final { scan-assembler-not {\mmfvsrd\M} } } */ Similar to the above: /* { dg-options "-O2 -mdejagnu-cpu=power10" } */ /* { dg-require-effective-target int128 } */ /* { dg-require-effective-target powerpc_vsx } */ Also adding one comment why it requires power10. BR, Kewen > + > +#include <altivec.h> > + > +void > +foo (signed int *dst, vector signed __int128 src) > +{ > + __builtin_vec_xst_trunc (src, 0, dst); > +} > >