From adb8e07e68e65f801a4fafc491c55dfe30af66ed Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Mon, 19 Jul 2004 12:45:44 +0000 Subject: [PATCH] fold-const.c (tree_expr_nonzero_p): Add function prototype. * fold-const.c (tree_expr_nonzero_p): Add function prototype. (fold) : Move tree_expr_nonzero_p optimization from fold_relational_const to here, i.e. "(x | 5) == 0" -> false. (fold) (UNEQ_EXPR>: Add optimizations for unordered comparisons of the form "x op x" where op is UNLE, UNGE, UNEQ or LTGT. (fold_relational_const): Tidy up handling of floating point comparisons by calling real_compare. Remove tree_expr_nonzero_p transformation; fold_relational_const assumes constant operands. From-SVN: r84916 --- gcc/ChangeLog | 11 ++++++++ gcc/fold-const.c | 73 +++++++++++++++--------------------------------- 2 files changed, 34 insertions(+), 50 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3433fbb0b7e..12667fd1339 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2004-07-19 Roger Sayle + + * fold-const.c (tree_expr_nonzero_p): Add function prototype. + (fold) : Move tree_expr_nonzero_p optimization from + fold_relational_const to here, i.e. "(x | 5) == 0" -> false. + (fold) (UNEQ_EXPR>: Add optimizations for unordered comparisons + of the form "x op x" where op is UNLE, UNGE, UNEQ or LTGT. + (fold_relational_const): Tidy up handling of floating point + comparisons by calling real_compare. Remove tree_expr_nonzero_p + transformation; fold_relational_const assumes constant operands. + 2004-07-19 Gabriel Dos Reis * doc/sourcebuild.texi: Add libcpp, now that CPP has its own diff --git a/gcc/fold-const.c b/gcc/fold-const.c index bc1e8773c97..7c6b66533e6 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -137,6 +137,7 @@ static tree fold_not_const (tree, tree); static tree fold_relational_const (enum tree_code, tree, tree, tree); static tree fold_relational_hi_lo (enum tree_code *, const tree, tree *, tree *); +static bool tree_expr_nonzero_p (tree); /* We know that A1 + B1 = SUM1, using 2's complement arithmetic and ignoring overflow. Suppose A, B and SUM have the same respective signs as A1, B1, @@ -8638,9 +8639,14 @@ fold (tree expr) return t1; } - /* Both ARG0 and ARG1 are known to be constants at this point. */ + if ((code == EQ_EXPR || code == NE_EXPR) + && !TREE_SIDE_EFFECTS (arg0) + && integer_zerop (arg1) + && tree_expr_nonzero_p (arg0)) + return constant_boolean_node (code==NE_EXPR, type); + t1 = fold_relational_const (code, type, arg0, arg1); - return (t1 == NULL_TREE ? t : t1); + return t1 == NULL_TREE ? t : t1; case UNORDERED_EXPR: case ORDERED_EXPR: @@ -8679,6 +8685,16 @@ fold (tree expr) return omit_one_operand (type, t1, arg0); } + /* Simplify unordered comparison of something with itself. */ + if ((code == UNLE_EXPR || code == UNGE_EXPR || code == UNEQ_EXPR) + && operand_equal_p (arg0, arg1, 0)) + return constant_boolean_node (1, type); + + if (code == LTGT_EXPR + && !flag_trapping_math + && operand_equal_p (arg0, arg1, 0)) + return constant_boolean_node (0, type); + /* Fold (double)float1 CMP (double)float2 into float1 CMP float2. */ { tree targ0 = strip_float_extensions (arg0); @@ -10394,9 +10410,11 @@ fold_relational_const (enum tree_code code, tree type, tree op0, tree op1) if (TREE_CODE (op0) == REAL_CST && TREE_CODE (op1) == REAL_CST) { + const REAL_VALUE_TYPE *c0 = TREE_REAL_CST_PTR (op0); + const REAL_VALUE_TYPE *c1 = TREE_REAL_CST_PTR (op1); + /* Handle the cases where either operand is a NaN. */ - if (REAL_VALUE_ISNAN (TREE_REAL_CST (op0)) - || REAL_VALUE_ISNAN (TREE_REAL_CST (op1))) + if (real_isnan (c0) || real_isnan (c1)) { switch (code) { @@ -10432,37 +10450,7 @@ fold_relational_const (enum tree_code code, tree type, tree op0, tree op1) return constant_boolean_node (result, type); } - /* From here on we're sure there are no NaNs. */ - switch (code) - { - case ORDERED_EXPR: - return constant_boolean_node (true, type); - - case UNORDERED_EXPR: - return constant_boolean_node (false, type); - - case UNLT_EXPR: - code = LT_EXPR; - break; - case UNLE_EXPR: - code = LE_EXPR; - break; - case UNGT_EXPR: - code = GT_EXPR; - break; - case UNGE_EXPR: - code = GE_EXPR; - break; - case UNEQ_EXPR: - code = EQ_EXPR; - break; - case LTGT_EXPR: - code = NE_EXPR; - break; - - default: - break; - } + return constant_boolean_node (real_compare (code, c0, c1), type); } /* From here on we only handle LT, LE, GT, GE, EQ and NE. @@ -10503,21 +10491,6 @@ fold_relational_const (enum tree_code code, tree type, tree op0, tree op1) else result = INT_CST_LT (op0, op1); } - - else if (code == EQ_EXPR && !TREE_SIDE_EFFECTS (op0) - && integer_zerop (op1) && tree_expr_nonzero_p (op0)) - result = 0; - - /* Two real constants can be compared explicitly. */ - else if (TREE_CODE (op0) == REAL_CST && TREE_CODE (op1) == REAL_CST) - { - if (code == EQ_EXPR) - result = REAL_VALUES_EQUAL (TREE_REAL_CST (op0), - TREE_REAL_CST (op1)); - else - result = REAL_VALUES_LESS (TREE_REAL_CST (op0), - TREE_REAL_CST (op1)); - } else return NULL_TREE; -- 2.30.2