[Committed] S/390: Fix problem with vec_init expander

Message ID 1539590880-22961-1-git-send-email-krebbel@linux.ibm.com
State New
Headers show
Series
  • [Committed] S/390: Fix problem with vec_init expander
Related show

Commit Message

Andreas Krebbel Oct. 15, 2018, 8:08 a.m.
gcc/ChangeLog:

2018-10-15  Andreas Krebbel  <krebbel@linux.ibm.com>

	* config/s390/s390.c (s390_expand_vec_init): Force vector element
	into reg if it isn't a general operand.

gcc/testsuite/ChangeLog:

2018-10-15  Andreas Krebbel  <krebbel@linux.ibm.com>

	* g++.dg/vec-init-1.C: New test.
---
 gcc/config/s390/s390.c            | 11 ++++++++---
 gcc/testsuite/g++.dg/vec-init-1.C | 26 ++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/vec-init-1.C

-- 
2.7.4

Patch

diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 71039fe..ab22c2c 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -6627,11 +6627,16 @@  s390_expand_vec_init (rtx target, rtx vals)
       return;
     }
 
+  /* Use vector replicate instructions.  vlrep/vrepi/vrep  */
   if (all_same)
     {
-      emit_insn (gen_rtx_SET (target,
-			      gen_rtx_VEC_DUPLICATE (mode,
-						     XVECEXP (vals, 0, 0))));
+      rtx elem = XVECEXP (vals, 0, 0);
+
+      /* vec_splats accepts general_operand as source.  */
+      if (!general_operand (elem, GET_MODE (elem)))
+	elem = force_reg (inner_mode, elem);
+
+      emit_insn (gen_rtx_SET (target, gen_rtx_VEC_DUPLICATE (mode, elem)));
       return;
     }
 
diff --git a/gcc/testsuite/g++.dg/vec-init-1.C b/gcc/testsuite/g++.dg/vec-init-1.C
new file mode 100644
index 0000000..f35d39c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vec-init-1.C
@@ -0,0 +1,26 @@ 
+/* On S/390 this ends up calling the vec_init RTL expander with a
+   parallel of two symbol_refs.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O3 -fPIC" } */
+
+
+struct test
+{
+    struct base
+    {
+       int key;
+    };
+    struct derived : public base
+    {
+       int key;
+    };
+
+    derived core;
+    derived &dRef;
+    base &bRef;
+
+    test() : dRef (core), bRef (core) {}
+};
+
+test test;