diff options
author | Richard Biener <rguenther@suse.de> | 2020-05-29 09:25:53 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2020-05-29 10:15:57 +0200 |
commit | 07852a81f58532c63a57631d7c3757fc6bcea17d (patch) | |
tree | 225cd9b44de4288c2213b9155b4a9770aef011fe /gcc/tree-ssa-phiopt.c | |
parent | 6802b5ba8234427598abfd9f0163eb5e7c0d6aa8 (diff) | |
download | gcc-07852a81f58532c63a57631d7c3757fc6bcea17d.zip gcc-07852a81f58532c63a57631d7c3757fc6bcea17d.tar.gz gcc-07852a81f58532c63a57631d7c3757fc6bcea17d.tar.bz2 |
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 <rguenther@suse.de>
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.
Diffstat (limited to 'gcc/tree-ssa-phiopt.c')
-rw-r--r-- | gcc/tree-ssa-phiopt.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index b1e0dce..bb97dcf6 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); |