Hi!

As the comment say, we want to insert (if should_insert_square_recip
is true) new_square_stmt right after new_stmt.  The current code does
that correctly if new_stmt is inserted with
  gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
because the following
    gsi_insert_before (&gsi, new_square_stmt, GSI_SAME_STMT);
will keep inserting before whatever gsi points to.
But one of the 3 cases inserts new_stmt instead after def_gsi, and the
current
  gsi = *def_gsi;
  gsi_insert_after (def_gsi, new_stmt, GSI_NEW_STMT);
    gsi_insert_before (&gsi, new_square_stmt, GSI_SAME_STMT);
certainly doesn't do that, it inserts new_stmt after the def_gsi stmt and
then inserts new_square_stmt before the def_gsi stmt, so we have order of:
  new_square_stmt
  whatever-def_gsi-pointed-to-stmt
  new_stmt
where new_square_stmt uses the lhs of new_stmt.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2018-08-03  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/86835
        * tree-ssa-math-opts.c (insert_reciprocals): Even when inserting
        new_stmt after def_gsi, make sure to insert new_square_stmt after
        that stmt, not 2 stmts before it.

        * gcc.dg/pr86835.c: New test.

--- gcc/tree-ssa-math-opts.c.jj 2018-07-12 21:31:27.698410833 +0200
+++ gcc/tree-ssa-math-opts.c    2018-08-03 12:58:27.475961037 +0200
@@ -422,6 +422,8 @@ insert_reciprocals (gimple_stmt_iterator
            gsi_next (&gsi);
 
          gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
+         if (should_insert_square_recip)
+           gsi_insert_before (&gsi, new_square_stmt, GSI_SAME_STMT);
        }
       else if (def_gsi && occ->bb == def_gsi->bb)
        {
@@ -429,21 +431,19 @@ insert_reciprocals (gimple_stmt_iterator
             never happen if the definition statement can throw, because in
             that case the sole successor of the statement's basic block will
             dominate all the uses as well.  */
-         gsi = *def_gsi;
          gsi_insert_after (def_gsi, new_stmt, GSI_NEW_STMT);
+         if (should_insert_square_recip)
+           gsi_insert_after (def_gsi, new_square_stmt, GSI_NEW_STMT);
        }
       else
        {
          /* Case 3: insert in a basic block not containing defs/uses.  */
          gsi = gsi_after_labels (occ->bb);
          gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
+         if (should_insert_square_recip)
+           gsi_insert_before (&gsi, new_square_stmt, GSI_SAME_STMT);
        }
 
-      /* Regardless of which case the reciprocal as inserted in,
-        we insert the square immediately after the reciprocal.  */
-      if (should_insert_square_recip)
-       gsi_insert_before (&gsi, new_square_stmt, GSI_SAME_STMT);
-
       reciprocal_stats.rdivs_inserted++;
 
       occ->recip_def_stmt = new_stmt;
--- gcc/testsuite/gcc.dg/pr86835.c.jj   2018-08-03 13:07:28.834159126 +0200
+++ gcc/testsuite/gcc.dg/pr86835.c      2018-08-03 13:07:14.119126559 +0200
@@ -0,0 +1,29 @@
+/* PR tree-optimization/86835 */
+/* { dg-do run } */
+/* { dg-options "-O2 -ffast-math -Wuninitialized" } */
+
+__attribute__((noipa)) void
+foo (int n, double *x, double *y)
+{              /* { dg-bogus "is used uninitialized in this function" "" { 
target *-*-* } 0 } */
+  int i;
+  double b = y[4];
+  for (i = 0; i < n; ++i)
+    y[3] += __builtin_sin (x[i] / b);
+  y[0] /= b;
+  y[1] /= b * b;
+  y[2] /= b;
+}
+
+int
+main ()
+{
+  double y[] = { 16.0, 64.0, 128.0, 0.0, 2.0 };
+  foo (0, y, y);
+  if (__builtin_fabs (y[0] - 8.0) > 0.0001
+      || __builtin_fabs (y[1] - 16.0) > 0.0001
+      || __builtin_fabs (y[2] - 64.0) > 0.0001
+      || y[3] != 0.0
+      || y[4] != 2.0)
+    __builtin_abort ();
+  return 0;
+}

        Jakub

Reply via email to