diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 38cdb6db00f..ac3dbbc8b1d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2016-02-10 Yuri Rumyantsev + + PR tree-optimization/69652 + * tree-vect-loop.c (optimize_mask_stores): Move declaration of STMT1 + to nested loop, did source re-formatting, skip debug statements, + add check on statement with volatile operand, remove dead scalar + statements. + 2016-02-10 Jakub Jelinek Patrick Palka diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5475bec275a..6eb0aaa74eb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-02-10 Yuri Rumyantsev + + PR tree-optimization/69652 + * gcc.dg/torture/pr69652.c: New test. + 2016-02-10 Jakub Jelinek Patrick Palka diff --git a/gcc/testsuite/gcc.dg/torture/pr69652.c b/gcc/testsuite/gcc.dg/torture/pr69652.c new file mode 100644 index 00000000000..ab7b69842c6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr69652.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ffast-math -ftree-vectorize " } */ +/* { dg-additional-options "-mavx" { target { i?86-*-* x86_64-*-* } } } */ + +void fn1(double **matrix, int column, int row, int n) +{ + int k; + for (k = 0; k < n; k++) + if (matrix[row][k] != matrix[column][k]) + { + matrix[column][k] = -matrix[column][k]; + matrix[row][k] = matrix[row][k] - matrix[column][k]; + } +} diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 976e1923a4c..bbef502db3f 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -6970,7 +6970,7 @@ optimize_mask_stores (struct loop *loop) unsigned i; basic_block bb; gimple_stmt_iterator gsi; - gimple *stmt, *stmt1 = NULL; + gimple *stmt; auto_vec worklist; vect_location = find_loop_location (loop); @@ -7049,6 +7049,8 @@ optimize_mask_stores (struct loop *loop) while (true) { gimple_stmt_iterator gsi_from; + gimple *stmt1 = NULL; + /* Move masked store to STORE_BB. */ last_store = last; gsi = gsi_for_stmt (last); @@ -7065,67 +7067,81 @@ optimize_mask_stores (struct loop *loop) "Move stmt to created bb\n"); dump_gimple_stmt (MSG_NOTE, TDF_SLIM, last, 0); } - /* Move all stored value producers if possible. */ - while (!gsi_end_p (gsi)) - { - tree lhs; - imm_use_iterator imm_iter; - use_operand_p use_p; - bool res; - stmt1 = gsi_stmt (gsi); - /* Do not consider statements writing to memory. */ - if (gimple_vdef (stmt1)) - break; - gsi_from = gsi; - gsi_prev (&gsi); - lhs = gimple_get_lhs (stmt1); - if (!lhs) - break; + /* Move all stored value producers if possible. */ + while (!gsi_end_p (gsi)) + { + tree lhs; + imm_use_iterator imm_iter; + use_operand_p use_p; + bool res; - /* LHS of vectorized stmt must be SSA_NAME. */ - if (TREE_CODE (lhs) != SSA_NAME) - break; + /* Skip debug statements. */ + if (is_gimple_debug (gsi_stmt (gsi))) + continue; + stmt1 = gsi_stmt (gsi); + /* Do not consider statements writing to memory or having + volatile operand. */ + if (gimple_vdef (stmt1) + || gimple_has_volatile_ops (stmt1)) + break; + gsi_from = gsi; + gsi_prev (&gsi); + lhs = gimple_get_lhs (stmt1); + if (!lhs) + break; - /* Skip scalar statements. */ - if (!VECTOR_TYPE_P (TREE_TYPE (lhs))) - continue; + /* LHS of vectorized stmt must be SSA_NAME. */ + if (TREE_CODE (lhs) != SSA_NAME) + break; - /* Check that LHS does not have uses outside of STORE_BB. */ - res = true; - FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs) - { - gimple *use_stmt; - use_stmt = USE_STMT (use_p); - if (gimple_bb (use_stmt) != store_bb) - { - res = false; - break; - } - } - if (!res) - break; + if (!VECTOR_TYPE_P (TREE_TYPE (lhs))) + { + /* Remove dead scalar statement. */ + if (has_zero_uses (lhs)) + { + gsi_remove (&gsi_from, true); + continue; + } + } - if (gimple_vuse (stmt1) - && gimple_vuse (stmt1) != gimple_vuse (last_store)) - break; + /* Check that LHS does not have uses outside of STORE_BB. */ + res = true; + FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs) + { + gimple *use_stmt; + use_stmt = USE_STMT (use_p); + if (is_gimple_debug (use_stmt)) + continue; + if (gimple_bb (use_stmt) != store_bb) + { + res = false; + break; + } + } + if (!res) + break; - /* Can move STMT1 to STORE_BB. */ - if (dump_enabled_p ()) - { - dump_printf_loc (MSG_NOTE, vect_location, - "Move stmt to created bb\n"); - dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt1, 0); - } - gsi_move_before (&gsi_from, &gsi_to); - /* Shift GSI_TO for further insertion. */ - gsi_prev (&gsi_to); - } - /* Put other masked stores with the same mask to STORE_BB. */ - if (worklist.is_empty () - || gimple_call_arg (worklist.last (), 2) != mask - || worklist.last () != stmt1) - break; - last = worklist.pop (); + if (gimple_vuse (stmt1) + && gimple_vuse (stmt1) != gimple_vuse (last_store)) + break; + + /* Can move STMT1 to STORE_BB. */ + if (dump_enabled_p ()) + { + dump_printf_loc (MSG_NOTE, vect_location, + "Move stmt to created bb\n"); + dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt1, 0); + } + gsi_move_before (&gsi_from, &gsi_to); + /* Shift GSI_TO for further insertion. */ + gsi_prev (&gsi_to); + } + /* Put other masked stores with the same mask to STORE_BB. */ + if (worklist.is_empty () + || gimple_call_arg (worklist.last (), 2) != mask + || worklist.last () != stmt1) + break; + last = worklist.pop (); } add_phi_arg (phi, gimple_vuse (last_store), e, UNKNOWN_LOCATION); }