From 5f84eb27a0a4f90914fab1d0068ae586fb763bde Mon Sep 17 00:00:00 2001 From: Wilco Dijkstra Date: Wed, 20 Dec 2017 23:55:42 +0000 Subject: [PATCH] re PR tree-optimization/83491 (ICE in execute_cse_reciprocals_1 at gcc/tree-ssa-math-opts.c:585) PR tree-optimization/83491 * tree-ssa-math-opts.c (execute_cse_reciprocals_1): Check for SSA_NAME before walking uses. Improve coding style and comments. PR tree-optimization/83491 * gcc.dg/pr83491.c: Add new test. From-SVN: r255906 --- gcc/ChangeLog | 6 ++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/pr83491.c | 10 +++++++ gcc/tree-ssa-math-opts.c | 55 +++++++++++++++++----------------- 4 files changed, 48 insertions(+), 28 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr83491.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 10451676684..29d32b8bc59 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2017-12-20 Wilco Dijkstra + + PR tree-optimization/83491 + * tree-ssa-math-opts.c (execute_cse_reciprocals_1): Check for SSA_NAME + before walking uses. Improve coding style and comments. + 2017-12-20 Tom de Vries * gimple-fold.c (fold_internal_goacc_dim): Simplify. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9f564ade9ce..54f15f1c4bd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-12-20 Wilco Dijkstra + + PR tree-optimization/83491 + * gcc.dg/pr83491.c: Add new test. + 2017-12-20 Thomas Koenig PR fortran/83436 diff --git a/gcc/testsuite/gcc.dg/pr83491.c b/gcc/testsuite/gcc.dg/pr83491.c new file mode 100644 index 00000000000..f23cc19c72f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr83491.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -funsafe-math-optimizations" } */ + +float a; +float b; +void bar () +{ + a = __builtin_nanf (""); + b = __builtin_powf (a, 2.5F); +} diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index 8db12f5e1cd..4e8f5e728d0 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -544,29 +544,32 @@ execute_cse_reciprocals_1 (gimple_stmt_iterator *def_gsi, tree def) int square_recip_count = 0; int sqrt_recip_count = 0; - gcc_assert (FLOAT_TYPE_P (TREE_TYPE (def)) && is_gimple_reg (def)); + gcc_assert (FLOAT_TYPE_P (TREE_TYPE (def)) && is_gimple_reg (def) + && TREE_CODE (def) == SSA_NAME); threshold = targetm.min_divisions_for_recip_mul (TYPE_MODE (TREE_TYPE (def))); - /* If this is a square (x * x), we should check whether there are any - enough divisions by x on it's own to warrant waiting for that pass. */ - if (TREE_CODE (def) == SSA_NAME) + /* If DEF is a square (x * x), count the number of divisions by x. + If there are more divisions by x than by (DEF * DEF), prefer to optimize + the reciprocal of x instead of DEF. This improves cases like: + def = x * x + t0 = a / def + t1 = b / def + t2 = c / x + Reciprocal optimization of x results in 1 division rather than 2 or 3. */ + gimple *def_stmt = SSA_NAME_DEF_STMT (def); + + if (is_gimple_assign (def_stmt) + && gimple_assign_rhs_code (def_stmt) == MULT_EXPR + && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME + && gimple_assign_rhs1 (def_stmt) == gimple_assign_rhs2 (def_stmt)) { - gimple *def_stmt = SSA_NAME_DEF_STMT (def); + tree op0 = gimple_assign_rhs1 (def_stmt); - if (is_gimple_assign (def_stmt) - && gimple_assign_rhs_code (def_stmt) == MULT_EXPR - && gimple_assign_rhs1 (def_stmt) == gimple_assign_rhs2 (def_stmt)) + FOR_EACH_IMM_USE_FAST (use_p, use_iter, op0) { - /* This statement is a square of something. We should take this - in to account, as it may be more profitable to not extract - the reciprocal here. */ - tree op0 = gimple_assign_rhs1 (def_stmt); - FOR_EACH_IMM_USE_FAST (use_p, use_iter, op0) - { - gimple *use_stmt = USE_STMT (use_p); - if (is_division_by (use_stmt, op0)) - sqrt_recip_count ++; - } + gimple *use_stmt = USE_STMT (use_p); + if (is_division_by (use_stmt, op0)) + sqrt_recip_count++; } } @@ -587,26 +590,23 @@ execute_cse_reciprocals_1 (gimple_stmt_iterator *def_gsi, tree def) gimple *square_use_stmt = USE_STMT (square_use_p); if (is_division_by (square_use_stmt, square_def)) { - /* Halve the relative importance as this is called twice - for each division by a square. */ + /* This is executed twice for each division by a square. */ register_division_in (gimple_bb (square_use_stmt), 1); - square_recip_count ++; + square_recip_count++; } } } } - /* Square reciprocals will have been counted twice. */ + /* Square reciprocals were counted twice above. */ square_recip_count /= 2; + /* If it is more profitable to optimize 1 / x, don't optimize 1 / (x * x). */ if (sqrt_recip_count > square_recip_count) - /* It will be more profitable to extract a 1 / x expression later, - so it is not worth attempting to extract 1 / (x * x) now. */ return; /* Do the expensive part only if we can hope to optimize something. */ - if (count + square_recip_count >= threshold - && count >= 1) + if (count + square_recip_count >= threshold && count >= 1) { gimple *use_stmt; for (occ = occ_head; occ; occ = occ->next) @@ -623,8 +623,7 @@ execute_cse_reciprocals_1 (gimple_stmt_iterator *def_gsi, tree def) FOR_EACH_IMM_USE_ON_STMT (use_p, use_iter) replace_reciprocal (use_p); } - else if (square_recip_count > 0 - && is_square_of (use_stmt, def)) + else if (square_recip_count > 0 && is_square_of (use_stmt, def)) { FOR_EACH_IMM_USE_ON_STMT (use_p, use_iter) { -- 2.30.2