re PR tree-optimization/56365 (Missed opportunities for smin/smax standard name patterns when compiling as C++)
2016-03-14 Richard Biener <rguenther@suse.de> PR tree-optimization/56365 * tree-ssa-phiopt.c (minmax_replacement): Handle alternate constants to compare against. * gcc.dg/tree-ssa/phi-opt-14.c: New testcase. From-SVN: r234183
This commit is contained in:
parent
4799603f1a
commit
a9fee7cdc3
@ -1,3 +1,9 @@
|
||||
2016-03-14 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/56365
|
||||
* tree-ssa-phiopt.c (minmax_replacement): Handle alternate
|
||||
constants to compare against.
|
||||
|
||||
2016-03-14 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
|
||||
PR target/70098
|
||||
|
@ -1,3 +1,8 @@
|
||||
2016-03-14 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/56365
|
||||
* gcc.dg/tree-ssa/phi-opt-14.c: New testcase.
|
||||
|
||||
2016-03-14 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
|
||||
PR target/70098
|
||||
|
37
gcc/testsuite/gcc.dg/tree-ssa/phi-opt-14.c
Normal file
37
gcc/testsuite/gcc.dg/tree-ssa/phi-opt-14.c
Normal file
@ -0,0 +1,37 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O -fdump-tree-phiopt1" } */
|
||||
|
||||
int test_01 (int a)
|
||||
{
|
||||
if (127 <= a)
|
||||
a = 127;
|
||||
else if (a <= -128)
|
||||
a = -128;
|
||||
return a;
|
||||
}
|
||||
int test_02 (int a)
|
||||
{
|
||||
if (127 < a)
|
||||
a = 127;
|
||||
else if (a <= -128)
|
||||
a = -128;
|
||||
return a;
|
||||
}
|
||||
int test_03 (int a)
|
||||
{
|
||||
if (127 <= a)
|
||||
a = 127;
|
||||
else if (a < -128)
|
||||
a = -128;
|
||||
return a;
|
||||
}
|
||||
int test_04 (int a)
|
||||
{
|
||||
if (127 < a)
|
||||
a = 127;
|
||||
else if (a < -128)
|
||||
a = -128;
|
||||
return a;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-not "if" "phiopt1" } } */
|
@ -1045,7 +1045,7 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
|
||||
gassign *new_stmt;
|
||||
edge true_edge, false_edge;
|
||||
enum tree_code cmp, minmax, ass_code;
|
||||
tree smaller, larger, arg_true, arg_false;
|
||||
tree smaller, alt_smaller, larger, alt_larger, arg_true, arg_false;
|
||||
gimple_stmt_iterator gsi, gsi_from;
|
||||
|
||||
type = TREE_TYPE (PHI_RESULT (phi));
|
||||
@ -1059,15 +1059,59 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
|
||||
|
||||
/* This transformation is only valid for order comparisons. Record which
|
||||
operand is smaller/larger if the result of the comparison is true. */
|
||||
alt_smaller = NULL_TREE;
|
||||
alt_larger = NULL_TREE;
|
||||
if (cmp == LT_EXPR || cmp == LE_EXPR)
|
||||
{
|
||||
smaller = gimple_cond_lhs (cond);
|
||||
larger = gimple_cond_rhs (cond);
|
||||
/* If we have smaller < CST it is equivalent to smaller <= CST-1.
|
||||
Likewise smaller <= CST is equivalent to smaller < CST+1. */
|
||||
if (TREE_CODE (larger) == INTEGER_CST)
|
||||
{
|
||||
if (cmp == LT_EXPR)
|
||||
{
|
||||
bool overflow;
|
||||
wide_int alt = wi::sub (larger, 1, TYPE_SIGN (TREE_TYPE (larger)),
|
||||
&overflow);
|
||||
if (! overflow)
|
||||
alt_larger = wide_int_to_tree (TREE_TYPE (larger), alt);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool overflow;
|
||||
wide_int alt = wi::add (larger, 1, TYPE_SIGN (TREE_TYPE (larger)),
|
||||
&overflow);
|
||||
if (! overflow)
|
||||
alt_larger = wide_int_to_tree (TREE_TYPE (larger), alt);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (cmp == GT_EXPR || cmp == GE_EXPR)
|
||||
{
|
||||
smaller = gimple_cond_rhs (cond);
|
||||
larger = gimple_cond_lhs (cond);
|
||||
/* If we have larger > CST it is equivalent to larger >= CST+1.
|
||||
Likewise larger >= CST is equivalent to larger > CST-1. */
|
||||
if (TREE_CODE (smaller) == INTEGER_CST)
|
||||
{
|
||||
if (cmp == GT_EXPR)
|
||||
{
|
||||
bool overflow;
|
||||
wide_int alt = wi::add (smaller, 1, TYPE_SIGN (TREE_TYPE (smaller)),
|
||||
&overflow);
|
||||
if (! overflow)
|
||||
alt_smaller = wide_int_to_tree (TREE_TYPE (smaller), alt);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool overflow;
|
||||
wide_int alt = wi::sub (smaller, 1, TYPE_SIGN (TREE_TYPE (smaller)),
|
||||
&overflow);
|
||||
if (! overflow)
|
||||
alt_smaller = wide_int_to_tree (TREE_TYPE (smaller), alt);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
@ -1098,8 +1142,12 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
|
||||
|
||||
if (empty_block_p (middle_bb))
|
||||
{
|
||||
if (operand_equal_for_phi_arg_p (arg_true, smaller)
|
||||
&& operand_equal_for_phi_arg_p (arg_false, larger))
|
||||
if ((operand_equal_for_phi_arg_p (arg_true, smaller)
|
||||
|| (alt_smaller
|
||||
&& operand_equal_for_phi_arg_p (arg_true, alt_smaller)))
|
||||
&& (operand_equal_for_phi_arg_p (arg_false, larger)
|
||||
|| (alt_larger
|
||||
&& operand_equal_for_phi_arg_p (arg_true, alt_larger))))
|
||||
{
|
||||
/* Case
|
||||
|
||||
@ -1109,8 +1157,12 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
|
||||
rslt = larger; */
|
||||
minmax = MIN_EXPR;
|
||||
}
|
||||
else if (operand_equal_for_phi_arg_p (arg_false, smaller)
|
||||
&& operand_equal_for_phi_arg_p (arg_true, larger))
|
||||
else if ((operand_equal_for_phi_arg_p (arg_false, smaller)
|
||||
|| (alt_smaller
|
||||
&& operand_equal_for_phi_arg_p (arg_false, alt_smaller)))
|
||||
&& (operand_equal_for_phi_arg_p (arg_true, larger)
|
||||
|| (alt_larger
|
||||
&& operand_equal_for_phi_arg_p (arg_true, alt_larger))))
|
||||
minmax = MAX_EXPR;
|
||||
else
|
||||
return false;
|
||||
@ -1148,7 +1200,9 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
|
||||
if (!operand_equal_for_phi_arg_p (lhs, arg_true))
|
||||
return false;
|
||||
|
||||
if (operand_equal_for_phi_arg_p (arg_false, larger))
|
||||
if (operand_equal_for_phi_arg_p (arg_false, larger)
|
||||
|| (alt_larger
|
||||
&& operand_equal_for_phi_arg_p (arg_false, alt_larger)))
|
||||
{
|
||||
/* Case
|
||||
|
||||
@ -1161,9 +1215,13 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
|
||||
return false;
|
||||
|
||||
minmax = MIN_EXPR;
|
||||
if (operand_equal_for_phi_arg_p (op0, smaller))
|
||||
if (operand_equal_for_phi_arg_p (op0, smaller)
|
||||
|| (alt_smaller
|
||||
&& operand_equal_for_phi_arg_p (op0, alt_smaller)))
|
||||
bound = op1;
|
||||
else if (operand_equal_for_phi_arg_p (op1, smaller))
|
||||
else if (operand_equal_for_phi_arg_p (op1, smaller)
|
||||
|| (alt_smaller
|
||||
&& operand_equal_for_phi_arg_p (op1, alt_smaller)))
|
||||
bound = op0;
|
||||
else
|
||||
return false;
|
||||
@ -1173,7 +1231,9 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
|
||||
bound, larger)))
|
||||
return false;
|
||||
}
|
||||
else if (operand_equal_for_phi_arg_p (arg_false, smaller))
|
||||
else if (operand_equal_for_phi_arg_p (arg_false, smaller)
|
||||
|| (alt_smaller
|
||||
&& operand_equal_for_phi_arg_p (arg_false, alt_smaller)))
|
||||
{
|
||||
/* Case
|
||||
|
||||
@ -1186,9 +1246,13 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
|
||||
return false;
|
||||
|
||||
minmax = MAX_EXPR;
|
||||
if (operand_equal_for_phi_arg_p (op0, larger))
|
||||
if (operand_equal_for_phi_arg_p (op0, larger)
|
||||
|| (alt_larger
|
||||
&& operand_equal_for_phi_arg_p (op0, alt_larger)))
|
||||
bound = op1;
|
||||
else if (operand_equal_for_phi_arg_p (op1, larger))
|
||||
else if (operand_equal_for_phi_arg_p (op1, larger)
|
||||
|| (alt_larger
|
||||
&& operand_equal_for_phi_arg_p (op1, alt_larger)))
|
||||
bound = op0;
|
||||
else
|
||||
return false;
|
||||
@ -1207,7 +1271,9 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
|
||||
if (!operand_equal_for_phi_arg_p (lhs, arg_false))
|
||||
return false;
|
||||
|
||||
if (operand_equal_for_phi_arg_p (arg_true, larger))
|
||||
if (operand_equal_for_phi_arg_p (arg_true, larger)
|
||||
|| (alt_larger
|
||||
&& operand_equal_for_phi_arg_p (arg_true, alt_larger)))
|
||||
{
|
||||
/* Case
|
||||
|
||||
@ -1220,9 +1286,13 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
|
||||
return false;
|
||||
|
||||
minmax = MAX_EXPR;
|
||||
if (operand_equal_for_phi_arg_p (op0, smaller))
|
||||
if (operand_equal_for_phi_arg_p (op0, smaller)
|
||||
|| (alt_smaller
|
||||
&& operand_equal_for_phi_arg_p (op0, alt_smaller)))
|
||||
bound = op1;
|
||||
else if (operand_equal_for_phi_arg_p (op1, smaller))
|
||||
else if (operand_equal_for_phi_arg_p (op1, smaller)
|
||||
|| (alt_smaller
|
||||
&& operand_equal_for_phi_arg_p (op1, alt_smaller)))
|
||||
bound = op0;
|
||||
else
|
||||
return false;
|
||||
@ -1232,7 +1302,9 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
|
||||
bound, larger)))
|
||||
return false;
|
||||
}
|
||||
else if (operand_equal_for_phi_arg_p (arg_true, smaller))
|
||||
else if (operand_equal_for_phi_arg_p (arg_true, smaller)
|
||||
|| (alt_smaller
|
||||
&& operand_equal_for_phi_arg_p (arg_true, alt_smaller)))
|
||||
{
|
||||
/* Case
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user