This patch fixes PR 52199, which shows up on power7 systems when the compiler
is vectorizing DImode operations, and the vector duplicate code was not
prepared to accept CONST and SYMBOL_REF's.

I have done a bootstrap and make compare, and there were no regressions.  Is
this ok to install?  I will also back port the change to 4.6, since the exact
same code is in that revision as well.

-- 
Michael Meissner, IBM
5 Technology Place Drive, M/S 2757, Westford, MA 01886-3141, USA
meiss...@linux.vnet.ibm.com     fax +1 (978) 399-6899
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 184276)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -4701,28 +4701,25 @@ rs6000_expand_vector_init (rtx target, r
   /* Double word values on VSX can use xxpermdi or lxvdsx.  */
   if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
     {
+      rtx op0 = XVECEXP (vals, 0, 0);
+      rtx op1 = XVECEXP (vals, 0, 1);
       if (all_same)
        {
-         rtx element = XVECEXP (vals, 0, 0);
+         if (!MEM_P (op0) && !REG_P (op0))
+           op0 = force_reg (inner_mode, op0);
          if (mode == V2DFmode)
-           emit_insn (gen_vsx_splat_v2df (target, element));
+           emit_insn (gen_vsx_splat_v2df (target, op0));
          else
-           emit_insn (gen_vsx_splat_v2di (target, element));
+           emit_insn (gen_vsx_splat_v2di (target, op0));
        }
       else
        {
+         op0 = force_reg (inner_mode, op0);
+         op1 = force_reg (inner_mode, op1);
          if (mode == V2DFmode)
-           {
-             rtx op0 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 0));
-             rtx op1 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 1));
-             emit_insn (gen_vsx_concat_v2df (target, op0, op1));
-           }
+           emit_insn (gen_vsx_concat_v2df (target, op0, op1));
          else
-           {
-             rtx op0 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 0));
-             rtx op1 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 1));
-             emit_insn (gen_vsx_concat_v2di (target, op0, op1));
-           }
+           emit_insn (gen_vsx_concat_v2di (target, op0, op1));
        }
       return;
     }
@@ -4736,7 +4733,7 @@ rs6000_expand_vector_init (rtx target, r
       if (all_same)
        {
          rtx freg = gen_reg_rtx (V4SFmode);
-         rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
+         rtx sreg = force_reg (SFmode, XVECEXP (vals, 0, 0));
 
          emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
          emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
@@ -4747,13 +4744,13 @@ rs6000_expand_vector_init (rtx target, r
          rtx dbl_odd  = gen_reg_rtx (V2DFmode);
          rtx flt_even = gen_reg_rtx (V4SFmode);
          rtx flt_odd  = gen_reg_rtx (V4SFmode);
+         rtx op0 = force_reg (SFmode, XVECEXP (vals, 0, 0));
+         rtx op1 = force_reg (SFmode, XVECEXP (vals, 0, 1));
+         rtx op2 = force_reg (SFmode, XVECEXP (vals, 0, 2));
+         rtx op3 = force_reg (SFmode, XVECEXP (vals, 0, 3));
 
-         emit_insn (gen_vsx_concat_v2sf (dbl_even,
-                                         copy_to_reg (XVECEXP (vals, 0, 0)),
-                                         copy_to_reg (XVECEXP (vals, 0, 1))));
-         emit_insn (gen_vsx_concat_v2sf (dbl_odd,
-                                         copy_to_reg (XVECEXP (vals, 0, 2)),
-                                         copy_to_reg (XVECEXP (vals, 0, 3))));
+         emit_insn (gen_vsx_concat_v2sf (dbl_even, op0, op1));
+         emit_insn (gen_vsx_concat_v2sf (dbl_odd, op2, op3));
          emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
          emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
          rs6000_expand_extract_even (target, flt_even, flt_odd);
Index: gcc/testsuite/gcc.target/powerpc/pr52199.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr52199.c  (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/pr52199.c  (revision 0)
@@ -0,0 +1,24 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-O3 -mcpu=power7 -fmerge-all-constants" } */
+
+struct locale_time_t
+{
+  const char *abday[7];
+  const unsigned int *wabday[7];
+};
+
+static const unsigned int empty_wstr[1] = { 0 };
+
+void
+time_read (struct locale_time_t *time)
+{
+  int cnt;
+
+  for (cnt=0; cnt < 7; cnt++)
+    {
+      time->abday[cnt] = "";
+      time->wabday[cnt] = empty_wstr;
+    }
+}

Reply via email to