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.
This commit is contained in:
parent
6802b5ba82
commit
07852a81f5
3 changed files with 29 additions and 13 deletions
|
@ -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 } } } } }
|
||||
|
|
15
gcc/testsuite/gcc.dg/tree-ssa/phi-opt-21.c
Normal file
15
gcc/testsuite/gcc.dg/tree-ssa/phi-opt-21.c
Normal file
|
@ -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<s, 0>. */
|
||||
/* { dg-final { scan-tree-dump-not "MAX" "phiopt4" } } */
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue