Commit 4db183a2 by Eric Botcazou Committed by Eric Botcazou

re PR tree-optimization/44683 (Optimization bug with copysign builtin)

	* fold-const.c (invert_tree_comparison): Always invert EQ_EXPR/NE_EXPR.

	PR tree-optimization/44683
	* tree-ssa-dom.c (record_edge_info): Record simple equivalences only if
	we can be sure that there are no signed zeros involved.

From-SVN: r180340
parent d621a5fb
2011-10-23 Eric Botcazou <ebotcazou@adacore.com>
* fold-const.c (invert_tree_comparison): Always invert EQ_EXPR/NE_EXPR.
PR tree-optimization/44683
* tree-ssa-dom.c (record_edge_info): Record simple equivalences only if
we can be sure that there are no signed zeros involved.
2011-10-23 Jan Hubicka <jh@suse.cz> 2011-10-23 Jan Hubicka <jh@suse.cz>
* ipa-inline.c (estimate_badness): Scale up and handle overflows. * ipa-inline.c (estimate_badness): Scale up and handle overflows.
...@@ -2100,15 +2100,14 @@ pedantic_non_lvalue_loc (location_t loc, tree x) ...@@ -2100,15 +2100,14 @@ pedantic_non_lvalue_loc (location_t loc, tree x)
return protected_set_expr_location_unshare (x, loc); return protected_set_expr_location_unshare (x, loc);
} }
/* Given a tree comparison code, return the code that is the logical inverse /* Given a tree comparison code, return the code that is the logical inverse.
of the given code. It is not safe to do this for floating-point It is generally not safe to do this for floating-point comparisons, except
comparisons, except for NE_EXPR and EQ_EXPR, so we receive a machine mode for EQ_EXPR and NE_EXPR, so we return ERROR_MARK in this case. */
as well: if reversing the comparison is unsafe, return ERROR_MARK. */
enum tree_code enum tree_code
invert_tree_comparison (enum tree_code code, bool honor_nans) invert_tree_comparison (enum tree_code code, bool honor_nans)
{ {
if (honor_nans && flag_trapping_math) if (honor_nans && flag_trapping_math && code != EQ_EXPR && code != NE_EXPR)
return ERROR_MARK; return ERROR_MARK;
switch (code) switch (code)
......
...@@ -1610,12 +1610,15 @@ record_edge_info (basic_block bb) ...@@ -1610,12 +1610,15 @@ record_edge_info (basic_block bb)
{ {
tree cond = build2 (code, boolean_type_node, op0, op1); tree cond = build2 (code, boolean_type_node, op0, op1);
tree inverted = invert_truthvalue_loc (loc, cond); tree inverted = invert_truthvalue_loc (loc, cond);
bool can_infer_simple_equiv
= !(HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (op0)))
&& real_zerop (op0));
struct edge_info *edge_info; struct edge_info *edge_info;
edge_info = allocate_edge_info (true_edge); edge_info = allocate_edge_info (true_edge);
record_conditions (edge_info, cond, inverted); record_conditions (edge_info, cond, inverted);
if (code == EQ_EXPR) if (can_infer_simple_equiv && code == EQ_EXPR)
{ {
edge_info->lhs = op1; edge_info->lhs = op1;
edge_info->rhs = op0; edge_info->rhs = op0;
...@@ -1624,7 +1627,7 @@ record_edge_info (basic_block bb) ...@@ -1624,7 +1627,7 @@ record_edge_info (basic_block bb)
edge_info = allocate_edge_info (false_edge); edge_info = allocate_edge_info (false_edge);
record_conditions (edge_info, inverted, cond); record_conditions (edge_info, inverted, cond);
if (TREE_CODE (inverted) == EQ_EXPR) if (can_infer_simple_equiv && TREE_CODE (inverted) == EQ_EXPR)
{ {
edge_info->lhs = op1; edge_info->lhs = op1;
edge_info->rhs = op0; edge_info->rhs = op0;
...@@ -1632,17 +1635,20 @@ record_edge_info (basic_block bb) ...@@ -1632,17 +1635,20 @@ record_edge_info (basic_block bb)
} }
else if (TREE_CODE (op0) == SSA_NAME else if (TREE_CODE (op0) == SSA_NAME
&& (is_gimple_min_invariant (op1) && (TREE_CODE (op1) == SSA_NAME
|| TREE_CODE (op1) == SSA_NAME)) || is_gimple_min_invariant (op1)))
{ {
tree cond = build2 (code, boolean_type_node, op0, op1); tree cond = build2 (code, boolean_type_node, op0, op1);
tree inverted = invert_truthvalue_loc (loc, cond); tree inverted = invert_truthvalue_loc (loc, cond);
bool can_infer_simple_equiv
= !(HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (op1)))
&& (TREE_CODE (op1) == SSA_NAME || real_zerop (op1)));
struct edge_info *edge_info; struct edge_info *edge_info;
edge_info = allocate_edge_info (true_edge); edge_info = allocate_edge_info (true_edge);
record_conditions (edge_info, cond, inverted); record_conditions (edge_info, cond, inverted);
if (code == EQ_EXPR) if (can_infer_simple_equiv && code == EQ_EXPR)
{ {
edge_info->lhs = op0; edge_info->lhs = op0;
edge_info->rhs = op1; edge_info->rhs = op1;
...@@ -1651,7 +1657,7 @@ record_edge_info (basic_block bb) ...@@ -1651,7 +1657,7 @@ record_edge_info (basic_block bb)
edge_info = allocate_edge_info (false_edge); edge_info = allocate_edge_info (false_edge);
record_conditions (edge_info, inverted, cond); record_conditions (edge_info, inverted, cond);
if (TREE_CODE (inverted) == EQ_EXPR) if (can_infer_simple_equiv && TREE_CODE (inverted) == EQ_EXPR)
{ {
edge_info->lhs = op0; edge_info->lhs = op0;
edge_info->rhs = op1; edge_info->rhs = op1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment