The fallback routine in the S/390 vecinit expander did not check
whether each of the initializer elements is a proper general_operand.
Since revision r236582 the expander is invoked also with e.g. symbol
refs with an odd addend resulting in invalid insns.

Fixed by forcing the element into a register in such cases.

gcc/ChangeLog:

2016-07-06  Andreas Krebbel  <kreb...@linux.vnet.ibm.com>

        * config/s390/s390.c (s390_expand_vec_init): Force initializer
        element to register if it doesn't match general_operand.
---
 gcc/ChangeLog          |  5 +++++
 gcc/config/s390/s390.c | 16 +++++++++++-----
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f309904..b248acd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2016-07-06  Andreas Krebbel  <kreb...@linux.vnet.ibm.com>
+
+       * config/s390/s390.c (s390_expand_vec_init): Force initializer
+       element to register if it doesn't match general_operand.
+
 2016-07-05  Michael Meissner  <meiss...@linux.vnet.ibm.com>
            Bill Schmidt  <wschm...@linux.vnet.ibm.com>
 
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index ee0187c..9d2b2c0 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -6443,11 +6443,17 @@ s390_expand_vec_init (rtx target, rtx vals)
   /* Unfortunately the vec_init expander is not allowed to fail.  So
      we have to implement the fallback ourselves.  */
   for (i = 0; i < n_elts; i++)
-    emit_insn (gen_rtx_SET (target,
-                           gen_rtx_UNSPEC (mode,
-                                           gen_rtvec (3, XVECEXP (vals, 0, i),
-                                                      GEN_INT (i), target),
-                                           UNSPEC_VEC_SET)));
+    {
+      rtx elem = XVECEXP (vals, 0, i);
+      if (!general_operand (elem, GET_MODE (elem)))
+       elem = force_reg (inner_mode, elem);
+
+      emit_insn (gen_rtx_SET (target,
+                             gen_rtx_UNSPEC (mode,
+                                             gen_rtvec (3, elem,
+                                                        GEN_INT (i), target),
+                                             UNSPEC_VEC_SET)));
+    }
 }
 
 /* Structure to hold the initial parameters for a compare_and_swap operation
-- 
1.9.1

Reply via email to