From: Eric Botcazou Date: Sun, 23 Oct 2011 15:57:09 +0000 (+0000) Subject: re PR tree-optimization/44683 (Optimization bug with copysign builtin) X-Git-Tag: releases/gcc-4.7.0~2892 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4db183a2d5c98d60144b88dcf402f06fc2103200;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2602f76c41fe..e9b48cbecf3f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2011-10-23 Eric Botcazou + + * 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 * ipa-inline.c (estimate_badness): Scale up and handle overflows. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index a838c3458819..e4c258903f76 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -2100,15 +2100,14 @@ pedantic_non_lvalue_loc (location_t loc, tree x) return protected_set_expr_location_unshare (x, loc); } -/* 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 - comparisons, except for NE_EXPR and EQ_EXPR, so we receive a machine mode - as well: if reversing the comparison is unsafe, return ERROR_MARK. */ +/* Given a tree comparison code, return the code that is the logical inverse. + It is generally not safe to do this for floating-point comparisons, except + for EQ_EXPR and NE_EXPR, so we return ERROR_MARK in this case. */ enum tree_code 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; switch (code) diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index 8bfc91aae4f9..949acf1d1682 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -1610,12 +1610,15 @@ record_edge_info (basic_block bb) { tree cond = build2 (code, boolean_type_node, op0, op1); 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; edge_info = allocate_edge_info (true_edge); record_conditions (edge_info, cond, inverted); - if (code == EQ_EXPR) + if (can_infer_simple_equiv && code == EQ_EXPR) { edge_info->lhs = op1; edge_info->rhs = op0; @@ -1624,7 +1627,7 @@ record_edge_info (basic_block bb) edge_info = allocate_edge_info (false_edge); 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->rhs = op0; @@ -1632,17 +1635,20 @@ record_edge_info (basic_block bb) } 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 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; edge_info = allocate_edge_info (true_edge); record_conditions (edge_info, cond, inverted); - if (code == EQ_EXPR) + if (can_infer_simple_equiv && code == EQ_EXPR) { edge_info->lhs = op0; edge_info->rhs = op1; @@ -1651,7 +1657,7 @@ record_edge_info (basic_block bb) edge_info = allocate_edge_info (false_edge); 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->rhs = op1;