S/390: Fix vecinit expansion.
authorAndreas Krebbel <krebbel@linux.vnet.ibm.com>
Wed, 6 Jul 2016 07:05:11 +0000 (07:05 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Wed, 6 Jul 2016 07:05:11 +0000 (07:05 +0000)
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  <krebbel@linux.vnet.ibm.com>

* config/s390/s390.c (s390_expand_vec_init): Force initializer
element to register if it doesn't match general_operand.

From-SVN: r238032

gcc/ChangeLog
gcc/config/s390/s390.c

index f3099046a832a321cb92ebee7b25017217558cd4..b248acd1f0042d7618b9eea8a6de23bcdfcede08 100644 (file)
@@ -1,3 +1,8 @@
+2016-07-06  Andreas Krebbel  <krebbel@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  <meissner@linux.vnet.ibm.com>
            Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
 
index ee0187c67f70628edb923cfa432283a724b5f5c8..9d2b2c0cadd721e25e1fb5be007657a29d04d47d 100644 (file)
@@ -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