re PR tree-optimization/39874 (missing VRP (submission))

2010-06-08  Sandra Loosemore  <sandra@codesourcery.com>

	PR tree-optimization/39874
	PR middle-end/28685

	gcc/
	* gimple.h (maybe_fold_and_comparisons, maybe_fold_or_comparisons):
	Declare.
	* gimple-fold.c (canonicalize_bool, same_bool_comparison_p,
	same_bool_result_p): New.
	(and_var_with_comparison, and_var_with_comparison_1,
	and_comparisons_1, and_comparisons, maybe_fold_and_comparisons): New.
	(or_var_with_comparison, or_var_with_comparison_1,
	or_comparisons_1, or_comparisons, maybe_fold_or_comparisons): New.
	* tree-ssa-reassoc.c (eliminate_redundant_comparison): Use
	maybe_fold_and_comparisons or maybe_fold_or_comparisons instead
	of combine_comparisons.
	* tree-ssa-ifcombine.c (ifcombine_ifandif, ifcombine_iforif): Likewise.

	gcc/testsuite/
	* gcc.dg/pr39874.c: New file.

From-SVN: r160445
This commit is contained in:
Sandra Loosemore 2010-06-08 14:15:53 -04:00 committed by Sandra Loosemore
parent c547eb0db1
commit e89065a172
7 changed files with 1137 additions and 39 deletions

View File

@ -1,3 +1,20 @@
2010-06-08 Sandra Loosemore <sandra@codesourcery.com>
PR tree-optimization/39874
PR middle-end/28685
* gimple.h (maybe_fold_and_comparisons, maybe_fold_or_comparisons):
Declare.
* gimple-fold.c (canonicalize_bool, same_bool_comparison_p,
same_bool_result_p): New.
(and_var_with_comparison, and_var_with_comparison_1,
and_comparisons_1, and_comparisons, maybe_fold_and_comparisons): New.
(or_var_with_comparison, or_var_with_comparison_1,
or_comparisons_1, or_comparisons, maybe_fold_or_comparisons): New.
* tree-ssa-reassoc.c (eliminate_redundant_comparison): Use
maybe_fold_and_comparisons or maybe_fold_or_comparisons instead
of combine_comparisons.
* tree-ssa-ifcombine.c (ifcombine_ifandif, ifcombine_iforif): Likewise.
2010-06-08 Anatoly Sokolov <aesok@post.ru>
* config/pdp11/pdp11.h (FUNCTION_VALUE, FUNCTION_OUTGOING_VALUE,

File diff suppressed because it is too large Load Diff

View File

@ -4812,6 +4812,9 @@ tree maybe_fold_offset_to_address (location_t, tree, tree, tree);
tree maybe_fold_stmt_addition (location_t, tree, tree, tree);
tree get_symbol_constant_value (tree);
bool may_propagate_address_into_dereference (tree, tree);
extern tree maybe_fold_and_comparisons (enum tree_code, tree, tree,
enum tree_code, tree, tree);
extern tree maybe_fold_or_comparisons (enum tree_code, tree, tree,
enum tree_code, tree, tree);
#endif /* GCC_GIMPLE_H */

View File

@ -1,3 +1,9 @@
2010-06-08 Sandra Loosemore <sandra@codesourcery.com>
PR tree-optimization/39874
PR middle-end/28685
* gcc.dg/pr39874.c: New file.
2010-06-08 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/ext/attr-alias-1.C: New.

View File

@ -0,0 +1,29 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
extern void func();
void test1(char *signature)
{
char ch = signature[0];
if (ch == 15 || ch == 3)
{
if (ch == 15) func();
}
}
void test2(char *signature)
{
char ch = signature[0];
if (ch == 15 || ch == 3)
{
if (ch > 14) func();
}
}
/* { dg-final { scan-tree-dump-times " == 15" 2 "optimized" } } */
/* { dg-final { scan-tree-dump-not " == 3" "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */

View File

@ -366,21 +366,16 @@ ifcombine_ifandif (basic_block inner_cond_bb, basic_block outer_cond_bb)
/* See if we have two comparisons that we can merge into one. */
else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
&& TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison
&& operand_equal_p (gimple_cond_lhs (inner_cond),
gimple_cond_lhs (outer_cond), 0)
&& operand_equal_p (gimple_cond_rhs (inner_cond),
gimple_cond_rhs (outer_cond), 0))
&& TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison)
{
enum tree_code code1 = gimple_cond_code (inner_cond);
enum tree_code code2 = gimple_cond_code (outer_cond);
tree t;
if (!(t = combine_comparisons (UNKNOWN_LOCATION,
TRUTH_ANDIF_EXPR, code1, code2,
boolean_type_node,
gimple_cond_lhs (outer_cond),
gimple_cond_rhs (outer_cond))))
if (!(t = maybe_fold_and_comparisons (gimple_cond_code (inner_cond),
gimple_cond_lhs (inner_cond),
gimple_cond_rhs (inner_cond),
gimple_cond_code (outer_cond),
gimple_cond_lhs (outer_cond),
gimple_cond_rhs (outer_cond))))
return false;
t = canonicalize_cond_expr_cond (t);
if (!t)
@ -518,22 +513,17 @@ ifcombine_iforif (basic_block inner_cond_bb, basic_block outer_cond_bb)
/* See if we have two comparisons that we can merge into one.
This happens for C++ operator overloading where for example
GE_EXPR is implemented as GT_EXPR || EQ_EXPR. */
else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
&& TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison
&& operand_equal_p (gimple_cond_lhs (inner_cond),
gimple_cond_lhs (outer_cond), 0)
&& operand_equal_p (gimple_cond_rhs (inner_cond),
gimple_cond_rhs (outer_cond), 0))
else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
&& TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison)
{
enum tree_code code1 = gimple_cond_code (inner_cond);
enum tree_code code2 = gimple_cond_code (outer_cond);
tree t;
if (!(t = combine_comparisons (UNKNOWN_LOCATION,
TRUTH_ORIF_EXPR, code1, code2,
boolean_type_node,
gimple_cond_lhs (outer_cond),
gimple_cond_rhs (outer_cond))))
if (!(t = maybe_fold_or_comparisons (gimple_cond_code (inner_cond),
gimple_cond_lhs (inner_cond),
gimple_cond_rhs (inner_cond),
gimple_cond_code (outer_cond),
gimple_cond_lhs (outer_cond),
gimple_cond_rhs (outer_cond))))
return false;
t = canonicalize_cond_expr_cond (t);
if (!t)

View File

@ -1261,23 +1261,27 @@ eliminate_redundant_comparison (enum tree_code opcode,
rcode = gimple_assign_rhs_code (def2);
if (TREE_CODE_CLASS (rcode) != tcc_comparison)
continue;
if (operand_equal_p (op1, gimple_assign_rhs1 (def2), 0)
&& operand_equal_p (op2, gimple_assign_rhs2 (def2), 0))
;
else if (operand_equal_p (op1, gimple_assign_rhs2 (def2), 0)
&& operand_equal_p (op2, gimple_assign_rhs1 (def2), 0))
rcode = swap_tree_comparison (rcode);
else
continue;
/* If we got here, we have a match. See if we can combine the
two comparisons. */
t = combine_comparisons (UNKNOWN_LOCATION,
(opcode == BIT_IOR_EXPR
? TRUTH_OR_EXPR : TRUTH_AND_EXPR),
lcode, rcode, TREE_TYPE (curr->op), op1, op2);
if (opcode == BIT_IOR_EXPR)
t = maybe_fold_or_comparisons (lcode, op1, op2,
rcode, gimple_assign_rhs1 (def2),
gimple_assign_rhs2 (def2));
else
t = maybe_fold_and_comparisons (lcode, op1, op2,
rcode, gimple_assign_rhs1 (def2),
gimple_assign_rhs2 (def2));
if (!t)
continue;
/* maybe_fold_and_comparisons and maybe_fold_or_comparisons
always give us a boolean_type_node value back. If the original
BIT_AND_EXPR or BIT_IOR_EXPR was of a wider integer type,
we need to convert. */
if (!useless_type_conversion_p (TREE_TYPE (curr->op), TREE_TYPE (t)))
t = fold_convert (TREE_TYPE (curr->op), t);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Equivalence: ");
@ -1303,7 +1307,7 @@ eliminate_redundant_comparison (enum tree_code opcode,
VEC_ordered_remove (operand_entry_t, *ops, currindex);
add_to_ops_vec (ops, t);
}
else if (TREE_CODE (t) != lcode)
else if (!operand_equal_p (t, curr->op, 0))
{
tree tmpvar;
gimple sum;