From 6758b11cdbe147d35f40049e3d31716c7c22e255 Mon Sep 17 00:00:00 2001 From: rguenth Date: Thu, 15 Jun 2006 18:55:18 +0000 Subject: [PATCH] 2006-06-15 Richard Guenther * fold-const.c (fold_truth_not_expr): Rename from invert_truthvalue. Give it fold_* semantics to avoid generating garbage. (invert_truthvalue): New function. Wrapper around fold_truth_not_expr. (optimize_minmax_comparison): Avoid creating garbage. (fold_unary): Use fold_truth_not_expr for folding TRUTH_NOT_EXPR. (fold_ternary): Replace uses of invert_truthvalue with fold_truth_not_expr where applicable. * tree.h (fold_truth_not_expr): Prototype. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@114683 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 14 +++++++++++ gcc/fold-const.c | 74 +++++++++++++++++++++++++++++++++----------------------- gcc/tree.h | 1 + 3 files changed, 59 insertions(+), 30 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3fffbff..13d07af 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2006-06-15 Richard Guenther + + * fold-const.c (fold_truth_not_expr): Rename from + invert_truthvalue. Give it fold_* semantics to avoid + generating garbage. + (invert_truthvalue): New function. Wrapper around + fold_truth_not_expr. + (optimize_minmax_comparison): Avoid creating garbage. + (fold_unary): Use fold_truth_not_expr for folding + TRUTH_NOT_EXPR. + (fold_ternary): Replace uses of invert_truthvalue with + fold_truth_not_expr where applicable. + * tree.h (fold_truth_not_expr): Prototype. + 2006-06-16 Richard Guenther PR tree-optimization/27781 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 5bf3ade..6522afd 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -3049,15 +3049,13 @@ omit_two_operands (tree type, tree result, tree omitted1, tree omitted2) FIXME: one would think we would fold the result, but it causes problems with the dominator optimizer. */ + tree -invert_truthvalue (tree arg) +fold_truth_not_expr (tree arg) { tree type = TREE_TYPE (arg); enum tree_code code = TREE_CODE (arg); - if (code == ERROR_MARK) - return arg; - /* If this is a comparison, we can simply invert it, except for floating-point non-equality comparisons, in which case we just enclose a TRUTH_NOT_EXPR around what we have. */ @@ -3069,13 +3067,13 @@ invert_truthvalue (tree arg) && flag_trapping_math && code != ORDERED_EXPR && code != UNORDERED_EXPR && code != NE_EXPR && code != EQ_EXPR) - return build1 (TRUTH_NOT_EXPR, type, arg); + return NULL_TREE; else { code = invert_tree_comparison (code, HONOR_NANS (TYPE_MODE (op_type))); if (code == ERROR_MARK) - return build1 (TRUTH_NOT_EXPR, type, arg); + return NULL_TREE; else return build2 (code, type, TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1)); @@ -3147,7 +3145,7 @@ invert_truthvalue (tree arg) case NOP_EXPR: if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE) - break; + return build1 (TRUTH_NOT_EXPR, type, arg); case CONVERT_EXPR: case FLOAT_EXPR: @@ -3170,8 +3168,30 @@ invert_truthvalue (tree arg) default: break; } - gcc_assert (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE); - return build1 (TRUTH_NOT_EXPR, type, arg); + + return NULL_TREE; +} + +/* Return a simplified tree node for the truth-negation of ARG. This + never alters ARG itself. We assume that ARG is an operation that + returns a truth value (0 or 1). + + FIXME: one would think we would fold the result, but it causes + problems with the dominator optimizer. */ + +tree +invert_truthvalue (tree arg) +{ + tree tem; + + if (TREE_CODE (arg) == ERROR_MARK) + return arg; + + tem = fold_truth_not_expr (arg); + if (!tem) + tem = build1 (TRUTH_NOT_EXPR, TREE_TYPE (arg), arg); + + return tem; } /* Given a bit-wise operation CODE applied to ARG0 and ARG1, see if both @@ -5258,15 +5278,11 @@ optimize_minmax_comparison (enum tree_code code, tree type, tree op0, tree op1) { case NE_EXPR: case LT_EXPR: case LE_EXPR: { - /* FIXME: We should be able to invert code without building a - scratch tree node, but doing so would require us to - duplicate a part of invert_truthvalue here. */ - tree tem = invert_truthvalue (build2 (code, type, op0, op1)); - tem = optimize_minmax_comparison (TREE_CODE (tem), - TREE_TYPE (tem), - TREE_OPERAND (tem, 0), - TREE_OPERAND (tem, 1)); - return invert_truthvalue (tem); + tree tem = optimize_minmax_comparison (invert_tree_comparison (code, false), + type, op0, op1); + if (tem) + return invert_truthvalue (tem); + return NULL_TREE; } case GE_EXPR: @@ -7616,9 +7632,8 @@ fold_unary (enum tree_code code, tree type, tree op0) and its values must be 0 or 1. ("true" is a fixed value perhaps depending on the language, but we don't handle values other than 1 correctly yet.) */ - tem = invert_truthvalue (arg0); - /* Avoid infinite recursion. */ - if (TREE_CODE (tem) == TRUTH_NOT_EXPR) + tem = fold_truth_not_expr (arg0); + if (!tem) return NULL_TREE; return fold_convert (type, tem); @@ -11114,8 +11129,8 @@ fold_ternary (enum tree_code code, tree type, tree op0, tree op1, tree op2) TREE_OPERAND (arg0, 1)) && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (op2)))) { - tem = invert_truthvalue (arg0); - if (COMPARISON_CLASS_P (tem)) + tem = fold_truth_not_expr (arg0); + if (tem && COMPARISON_CLASS_P (tem)) { tem = fold_cond_expr_with_comparison (type, tem, op2, op1); if (tem) @@ -11131,9 +11146,8 @@ fold_ternary (enum tree_code code, tree type, tree op0, tree op1, tree op2) /* See if this can be inverted. If it can't, possibly because it was a floating-point inequality comparison, don't do anything. */ - tem = invert_truthvalue (arg0); - - if (TREE_CODE (tem) != TRUTH_NOT_EXPR) + tem = fold_truth_not_expr (arg0); + if (tem) return fold_build3 (code, type, tem, op2, op1); } @@ -11210,8 +11224,8 @@ fold_ternary (enum tree_code code, tree type, tree op0, tree op1, tree op2) && truth_value_p (TREE_CODE (arg1))) { /* Only perform transformation if ARG0 is easily inverted. */ - tem = invert_truthvalue (arg0); - if (TREE_CODE (tem) != TRUTH_NOT_EXPR) + tem = fold_truth_not_expr (arg0); + if (tem) return fold_build2 (TRUTH_ORIF_EXPR, type, fold_convert (type, tem), arg1); @@ -11223,8 +11237,8 @@ fold_ternary (enum tree_code code, tree type, tree op0, tree op1, tree op2) && truth_value_p (TREE_CODE (op2))) { /* Only perform transformation if ARG0 is easily inverted. */ - tem = invert_truthvalue (arg0); - if (TREE_CODE (tem) != TRUTH_NOT_EXPR) + tem = fold_truth_not_expr (arg0); + if (tem) return fold_build2 (TRUTH_ANDIF_EXPR, type, fold_convert (type, tem), op2); diff --git a/gcc/tree.h b/gcc/tree.h index 9c11818..ad21877 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -4208,6 +4208,7 @@ extern int operand_equal_p (tree, tree, unsigned int); extern tree omit_one_operand (tree, tree, tree); extern tree omit_two_operands (tree, tree, tree, tree); extern tree invert_truthvalue (tree); +extern tree fold_truth_not_expr (tree); extern tree fold_unary_to_constant (enum tree_code, tree, tree); extern tree fold_binary_to_constant (enum tree_code, tree, tree, tree); extern tree fold_read_from_constant_string (tree); -- 2.7.4