From 07852a81f58532c63a57631d7c3757fc6bcea17d Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 29 May 2020 09:25:53 +0200 Subject: [PATCH] tree-optimization/95393 - fold MIN/MAX_EXPR generated by phiopt This makes sure to fold generated stmts so they do not survive until RTL expansion and cause awkward code generation. 2020-05-29 Richard Biener PR tree-optimization/95393 * tree-ssa-phiopt.c (minmax_replacement): Use gimple_build to build the min/max expression so we simplify cases like MAX(0, s) immediately. * gcc.dg/tree-ssa/phi-opt-21.c: New testcase. * g++.dg/vect/slp-pr87105.cc: Adjust. --- gcc/testsuite/g++.dg/vect/slp-pr87105.cc | 2 +- gcc/testsuite/gcc.dg/tree-ssa/phi-opt-21.c | 15 +++++++++++++ gcc/tree-ssa-phiopt.c | 25 +++++++++++----------- 3 files changed, 29 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-21.c diff --git a/gcc/testsuite/g++.dg/vect/slp-pr87105.cc b/gcc/testsuite/g++.dg/vect/slp-pr87105.cc index 5518f319be3..d07b1cd46b7 100644 --- a/gcc/testsuite/g++.dg/vect/slp-pr87105.cc +++ b/gcc/testsuite/g++.dg/vect/slp-pr87105.cc @@ -102,4 +102,4 @@ void quadBoundingBoxA(const Point bez[3], Box& bBox) noexcept { // { dg-final { scan-tree-dump-times "basic block part vectorized" 1 "slp2" { xfail { { ! vect_element_align } && { ! vect_hw_misalign } } } } } // It's a bit awkward to detect that all stores were vectorized but the // following more or less does the trick -// { dg-final { scan-tree-dump "vect_iftmp\[^\r\m\]* = MIN" "slp2" { xfail { { ! vect_element_align } && { ! vect_hw_misalign } } } } } +// { dg-final { scan-tree-dump "vect_\[^\r\m\]* = MIN" "slp2" { xfail { { ! vect_element_align } && { ! vect_hw_misalign } } } } } diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-21.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-21.c new file mode 100644 index 00000000000..9f3d5695728 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-21.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-phiopt4-details" } */ + +int f(unsigned s) +{ + int i; + for (i = 0; i < s; ++i) + ; + + return i; +} + +/* { dg-final { scan-tree-dump "converted to straightline code" "phiopt4" } } */ +/* Make sure we fold the detected MAX. */ +/* { dg-final { scan-tree-dump-not "MAX" "phiopt4" } } */ diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index b1e0dce93d8..bb97dcf63b4 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-inline.h" #include "case-cfn-macros.h" #include "tree-eh.h" +#include "gimple-fold.h" static unsigned int tree_ssa_phiopt_worker (bool, bool, bool); static bool two_value_replacement (basic_block, basic_block, edge, gphi *, @@ -1364,7 +1365,6 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, { tree result, type, rhs; gcond *cond; - gassign *new_stmt; edge true_edge, false_edge; enum tree_code cmp, minmax, ass_code; tree smaller, alt_smaller, larger, alt_larger, arg_true, arg_false; @@ -1688,19 +1688,20 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb, gsi_move_before (&gsi_from, &gsi); } - /* Create an SSA var to hold the min/max result. If we're the only - things setting the target PHI, then we can clone the PHI - variable. Otherwise we must create a new one. */ - result = PHI_RESULT (phi); - if (EDGE_COUNT (gimple_bb (phi)->preds) == 2) - result = duplicate_ssa_name (result, NULL); - else - result = make_ssa_name (TREE_TYPE (result)); - /* Emit the statement to compute min/max. */ - new_stmt = gimple_build_assign (result, minmax, arg0, arg1); + gimple_seq stmts = NULL; + tree phi_result = PHI_RESULT (phi); + result = gimple_build (&stmts, minmax, TREE_TYPE (phi_result), arg0, arg1); + /* Duplicate range info if we're the only things setting the target PHI. */ + if (!gimple_seq_empty_p (stmts) + && EDGE_COUNT (gimple_bb (phi)->preds) == 2 + && !POINTER_TYPE_P (TREE_TYPE (phi_result)) + && SSA_NAME_RANGE_INFO (phi_result)) + duplicate_ssa_name_range_info (result, SSA_NAME_RANGE_TYPE (phi_result), + SSA_NAME_RANGE_INFO (phi_result)); + gsi = gsi_last_bb (cond_bb); - gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT); + gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT); replace_phi_edge_with_variable (cond_bb, e1, phi, result); -- 2.30.2