]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR rtl-optimization/pr55829
authorVladimir Makarov <vmakarov@redhat.com>
Wed, 9 Jan 2013 17:02:11 +0000 (17:02 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Wed, 9 Jan 2013 17:02:11 +0000 (17:02 +0000)
2013-01-09  Vladimir Makarov  <vmakarov@redhat.com>

PR rtl-optimization/pr55829
* lra-constraints.c (match_reload): Add code for absent output.
(curr_insn_transform): Add code for reloads of matched inputs
without output.

2013-01-09  Vladimir Makarov  <vmakarov@redhat.com>

PR rtl-optimization/pr55829
* gcc.target/i386/pr55829.c: New.

From-SVN: r195057

gcc/ChangeLog
gcc/lra-constraints.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr55829.c [new file with mode: 0644]

index 6377fe57b90179cb5814187e2980c8ae311bccc6..cbdc1adca959422b75878099ddb8cb2fc6911c5c 100644 (file)
@@ -1,3 +1,10 @@
+2013-01-09  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR rtl-optimization/pr55829
+       * lra-constraints.c (match_reload): Add code for absent output.
+       (curr_insn_transform): Add code for reloads of matched inputs
+       without output.
+
 2013-01-09  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/sse.md (*vec_interleave_highv2df): Change mode
index f6c6c89b8582ab6cfe56acdca312a623e4946bf4..fcece42970433b076fc566a4ec8c891d28f41ee8 100644 (file)
@@ -658,8 +658,9 @@ narrow_reload_pseudo_class (rtx reg, enum reg_class cl)
 
 /* Generate reloads for matching OUT and INS (array of input operand
    numbers with end marker -1) with reg class GOAL_CLASS.  Add input
-   and output reloads correspondingly to the lists *BEFORE and
-   *AFTER.  */
+   and output reloads correspondingly to the lists *BEFORE and *AFTER.
+   OUT might be negative.  In this case we generate input reloads for
+   matched input operands INS.  */
 static void
 match_reload (signed char out, signed char *ins, enum reg_class goal_class,
              rtx *before, rtx *after)
@@ -668,10 +669,10 @@ match_reload (signed char out, signed char *ins, enum reg_class goal_class,
   rtx new_in_reg, new_out_reg, reg, clobber;
   enum machine_mode inmode, outmode;
   rtx in_rtx = *curr_id->operand_loc[ins[0]];
-  rtx out_rtx = *curr_id->operand_loc[out];
+  rtx out_rtx = out < 0 ? in_rtx : *curr_id->operand_loc[out];
 
-  outmode = curr_operand_mode[out];
   inmode = curr_operand_mode[ins[0]];
+  outmode = out < 0 ? inmode : curr_operand_mode[out];
   push_to_sequence (*before);
   if (inmode != outmode)
     {
@@ -746,14 +747,13 @@ match_reload (signed char out, signed char *ins, enum reg_class goal_class,
        = lra_create_new_reg_with_unique_value (outmode, out_rtx,
                                                goal_class, "");
     }
-  /* In and out operand can be got from transformations before
-     processing insn constraints.  One example of such transformations
-     is subreg reloading (see function simplify_operand_subreg).  The
-     new pseudos created by the transformations might have inaccurate
+  /* In operand can be got from transformations before processing insn
+     constraints.  One example of such transformations is subreg
+     reloading (see function simplify_operand_subreg).  The new
+     pseudos created by the transformations might have inaccurate
      class (ALL_REGS) and we should make their classes more
      accurate.  */
   narrow_reload_pseudo_class (in_rtx, goal_class);
-  narrow_reload_pseudo_class (out_rtx, goal_class);
   lra_emit_move (copy_rtx (new_in_reg), in_rtx);
   *before = get_insns ();
   end_sequence ();
@@ -765,6 +765,10 @@ match_reload (signed char out, signed char *ins, enum reg_class goal_class,
       *curr_id->operand_loc[in] = new_in_reg;
     }
   lra_update_dups (curr_id, ins);
+  if (out < 0)
+    return;
+  /* See a comment for the input operand above.  */
+  narrow_reload_pseudo_class (out_rtx, goal_class);
   if (find_reg_note (curr_insn, REG_UNUSED, out_rtx) == NULL_RTX)
     {
       start_sequence ();
@@ -2597,6 +2601,7 @@ curr_insn_transform (void)
   int n_alternatives;
   int commutative;
   signed char goal_alt_matched[MAX_RECOG_OPERANDS][MAX_RECOG_OPERANDS];
+  signed char match_inputs[MAX_RECOG_OPERANDS + 1];
   rtx before, after;
   bool alt_p = false;
   /* Flag that the insn has been changed through a transformation.  */
@@ -3052,17 +3057,28 @@ curr_insn_transform (void)
               && (curr_static_id->operand[goal_alt_matched[i][0]].type
                   == OP_OUT))
        {
-         signed char arr[2];
-
-         arr[0] = i;
-         arr[1] = -1;
-         match_reload (goal_alt_matched[i][0], arr,
+         /* generate reloads for input and matched outputs.  */
+         match_inputs[0] = i;
+         match_inputs[1] = -1;
+         match_reload (goal_alt_matched[i][0], match_inputs,
                        goal_alt[i], &before, &after);
        }
       else if (curr_static_id->operand[i].type == OP_OUT
               && (curr_static_id->operand[goal_alt_matched[i][0]].type
                   == OP_IN))
+       /* Generate reloads for output and matched inputs.  */
        match_reload (i, goal_alt_matched[i], goal_alt[i], &before, &after);
+      else if (curr_static_id->operand[i].type == OP_IN
+              && (curr_static_id->operand[goal_alt_matched[i][0]].type
+                  == OP_IN))
+       {
+         /* Generate reloads for matched inputs.  */
+         match_inputs[0] = i;
+         for (j = 0; (k = goal_alt_matched[i][j]) >= 0; j++)
+           match_inputs[j + 1] = k;
+         match_inputs[j + 1] = -1;
+         match_reload (-1, match_inputs, goal_alt[i], &before, &after);
+       }
       else
        /* We must generate code in any case when function
           process_alt_operands decides that it is possible.  */
index bbb51fbbea088dea6d815fdc254f3d231ca17ef2..b545fe1b8dbe54e83e79d6e9f580a87c1e52ed32 100644 (file)
@@ -1,3 +1,8 @@
+2013-01-09  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR rtl-optimization/pr55829
+       * gcc.target/i386/pr55829.c: New.
+
 2013-01-09  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/55758
diff --git a/gcc/testsuite/gcc.target/i386/pr55829.c b/gcc/testsuite/gcc.target/i386/pr55829.c
new file mode 100644 (file)
index 0000000..be70ba2
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse3 -fno-expensive-optimizations" } */
+
+typedef double __m128d __attribute__ ((__vector_size__ (16)));
+
+extern double p1[];
+extern double p2[];
+extern double ck[];
+extern int n;
+
+__attribute__((__noinline__, __noclone__)) int chk_pd (double *v1, double *v2)
+{
+  return v2[n] != v1[n];
+}
+
+static inline void sse3_test_movddup_reg_subsume_ldsd (double *i1, double *r)
+{
+  __m128d t1 = (__m128d){*i1, 0};
+  __m128d t2 = __builtin_ia32_shufpd (t1, t1, 0);
+  __builtin_ia32_storeupd (r, t2);
+}
+
+int sse3_test (void)
+{
+  int i = 0;
+  int fail = 0;
+  for (; i < 80; i += 1)
+    {
+      ck[0] = p1[0];
+      fail += chk_pd (ck, p2);
+      sse3_test_movddup_reg_subsume_ldsd (p1, p2);
+    }
+  return fail;
+}