aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeevitha <jeevitha@linux.ibm.com>2024-07-08 06:09:49 -0500
committerJeevitha <jeevitha@linux.ibm.com>2024-07-08 06:09:49 -0500
commit5be97039aa6c27fdf5d5bd43ef393b307c5ecedd (patch)
tree90df2205903d02c745377f3bf4441c058b49d7a8
parentdafd63d7c5cddce1e00803606e742d75927b1a1e (diff)
downloadgcc-5be97039aa6c27fdf5d5bd43ef393b307c5ecedd.zip
gcc-5be97039aa6c27fdf5d5bd43ef393b307c5ecedd.tar.gz
gcc-5be97039aa6c27fdf5d5bd43ef393b307c5ecedd.tar.bz2
rs6000: load high and low part of 128bit vector independently [PR110040]
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.
-rw-r--r--gcc/config/rs6000/vsx.md17
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr110040-1.c15
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr110040-2.c16
3 files changed, 48 insertions, 0 deletions
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index 48ba262..23ce5c7 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -6735,3 +6735,20 @@
"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
index 0000000..0a521e9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr110040-1.c
@@ -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
index 0000000..8236f3c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr110040-2.c
@@ -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);
+}