]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rs6000: load high and low part of 128bit vector independently [PR110040]
authorJeevitha <jeevitha@linux.ibm.com>
Mon, 8 Jul 2024 11:09:49 +0000 (06:09 -0500)
committerJeevitha <jeevitha@linux.ibm.com>
Mon, 8 Jul 2024 11:09:49 +0000 (06:09 -0500)
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-07-08  Jeevitha Palanisamy  <jeevitha@linux.ibm.com>

gcc/
PR target/110040
* config/rs6000/vsx.md (split pattern for V1TI to DI move): New define.

gcc/testsuite/
PR target/110040
* gcc.target/powerpc/pr110040-1.c: New testcase.
* gcc.target/powerpc/pr110040-2.c: New testcase.

gcc/config/rs6000/vsx.md
gcc/testsuite/gcc.target/powerpc/pr110040-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/pr110040-2.c [new file with mode: 0644]

index 48ba262f7e485d2508e61672b9ff89c5feb94332..23ce5c7405102640d4dc9d48cf473f0348dee5dc 100644 (file)
   "vmsumcud %0,%1,%2,%3"
   [(set_attr "type" "veccomplex")]
 )
+
+(define_split
+  [(set (match_operand:V1TI 0 "gpc_reg_operand")
+       (match_operand:V1TI 1 "vsx_register_operand"))]
+  "reload_completed
+   && TARGET_DIRECT_MOVE_64BIT
+   && int_reg_operand (operands[0], V1TImode)
+   && vsx_register_operand (operands[1], V1TImode)"
+   [(pc)]
+{
+  rtx src_op = gen_rtx_REG (V2DImode, REGNO (operands[1]));
+  rtx dest_op0 = gen_rtx_REG (DImode, REGNO (operands[0]));
+  rtx dest_op1 = gen_rtx_REG (DImode, REGNO (operands[0]) + 1);
+  emit_insn (gen_vsx_extract_v2di (dest_op0, src_op, const0_rtx));
+  emit_insn (gen_vsx_extract_v2di (dest_op1, src_op, const1_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 (file)
index 0000000..0a521e9
--- /dev/null
@@ -0,0 +1,15 @@
+/* PR target/110040 */
+/* { dg-do compile } */
+/* { dg-require-effective-target int128 } */
+/* { dg-require-effective-target powerpc_vsx } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
+/* { 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 (file)
index 0000000..8236f3c
--- /dev/null
@@ -0,0 +1,16 @@
+/* PR target/110040 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=power10" } */
+/* { dg-require-effective-target int128 } */
+/* { dg-require-effective-target powerpc_vsx } */
+/* { dg-final { scan-assembler-not {\mmfvsrd\M} } } */
+
+/* builtin vec_xst_trunc requires power10.  */
+
+#include <altivec.h>
+
+void
+foo (signed int *dst, vector signed __int128 src)
+{
+  __builtin_vec_xst_trunc (src, 0, dst);
+}