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