diff options
author | Richard Biener <rguenther@suse.de> | 2015-07-03 12:02:35 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2015-07-03 12:02:35 +0000 |
commit | 07cdc2b892ca3969fd5d8c6a281cf77f559cea43 (patch) | |
tree | 8a704d2f67cd1491047c25ff7a2ed93cd6275ab1 /gcc/fold-const.c | |
parent | c8083fc05cb95d660edd12602b062f3d7adc43e3 (diff) | |
download | gcc-07cdc2b892ca3969fd5d8c6a281cf77f559cea43.zip gcc-07cdc2b892ca3969fd5d8c6a281cf77f559cea43.tar.gz gcc-07cdc2b892ca3969fd5d8c6a281cf77f559cea43.tar.bz2 |
fold-const.c (fold_mathfn_compare): Remove.
2015-07-03 Richard Biener <rguenther@suse.de>
* fold-const.c (fold_mathfn_compare): Remove.
(fold_inf_compare): Likewise.
(fold_comparison): Move floating point comparison simplifications...
* match.pd: ... to patterns here. Introduce simple_comparisons
operator list and use it for patterns formerly in fold_comparison.
From-SVN: r225375
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r-- | gcc/fold-const.c | 286 |
1 files changed, 0 insertions, 286 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 69ac19d..d896d7a 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -145,10 +145,6 @@ static tree fold_binary_op_with_conditional_arg (location_t, enum tree_code, tree, tree, tree, tree, tree, int); -static tree fold_mathfn_compare (location_t, - enum built_in_function, enum tree_code, - tree, tree, tree); -static tree fold_inf_compare (location_t, enum tree_code, tree, tree, tree); static tree fold_div_compare (location_t, enum tree_code, tree, tree, tree); static bool reorder_operands_p (const_tree, const_tree); static tree fold_negate_const (tree, tree); @@ -6418,199 +6414,6 @@ fold_real_zero_addition_p (const_tree type, const_tree addend, int negate) return negate && !HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (type)); } -/* Subroutine of fold() that checks comparisons of built-in math - functions against real constants. - - FCODE is the DECL_FUNCTION_CODE of the built-in, CODE is the comparison - operator: EQ_EXPR, NE_EXPR, GT_EXPR, LT_EXPR, GE_EXPR or LE_EXPR. TYPE - is the type of the result and ARG0 and ARG1 are the operands of the - comparison. ARG1 must be a TREE_REAL_CST. - - The function returns the constant folded tree if a simplification - can be made, and NULL_TREE otherwise. */ - -static tree -fold_mathfn_compare (location_t loc, - enum built_in_function fcode, enum tree_code code, - tree type, tree arg0, tree arg1) -{ - REAL_VALUE_TYPE c; - - if (BUILTIN_SQRT_P (fcode)) - { - tree arg = CALL_EXPR_ARG (arg0, 0); - machine_mode mode = TYPE_MODE (TREE_TYPE (arg0)); - - c = TREE_REAL_CST (arg1); - if (REAL_VALUE_NEGATIVE (c)) - { - /* sqrt(x) < y is always false, if y is negative. */ - if (code == EQ_EXPR || code == LT_EXPR || code == LE_EXPR) - return omit_one_operand_loc (loc, type, integer_zero_node, arg); - - /* sqrt(x) > y is always true, if y is negative and we - don't care about NaNs, i.e. negative values of x. */ - if (code == NE_EXPR || !HONOR_NANS (mode)) - return omit_one_operand_loc (loc, type, integer_one_node, arg); - - /* sqrt(x) > y is the same as x >= 0, if y is negative. */ - return fold_build2_loc (loc, GE_EXPR, type, arg, - build_real (TREE_TYPE (arg), dconst0)); - } - else if (code == GT_EXPR || code == GE_EXPR) - { - REAL_VALUE_TYPE c2; - - REAL_ARITHMETIC (c2, MULT_EXPR, c, c); - real_convert (&c2, mode, &c2); - - if (REAL_VALUE_ISINF (c2)) - { - /* sqrt(x) > y is x == +Inf, when y is very large. */ - if (HONOR_INFINITIES (mode)) - return fold_build2_loc (loc, EQ_EXPR, type, arg, - build_real (TREE_TYPE (arg), c2)); - - /* sqrt(x) > y is always false, when y is very large - and we don't care about infinities. */ - return omit_one_operand_loc (loc, type, integer_zero_node, arg); - } - - /* sqrt(x) > c is the same as x > c*c. */ - return fold_build2_loc (loc, code, type, arg, - build_real (TREE_TYPE (arg), c2)); - } - else if (code == LT_EXPR || code == LE_EXPR) - { - REAL_VALUE_TYPE c2; - - REAL_ARITHMETIC (c2, MULT_EXPR, c, c); - real_convert (&c2, mode, &c2); - - if (REAL_VALUE_ISINF (c2)) - { - /* sqrt(x) < y is always true, when y is a very large - value and we don't care about NaNs or Infinities. */ - if (! HONOR_NANS (mode) && ! HONOR_INFINITIES (mode)) - return omit_one_operand_loc (loc, type, integer_one_node, arg); - - /* sqrt(x) < y is x != +Inf when y is very large and we - don't care about NaNs. */ - if (! HONOR_NANS (mode)) - return fold_build2_loc (loc, NE_EXPR, type, arg, - build_real (TREE_TYPE (arg), c2)); - - /* sqrt(x) < y is x >= 0 when y is very large and we - don't care about Infinities. */ - if (! HONOR_INFINITIES (mode)) - return fold_build2_loc (loc, GE_EXPR, type, arg, - build_real (TREE_TYPE (arg), dconst0)); - - /* sqrt(x) < y is x >= 0 && x != +Inf, when y is large. */ - arg = save_expr (arg); - return fold_build2_loc (loc, TRUTH_ANDIF_EXPR, type, - fold_build2_loc (loc, GE_EXPR, type, arg, - build_real (TREE_TYPE (arg), - dconst0)), - fold_build2_loc (loc, NE_EXPR, type, arg, - build_real (TREE_TYPE (arg), - c2))); - } - - /* sqrt(x) < c is the same as x < c*c, if we ignore NaNs. */ - if (! HONOR_NANS (mode)) - return fold_build2_loc (loc, code, type, arg, - build_real (TREE_TYPE (arg), c2)); - - /* sqrt(x) < c is the same as x >= 0 && x < c*c. */ - arg = save_expr (arg); - return fold_build2_loc (loc, TRUTH_ANDIF_EXPR, type, - fold_build2_loc (loc, GE_EXPR, type, arg, - build_real (TREE_TYPE (arg), - dconst0)), - fold_build2_loc (loc, code, type, arg, - build_real (TREE_TYPE (arg), - c2))); - } - } - - return NULL_TREE; -} - -/* Subroutine of fold() that optimizes comparisons against Infinities, - either +Inf or -Inf. - - CODE is the comparison operator: EQ_EXPR, NE_EXPR, GT_EXPR, LT_EXPR, - GE_EXPR or LE_EXPR. TYPE is the type of the result and ARG0 and ARG1 - are the operands of the comparison. ARG1 must be a TREE_REAL_CST. - - The function returns the constant folded tree if a simplification - can be made, and NULL_TREE otherwise. */ - -static tree -fold_inf_compare (location_t loc, enum tree_code code, tree type, - tree arg0, tree arg1) -{ - machine_mode mode; - REAL_VALUE_TYPE max; - tree temp; - bool neg; - - mode = TYPE_MODE (TREE_TYPE (arg0)); - - /* For negative infinity swap the sense of the comparison. */ - neg = REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1)); - if (neg) - code = swap_tree_comparison (code); - - switch (code) - { - case GT_EXPR: - /* x > +Inf is always false, if with ignore sNANs. */ - if (HONOR_SNANS (mode)) - return NULL_TREE; - return omit_one_operand_loc (loc, type, integer_zero_node, arg0); - - case LE_EXPR: - /* x <= +Inf is always true, if we don't case about NaNs. */ - if (! HONOR_NANS (mode)) - return omit_one_operand_loc (loc, type, integer_one_node, arg0); - - /* x <= +Inf is the same as x == x, i.e. isfinite(x). */ - arg0 = save_expr (arg0); - return fold_build2_loc (loc, EQ_EXPR, type, arg0, arg0); - - case EQ_EXPR: - case GE_EXPR: - /* x == +Inf and x >= +Inf are always equal to x > DBL_MAX. */ - real_maxval (&max, neg, mode); - return fold_build2_loc (loc, neg ? LT_EXPR : GT_EXPR, type, - arg0, build_real (TREE_TYPE (arg0), max)); - - case LT_EXPR: - /* x < +Inf is always equal to x <= DBL_MAX. */ - real_maxval (&max, neg, mode); - return fold_build2_loc (loc, neg ? GE_EXPR : LE_EXPR, type, - arg0, build_real (TREE_TYPE (arg0), max)); - - case NE_EXPR: - /* x != +Inf is always equal to !(x > DBL_MAX). */ - real_maxval (&max, neg, mode); - if (! HONOR_NANS (mode)) - return fold_build2_loc (loc, neg ? GE_EXPR : LE_EXPR, type, - arg0, build_real (TREE_TYPE (arg0), max)); - - temp = fold_build2_loc (loc, neg ? LT_EXPR : GT_EXPR, type, - arg0, build_real (TREE_TYPE (arg0), max)); - return fold_build1_loc (loc, TRUTH_NOT_EXPR, type, temp); - - default: - break; - } - - return NULL_TREE; -} - /* Subroutine of fold() that optimizes comparisons of a division by a nonzero integer constant against an integer constant, i.e. X/C1 op C2. @@ -9075,95 +8878,6 @@ fold_comparison (location_t loc, enum tree_code code, tree type, if (tem) return tem; - if (FLOAT_TYPE_P (TREE_TYPE (arg0))) - { - tree targ0 = strip_float_extensions (arg0); - tree targ1 = strip_float_extensions (arg1); - tree newtype = TREE_TYPE (targ0); - - if (TYPE_PRECISION (TREE_TYPE (targ1)) > TYPE_PRECISION (newtype)) - newtype = TREE_TYPE (targ1); - - /* Fold (double)float1 CMP (double)float2 into float1 CMP float2. */ - if (TYPE_PRECISION (newtype) < TYPE_PRECISION (TREE_TYPE (arg0))) - return fold_build2_loc (loc, code, type, - fold_convert_loc (loc, newtype, targ0), - fold_convert_loc (loc, newtype, targ1)); - - if (TREE_CODE (arg1) == REAL_CST) - { - REAL_VALUE_TYPE cst; - cst = TREE_REAL_CST (arg1); - - /* IEEE doesn't distinguish +0 and -0 in comparisons. */ - /* a CMP (-0) -> a CMP 0 */ - if (REAL_VALUE_MINUS_ZERO (cst)) - return fold_build2_loc (loc, code, type, arg0, - build_real (TREE_TYPE (arg1), dconst0)); - - /* x != NaN is always true, other ops are always false. */ - if (REAL_VALUE_ISNAN (cst) - && ! HONOR_SNANS (arg1)) - { - tem = (code == NE_EXPR) ? integer_one_node : integer_zero_node; - return omit_one_operand_loc (loc, type, tem, arg0); - } - - /* Fold comparisons against infinity. */ - if (REAL_VALUE_ISINF (cst) - && MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg1)))) - { - tem = fold_inf_compare (loc, code, type, arg0, arg1); - if (tem != NULL_TREE) - return tem; - } - } - - /* If this is a comparison of a real constant with a PLUS_EXPR - or a MINUS_EXPR of a real constant, we can convert it into a - comparison with a revised real constant as long as no overflow - occurs when unsafe_math_optimizations are enabled. */ - if (flag_unsafe_math_optimizations - && TREE_CODE (arg1) == REAL_CST - && (TREE_CODE (arg0) == PLUS_EXPR - || TREE_CODE (arg0) == MINUS_EXPR) - && TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST - && 0 != (tem = const_binop (TREE_CODE (arg0) == PLUS_EXPR - ? MINUS_EXPR : PLUS_EXPR, - arg1, TREE_OPERAND (arg0, 1))) - && !TREE_OVERFLOW (tem)) - return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0), tem); - - /* Likewise, we can simplify a comparison of a real constant with - a MINUS_EXPR whose first operand is also a real constant, i.e. - (c1 - x) < c2 becomes x > c1-c2. Reordering is allowed on - floating-point types only if -fassociative-math is set. */ - if (flag_associative_math - && TREE_CODE (arg1) == REAL_CST - && TREE_CODE (arg0) == MINUS_EXPR - && TREE_CODE (TREE_OPERAND (arg0, 0)) == REAL_CST - && 0 != (tem = const_binop (MINUS_EXPR, TREE_OPERAND (arg0, 0), - arg1)) - && !TREE_OVERFLOW (tem)) - return fold_build2_loc (loc, swap_tree_comparison (code), type, - TREE_OPERAND (arg0, 1), tem); - - /* Fold comparisons against built-in math functions. */ - if (TREE_CODE (arg1) == REAL_CST - && flag_unsafe_math_optimizations - && ! flag_errno_math) - { - enum built_in_function fcode = builtin_mathfn_code (arg0); - - if (fcode != END_BUILTINS) - { - tem = fold_mathfn_compare (loc, fcode, code, type, arg0, arg1); - if (tem != NULL_TREE) - return tem; - } - } - } - if (TREE_CODE (TREE_TYPE (arg0)) == INTEGER_TYPE && CONVERT_EXPR_P (arg0)) { |