diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 23 | ||||
-rw-r--r-- | gcc/builtins.c | 12 | ||||
-rw-r--r-- | gcc/fold-const.c | 6 | ||||
-rw-r--r-- | gcc/gimple-fold.c | 2 | ||||
-rw-r--r-- | gcc/ifcvt.c | 6 | ||||
-rw-r--r-- | gcc/omp-low.c | 4 | ||||
-rw-r--r-- | gcc/real.c | 84 | ||||
-rw-r--r-- | gcc/real.h | 23 | ||||
-rw-r--r-- | gcc/rtlanal.c | 8 | ||||
-rw-r--r-- | gcc/simplify-rtx.c | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-dom.c | 6 | ||||
-rw-r--r-- | gcc/tree-ssa-phiopt.c | 4 | ||||
-rw-r--r-- | gcc/tree-ssa-reassoc.c | 4 | ||||
-rw-r--r-- | gcc/tree-ssa-uncprop.c | 2 |
14 files changed, 148 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a1cdd71..e62a1e4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2014-12-12 Marc Glisse <marc.glisse@inria.fr> + + * real.h (HONOR_SNANS, HONOR_INFINITIES, HONOR_SIGNED_ZEROS, + HONOR_SIGN_DEPENDENT_ROUNDING): Replace macros with 3 overloaded + declarations. + * real.c (HONOR_NANS): Fix indentation. + (HONOR_SNANS, HONOR_INFINITIES, HONOR_SIGNED_ZEROS, + HONOR_SIGN_DEPENDENT_ROUNDING): Define three overloads. + * builtins.c (fold_builtin_cproj, fold_builtin_signbit, + fold_builtin_fmin_fmax, fold_builtin_classify): Simplify argument + of HONOR_*. + * fold-const.c (operand_equal_p, fold_comparison, fold_binary_loc): + Likewise. + * gimple-fold.c (gimple_val_nonnegative_real_p): Likewise. + * ifcvt.c (noce_try_move, noce_try_minmax, noce_try_abs): Likewise. + * omp-low.c (omp_reduction_init): Likewise. + * rtlanal.c (may_trap_p_1): Likewise. + * simplify-rtx.c (simplify_const_relational_operation): Likewise. + * tree-ssa-dom.c (record_equality, record_edge_info): Likewise. + * tree-ssa-phiopt.c (value_replacement, abs_replacement): Likewise. + * tree-ssa-reassoc.c (eliminate_using_constants): Likewise. + * tree-ssa-uncprop.c (associate_equivalences_with_edges): Likewise. + 2014-12-12 Jan Hubicka <hubicka@ucw.cz> * ipa-inline.c (ipa_inline): Fix condition on when diff --git a/gcc/builtins.c b/gcc/builtins.c index 0d31981..445bff2 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -7678,7 +7678,7 @@ fold_builtin_cproj (location_t loc, tree arg, tree type) return NULL_TREE; /* If there are no infinities, return arg. */ - if (! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (type)))) + if (! HONOR_INFINITIES (type)) return non_lvalue_loc (loc, arg); /* Calculate the result when the argument is a constant. */ @@ -8949,7 +8949,7 @@ fold_builtin_signbit (location_t loc, tree arg, tree type) return omit_one_operand_loc (loc, type, integer_zero_node, arg); /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */ - if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg)))) + if (!HONOR_SIGNED_ZEROS (arg)) return fold_convert (type, fold_build2_loc (loc, LT_EXPR, boolean_type_node, arg, build_real (TREE_TYPE (arg), dconst0))); @@ -9143,12 +9143,12 @@ fold_builtin_fmin_fmax (location_t loc, tree arg0, tree arg1, omit_one_operand() ensures we create a non-lvalue. */ if (TREE_CODE (arg0) == REAL_CST && real_isnan (&TREE_REAL_CST (arg0)) - && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0))) + && (! HONOR_SNANS (arg0) || ! TREE_REAL_CST (arg0).signalling)) return omit_one_operand_loc (loc, type, arg1, arg0); if (TREE_CODE (arg1) == REAL_CST && real_isnan (&TREE_REAL_CST (arg1)) - && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1))) + && (! HONOR_SNANS (arg1) || ! TREE_REAL_CST (arg1).signalling)) return omit_one_operand_loc (loc, type, arg0, arg1); @@ -9559,7 +9559,7 @@ fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index) switch (builtin_index) { case BUILT_IN_ISINF: - if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg)))) + if (!HONOR_INFINITIES (arg)) return omit_one_operand_loc (loc, type, integer_zero_node, arg); if (TREE_CODE (arg) == REAL_CST) @@ -9608,7 +9608,7 @@ fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index) case BUILT_IN_ISFINITE: if (!HONOR_NANS (arg) - && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg)))) + && !HONOR_INFINITIES (arg)) return omit_one_operand_loc (loc, type, integer_one_node, arg); if (TREE_CODE (arg) == REAL_CST) diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 7b68bea..ec5ad98 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -2800,7 +2800,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags) return 1; - if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg0)))) + if (!HONOR_SIGNED_ZEROS (arg0)) { /* If we do not distinguish between signed and unsigned zero, consider them equal. */ @@ -9165,7 +9165,7 @@ fold_comparison (location_t loc, enum tree_code code, tree type, /* x != NaN is always true, other ops are always false. */ if (REAL_VALUE_ISNAN (cst) - && ! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))) + && ! HONOR_SNANS (arg1)) { tem = (code == NE_EXPR) ? integer_one_node : integer_zero_node; return omit_one_operand_loc (loc, type, tem, arg0); @@ -12808,7 +12808,7 @@ fold_binary_loc (location_t loc, if ((TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR) && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0) && ((TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST - && !HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))) + && !HONOR_SNANS (arg0)) || (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg1))))) { diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index e71e095..a8ca53d 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -5832,7 +5832,7 @@ gimple_val_nonnegative_real_p (tree val) CASE_FLT_FN (BUILT_IN_SQRT): /* sqrt(-0.0) is -0.0, and sqrt is not defined over other nonnegative inputs. */ - if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (val)))) + if (!HONOR_SIGNED_ZEROS (val)) return true; break; diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index f0159c1..90586da 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -1078,7 +1078,7 @@ noce_try_move (struct noce_if_info *if_info) /* This optimization isn't valid if either A or B could be a NaN or a signed zero. */ if (HONOR_NANS (if_info->x) - || HONOR_SIGNED_ZEROS (GET_MODE (if_info->x))) + || HONOR_SIGNED_ZEROS (if_info->x)) return FALSE; /* Check whether the operands of the comparison are A and in @@ -1969,7 +1969,7 @@ noce_try_minmax (struct noce_if_info *if_info) /* ??? Reject modes with NaNs or signed zeros since we don't know how they will be resolved with an SMIN/SMAX. It wouldn't be too hard to get the target to tell us... */ - if (HONOR_SIGNED_ZEROS (GET_MODE (if_info->x)) + if (HONOR_SIGNED_ZEROS (if_info->x) || HONOR_NANS (if_info->x)) return FALSE; @@ -2063,7 +2063,7 @@ noce_try_abs (struct noce_if_info *if_info) bool one_cmpl = false; /* Reject modes with signed zeros. */ - if (HONOR_SIGNED_ZEROS (GET_MODE (if_info->x))) + if (HONOR_SIGNED_ZEROS (if_info->x)) return FALSE; /* Recognize A and B as constituting an ABS or NABS. The canonical diff --git a/gcc/omp-low.c b/gcc/omp-low.c index ef143ab..a2e4737 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -3039,7 +3039,7 @@ omp_reduction_init (tree clause, tree type) if (SCALAR_FLOAT_TYPE_P (type)) { REAL_VALUE_TYPE max, min; - if (HONOR_INFINITIES (TYPE_MODE (type))) + if (HONOR_INFINITIES (type)) { real_inf (&max); real_arithmetic (&min, NEGATE_EXPR, &max, NULL); @@ -3058,7 +3058,7 @@ omp_reduction_init (tree clause, tree type) if (SCALAR_FLOAT_TYPE_P (type)) { REAL_VALUE_TYPE max; - if (HONOR_INFINITIES (TYPE_MODE (type))) + if (HONOR_INFINITIES (type)) real_inf (&max); else real_maxval (&max, 0, TYPE_MODE (type)); @@ -5003,6 +5003,88 @@ HONOR_NANS (const_tree t) bool HONOR_NANS (const_rtx x) { - return HONOR_NANS (GET_MODE (x)); + return HONOR_NANS (GET_MODE (x)); } +/* Like HONOR_NANs, but true if we honor signaling NaNs (or sNaNs). */ + +bool +HONOR_SNANS (machine_mode m) +{ + return flag_signaling_nans && HONOR_NANS (m); +} + +bool +HONOR_SNANS (const_tree t) +{ + return HONOR_SNANS (element_mode (t)); +} + +bool +HONOR_SNANS (const_rtx x) +{ + return HONOR_SNANS (GET_MODE (x)); +} + +/* As for HONOR_NANS, but true if the mode can represent infinity and + the treatment of infinite values is important. */ + +bool +HONOR_INFINITIES (machine_mode m) +{ + return MODE_HAS_INFINITIES (m) && !flag_finite_math_only; +} + +bool +HONOR_INFINITIES (const_tree t) +{ + return HONOR_INFINITIES (element_mode (t)); +} + +bool +HONOR_INFINITIES (const_rtx x) +{ + return HONOR_INFINITIES (GET_MODE (x)); +} + +/* Like HONOR_NANS, but true if the given mode distinguishes between + positive and negative zero, and the sign of zero is important. */ + +bool +HONOR_SIGNED_ZEROS (machine_mode m) +{ + return MODE_HAS_SIGNED_ZEROS (m) && flag_signed_zeros; +} + +bool +HONOR_SIGNED_ZEROS (const_tree t) +{ + return HONOR_SIGNED_ZEROS (element_mode (t)); +} + +bool +HONOR_SIGNED_ZEROS (const_rtx x) +{ + return HONOR_SIGNED_ZEROS (GET_MODE (x)); +} + +/* Like HONOR_NANS, but true if given mode supports sign-dependent rounding, + and the rounding mode is important. */ + +bool +HONOR_SIGN_DEPENDENT_ROUNDING (machine_mode m) +{ + return MODE_HAS_SIGN_DEPENDENT_ROUNDING (m) && flag_rounding_math; +} + +bool +HONOR_SIGN_DEPENDENT_ROUNDING (const_tree t) +{ + return HONOR_SIGN_DEPENDENT_ROUNDING (element_mode (t)); +} + +bool +HONOR_SIGN_DEPENDENT_ROUNDING (const_rtx x) +{ + return HONOR_SIGN_DEPENDENT_ROUNDING (GET_MODE (x)); +} @@ -195,6 +195,8 @@ extern const struct real_format * (FLOAT_MODE_P (MODE) \ && FLOAT_MODE_FORMAT (MODE)->has_sign_dependent_rounding) +/* Declare functions in real.c. */ + /* True if the given mode has a NaN representation and the treatment of NaN operands is important. Certain optimizations, such as folding x * 0 into 0, are not correct for NaN operands, and are normally @@ -205,24 +207,27 @@ extern bool HONOR_NANS (const_tree); extern bool HONOR_NANS (const_rtx); /* Like HONOR_NANs, but true if we honor signaling NaNs (or sNaNs). */ -#define HONOR_SNANS(MODE) (flag_signaling_nans && HONOR_NANS (MODE)) +extern bool HONOR_SNANS (machine_mode); +extern bool HONOR_SNANS (const_tree); +extern bool HONOR_SNANS (const_rtx); /* As for HONOR_NANS, but true if the mode can represent infinity and the treatment of infinite values is important. */ -#define HONOR_INFINITIES(MODE) \ - (MODE_HAS_INFINITIES (MODE) && !flag_finite_math_only) +extern bool HONOR_INFINITIES (machine_mode); +extern bool HONOR_INFINITIES (const_tree); +extern bool HONOR_INFINITIES (const_rtx); /* Like HONOR_NANS, but true if the given mode distinguishes between positive and negative zero, and the sign of zero is important. */ -#define HONOR_SIGNED_ZEROS(MODE) \ - (MODE_HAS_SIGNED_ZEROS (MODE) && flag_signed_zeros) +extern bool HONOR_SIGNED_ZEROS (machine_mode); +extern bool HONOR_SIGNED_ZEROS (const_tree); +extern bool HONOR_SIGNED_ZEROS (const_rtx); /* Like HONOR_NANS, but true if given mode supports sign-dependent rounding, and the rounding mode is important. */ -#define HONOR_SIGN_DEPENDENT_ROUNDING(MODE) \ - (MODE_HAS_SIGN_DEPENDENT_ROUNDING (MODE) && flag_rounding_math) - -/* Declare functions in real.c. */ +extern bool HONOR_SIGN_DEPENDENT_ROUNDING (machine_mode); +extern bool HONOR_SIGN_DEPENDENT_ROUNDING (const_tree); +extern bool HONOR_SIGN_DEPENDENT_ROUNDING (const_rtx); /* Binary or unary arithmetic on tree_code. */ extern bool real_arithmetic (REAL_VALUE_TYPE *, int, const REAL_VALUE_TYPE *, diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index e04dea8..2fad919 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -2526,7 +2526,7 @@ may_trap_p_1 (const_rtx x, unsigned flags) case MOD: case UDIV: case UMOD: - if (HONOR_SNANS (GET_MODE (x))) + if (HONOR_SNANS (x)) return 1; if (SCALAR_FLOAT_MODE_P (GET_MODE (x))) return flag_trapping_math; @@ -2563,11 +2563,11 @@ may_trap_p_1 (const_rtx x, unsigned flags) case EQ: case NE: - if (HONOR_SNANS (GET_MODE (x))) + if (HONOR_SNANS (x)) return 1; /* Often comparison is CC mode, so check operand modes. */ - if (HONOR_SNANS (GET_MODE (XEXP (x, 0))) - || HONOR_SNANS (GET_MODE (XEXP (x, 1)))) + if (HONOR_SNANS (XEXP (x, 0)) + || HONOR_SNANS (XEXP (x, 1))) return 1; break; diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 5afbc02..8ec416e 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -4757,7 +4757,7 @@ simplify_const_relational_operation (enum rtx_code code, if ((! HONOR_NANS (trueop0) || code == UNEQ || code == UNLE || code == UNGE || ((code == LT || code == GT || code == LTGT) - && ! HONOR_SNANS (GET_MODE (trueop0)))) + && ! HONOR_SNANS (trueop0))) && rtx_equal_p (trueop0, trueop1) && ! side_effects_p (trueop0)) return comparison_result (code, CMP_EQ); diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index bd37226..7842b79 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -1659,7 +1659,7 @@ record_equality (tree x, tree y) variable compared against zero. If we're honoring signed zeros, then we cannot record this value unless we know that the value is nonzero. */ - if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (x))) + if (HONOR_SIGNED_ZEROS (x) && (TREE_CODE (y) != REAL_CST || REAL_VALUES_EQUAL (dconst0, TREE_REAL_CST (y)))) return; @@ -1900,7 +1900,7 @@ 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))) + = !(HONOR_SIGNED_ZEROS (op0) && real_zerop (op0)); struct edge_info *edge_info; @@ -1930,7 +1930,7 @@ 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 (op1))) + = !(HONOR_SIGNED_ZEROS (op1) && (TREE_CODE (op1) == SSA_NAME || real_zerop (op1))); struct edge_info *edge_info; diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index b4febee..be1becb 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -749,7 +749,7 @@ value_replacement (basic_block cond_bb, basic_block middle_bb, /* If the type says honor signed zeros we cannot do this optimization. */ - if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1)))) + if (HONOR_SIGNED_ZEROS (arg1)) return 0; /* If there is a statement in MIDDLE_BB that defines one of the PHI @@ -1182,7 +1182,7 @@ abs_replacement (basic_block cond_bb, basic_block middle_bb, /* If the type says honor signed zeros we cannot do this optimization. */ - if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1)))) + if (HONOR_SIGNED_ZEROS (arg1)) return false; /* OTHER_BLOCK must have only one executable statement which must have the diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 8150292..52a4cae 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -967,7 +967,7 @@ eliminate_using_constants (enum tree_code opcode, if (integer_zerop (oelast->op) || (FLOAT_TYPE_P (type) && !HONOR_NANS (type) - && !HONOR_SIGNED_ZEROS (TYPE_MODE (type)) + && !HONOR_SIGNED_ZEROS (type) && real_zerop (oelast->op))) { if (ops->length () != 1) @@ -983,7 +983,7 @@ eliminate_using_constants (enum tree_code opcode, } else if (integer_onep (oelast->op) || (FLOAT_TYPE_P (type) - && !HONOR_SNANS (TYPE_MODE (type)) + && !HONOR_SNANS (type) && real_onep (oelast->op))) { if (ops->length () != 1) diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c index ecddef4..fd7ee3f 100644 --- a/gcc/tree-ssa-uncprop.c +++ b/gcc/tree-ssa-uncprop.c @@ -160,7 +160,7 @@ associate_equivalences_with_edges (void) the sign of a variable compared against zero. If we're honoring signed zeros, then we cannot record this value unless we know that the value is nonzero. */ - if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (op0))) + if (HONOR_SIGNED_ZEROS (op0) && (TREE_CODE (op1) != REAL_CST || REAL_VALUES_EQUAL (dconst0, TREE_REAL_CST (op1)))) continue; |