real.h (HONOR_NANS): Replace macro with 3 overloaded declarations.

2014-12-10  Marc Glisse  <marc.glisse@inria.fr>

	* real.h (HONOR_NANS): Replace macro with 3 overloaded declarations.
	* real.c: Include rtl.h and options.h.
	(HONOR_NANS): Define three overloads.
	* builtins.c (fold_builtin_classify, fold_builtin_unordered_cmp):
	Simplify argument of HONOR_NANS.
	* fold-const.c (combine_comparisons, fold_truth_not_expr,
	fold_cond_expr_with_comparison, merge_truthop_with_opposite_arm,
	fold_comparison, fold_binary_loc): Likewise.
	* ifcvt.c (noce_try_move, noce_try_minmax): Likewise.
	* ipa-inline-analysis.c (add_clause,
	set_cond_stmt_execution_predicate): Likewise.
	* match.pd: Likewise.
	* rtlanal.c (may_trap_p_1): Likewise.
	* simplify-rtx.c (simplify_const_relational_operation): Likewise.
	* tree-if-conv.c (parse_predicate): Likewise.
	* tree-ssa-ccp.c (valid_lattice_transition): Likewise.
	* tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise.
	* tree-ssa-phiopt.c (minmax_replacement, neg_replacement): Likewise.
	* tree-ssa-reassoc.c (eliminate_using_constants): Likewise.
	* tree-ssa-tail-merge.c (gimple_equal_p): Likewise.

From-SVN: r218605
This commit is contained in:
Marc Glisse 2014-12-10 21:26:05 +01:00 committed by Marc Glisse
parent 1c4967b998
commit 1b457aa45d
16 changed files with 96 additions and 55 deletions

View File

@ -1,3 +1,26 @@
2014-12-10 Marc Glisse <marc.glisse@inria.fr>
* real.h (HONOR_NANS): Replace macro with 3 overloaded declarations.
* real.c: Include rtl.h and options.h.
(HONOR_NANS): Define three overloads.
* builtins.c (fold_builtin_classify, fold_builtin_unordered_cmp):
Simplify argument of HONOR_NANS.
* fold-const.c (combine_comparisons, fold_truth_not_expr,
fold_cond_expr_with_comparison, merge_truthop_with_opposite_arm,
fold_comparison, fold_binary_loc): Likewise.
* ifcvt.c (noce_try_move, noce_try_minmax): Likewise.
* ipa-inline-analysis.c (add_clause,
set_cond_stmt_execution_predicate): Likewise.
* match.pd: Likewise.
* rtlanal.c (may_trap_p_1): Likewise.
* simplify-rtx.c (simplify_const_relational_operation): Likewise.
* tree-if-conv.c (parse_predicate): Likewise.
* tree-ssa-ccp.c (valid_lattice_transition): Likewise.
* tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise.
* tree-ssa-phiopt.c (minmax_replacement, neg_replacement): Likewise.
* tree-ssa-reassoc.c (eliminate_using_constants): Likewise.
* tree-ssa-tail-merge.c (gimple_equal_p): Likewise.
2014-12-10 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/62021

View File

@ -9607,7 +9607,7 @@ fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index)
}
case BUILT_IN_ISFINITE:
if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
if (!HONOR_NANS (arg)
&& !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
return omit_one_operand_loc (loc, type, integer_one_node, arg);
@ -9620,7 +9620,7 @@ fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index)
return NULL_TREE;
case BUILT_IN_ISNAN:
if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
if (!HONOR_NANS (arg))
return omit_one_operand_loc (loc, type, integer_zero_node, arg);
if (TREE_CODE (arg) == REAL_CST)
@ -9748,13 +9748,12 @@ fold_builtin_unordered_cmp (location_t loc, tree fndecl, tree arg0, tree arg1,
if (unordered_code == UNORDERED_EXPR)
{
if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
if (!HONOR_NANS (arg0))
return omit_two_operands_loc (loc, type, integer_zero_node, arg0, arg1);
return fold_build2_loc (loc, UNORDERED_EXPR, type, arg0, arg1);
}
code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
: ordered_code;
code = HONOR_NANS (arg0) ? unordered_code : ordered_code;
return fold_build1_loc (loc, TRUTH_NOT_EXPR, type,
fold_build2_loc (loc, code, type, arg0, arg1));
}

View File

@ -2592,7 +2592,7 @@ combine_comparisons (location_t loc,
enum tree_code rcode, tree truth_type,
tree ll_arg, tree lr_arg)
{
bool honor_nans = HONOR_NANS (element_mode (ll_arg));
bool honor_nans = HONOR_NANS (ll_arg);
enum comparison_code lcompcode = comparison_to_compcode (lcode);
enum comparison_code rcompcode = comparison_to_compcode (rcode);
int compcode;
@ -3376,7 +3376,7 @@ fold_truth_not_expr (location_t loc, tree arg)
&& code != NE_EXPR && code != EQ_EXPR)
return NULL_TREE;
code = invert_tree_comparison (code, HONOR_NANS (TYPE_MODE (op_type)));
code = invert_tree_comparison (code, HONOR_NANS (op_type));
if (code == ERROR_MARK)
return NULL_TREE;
@ -4988,7 +4988,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type,
operand which will be used if they are equal first
so that we can convert this back to the
corresponding COND_EXPR. */
if (!HONOR_NANS (element_mode (arg1)))
if (!HONOR_NANS (arg1))
{
comp_op0 = fold_convert_loc (loc, comp_type, comp_op0);
comp_op1 = fold_convert_loc (loc, comp_type, comp_op1);
@ -5004,7 +5004,7 @@ fold_cond_expr_with_comparison (location_t loc, tree type,
case GT_EXPR:
case UNGE_EXPR:
case UNGT_EXPR:
if (!HONOR_NANS (element_mode (arg1)))
if (!HONOR_NANS (arg1))
{
comp_op0 = fold_convert_loc (loc, comp_type, comp_op0);
comp_op1 = fold_convert_loc (loc, comp_type, comp_op1);
@ -5017,12 +5017,12 @@ fold_cond_expr_with_comparison (location_t loc, tree type,
}
break;
case UNEQ_EXPR:
if (!HONOR_NANS (element_mode (arg1)))
if (!HONOR_NANS (arg1))
return pedantic_non_lvalue_loc (loc,
fold_convert_loc (loc, type, arg2));
break;
case LTGT_EXPR:
if (!HONOR_NANS (element_mode (arg1)))
if (!HONOR_NANS (arg1))
return pedantic_non_lvalue_loc (loc,
fold_convert_loc (loc, type, arg1));
break;
@ -5317,7 +5317,7 @@ merge_truthop_with_opposite_arm (location_t loc, tree op, tree cmpop,
}
}
inv_code = invert_tree_comparison (code, HONOR_NANS (TYPE_MODE (type)));
inv_code = invert_tree_comparison (code, HONOR_NANS (type));
if (inv_code == rhs_code
&& operand_equal_p (TREE_OPERAND (rhs, 0), TREE_OPERAND (cmpop, 0), 0)
&& operand_equal_p (TREE_OPERAND (rhs, 1), TREE_OPERAND (cmpop, 1), 0))
@ -9254,14 +9254,14 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
{
case EQ_EXPR:
if (! FLOAT_TYPE_P (TREE_TYPE (arg0))
|| ! HONOR_NANS (element_mode (arg0)))
|| ! HONOR_NANS (arg0))
return constant_boolean_node (1, type);
break;
case GE_EXPR:
case LE_EXPR:
if (! FLOAT_TYPE_P (TREE_TYPE (arg0))
|| ! HONOR_NANS (element_mode (arg0)))
|| ! HONOR_NANS (arg0))
return constant_boolean_node (1, type);
return fold_build2_loc (loc, EQ_EXPR, type, arg0, arg1);
@ -9269,7 +9269,7 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
/* For NE, we can only do this simplification if integer
or we don't honor IEEE floating point NaNs. */
if (FLOAT_TYPE_P (TREE_TYPE (arg0))
&& HONOR_NANS (element_mode (arg0)))
&& HONOR_NANS (arg0))
break;
/* ... fall through ... */
case GT_EXPR:
@ -10748,7 +10748,7 @@ fold_binary_loc (location_t loc,
/* Fold z * +-I to __complex__ (-+__imag z, +-__real z).
This is not the same for NaNs or if signed zeros are
involved. */
if (!HONOR_NANS (element_mode (arg0))
if (!HONOR_NANS (arg0)
&& !HONOR_SIGNED_ZEROS (element_mode (arg0))
&& COMPLEX_FLOAT_TYPE_P (TREE_TYPE (arg0))
&& TREE_CODE (arg1) == COMPLEX_CST
@ -11680,7 +11680,7 @@ fold_binary_loc (location_t loc,
tree arg00 = CALL_EXPR_ARG (arg0, 0);
tree arg01 = CALL_EXPR_ARG (arg1, 0);
if (! HONOR_NANS (element_mode (arg00))
if (! HONOR_NANS (arg00)
&& ! HONOR_INFINITIES (element_mode (arg00))
&& operand_equal_p (arg00, arg01, 0))
{
@ -11700,7 +11700,7 @@ fold_binary_loc (location_t loc,
tree arg00 = CALL_EXPR_ARG (arg0, 0);
tree arg01 = CALL_EXPR_ARG (arg1, 0);
if (! HONOR_NANS (element_mode (arg00))
if (! HONOR_NANS (arg00)
&& ! HONOR_INFINITIES (element_mode (arg00))
&& operand_equal_p (arg00, arg01, 0))
{
@ -12842,7 +12842,7 @@ fold_binary_loc (location_t loc,
}
/* Convert (X - c) <= X to true. */
if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1)))
if (!HONOR_NANS (arg1)
&& code == LE_EXPR
&& ((code0 == MINUS_EXPR && is_positive >= 0)
|| (code0 == PLUS_EXPR && is_positive <= 0)))
@ -12857,7 +12857,7 @@ fold_binary_loc (location_t loc,
}
/* Convert (X + c) >= X to true. */
if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1)))
if (!HONOR_NANS (arg1)
&& code == GE_EXPR
&& ((code0 == PLUS_EXPR && is_positive >= 0)
|| (code0 == MINUS_EXPR && is_positive <= 0)))
@ -13064,7 +13064,7 @@ fold_binary_loc (location_t loc,
strict_overflow_p = false;
if (code == GE_EXPR
&& (integer_zerop (arg1)
|| (! HONOR_NANS (element_mode (arg0))
|| (! HONOR_NANS (arg0)
&& real_zerop (arg1)))
&& tree_expr_nonnegative_warnv_p (arg0, &strict_overflow_p))
{

View File

@ -1062,7 +1062,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 (GET_MODE (if_info->x))
if (HONOR_NANS (if_info->x)
|| HONOR_SIGNED_ZEROS (GET_MODE (if_info->x)))
return FALSE;
@ -1955,7 +1955,7 @@ noce_try_minmax (struct noce_if_info *if_info)
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))
|| HONOR_NANS (GET_MODE (if_info->x)))
|| HONOR_NANS (if_info->x))
return FALSE;
cond = noce_get_alt_condition (if_info, if_info->a, &earliest);

View File

@ -379,9 +379,8 @@ add_clause (conditions conditions, struct predicate *p, clause_t clause)
&& cc1->val == cc2->val
&& cc2->code != IS_NOT_CONSTANT
&& cc2->code != CHANGED
&& cc1->code == invert_tree_comparison
(cc2->code,
HONOR_NANS (TYPE_MODE (TREE_TYPE (cc1->val)))))
&& cc1->code == invert_tree_comparison (cc2->code,
HONOR_NANS (cc1->val)))
return;
}
}
@ -1762,9 +1761,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info,
if (unmodified_parm_or_parm_agg_item (info, last, op, &index, &aggpos))
{
code = gimple_cond_code (last);
inverted_code
= invert_tree_comparison (code,
HONOR_NANS (TYPE_MODE (TREE_TYPE (op))));
inverted_code = invert_tree_comparison (code, HONOR_NANS (op));
FOR_EACH_EDGE (e, ei, bb->succs)
{

View File

@ -73,7 +73,7 @@ along with GCC; see the file COPYING3. If not see
is volatile. */
(simplify
(minus @0 @0)
(if (!FLOAT_TYPE_P (type) || !HONOR_NANS (element_mode (type)))
(if (!FLOAT_TYPE_P (type) || !HONOR_NANS (type))
{ build_zero_cst (type); }))
(simplify
@ -86,8 +86,7 @@ along with GCC; see the file COPYING3. If not see
negative value by 0 gives -0, not +0. */
(simplify
(mult @0 real_zerop@1)
(if (!HONOR_NANS (element_mode (type))
&& !HONOR_SIGNED_ZEROS (element_mode (type)))
(if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (element_mode (type)))
@1))
/* In IEEE floating point, x*1 is not equivalent to x for snans.
@ -150,7 +149,7 @@ along with GCC; see the file COPYING3. If not see
(simplify
(rdiv @0 @0)
(if (FLOAT_TYPE_P (type)
&& ! HONOR_NANS (element_mode (type))
&& ! HONOR_NANS (type)
&& ! HONOR_INFINITIES (element_mode (type)))
{ build_one_cst (type); }))
@ -159,7 +158,7 @@ along with GCC; see the file COPYING3. If not see
(simplify
(rdiv:c @0 (negate @0))
(if (FLOAT_TYPE_P (type)
&& ! HONOR_NANS (element_mode (type))
&& ! HONOR_NANS (type)
&& ! HONOR_INFINITIES (element_mode (type)))
{ build_minus_one_cst (type); }))
@ -905,7 +904,7 @@ along with GCC; see the file COPYING3. If not see
a computed operator in the replacement tree thus we have
to play the trick below. */
(with { enum tree_code ic = invert_tree_comparison
(cmp, HONOR_NANS (element_mode (@0))); }
(cmp, HONOR_NANS (@0)); }
(if (ic == icmp)
(icmp @0 @1))
(if (ic == ncmp)
@ -913,7 +912,7 @@ along with GCC; see the file COPYING3. If not see
(simplify
(bit_xor (cmp @0 @1) integer_truep)
(with { enum tree_code ic = invert_tree_comparison
(cmp, HONOR_NANS (element_mode (@0))); }
(cmp, HONOR_NANS (@0)); }
(if (ic == icmp)
(icmp @0 @1))
(if (ic == ncmp)

View File

@ -30,6 +30,8 @@
#include "tm_p.h"
#include "dfp.h"
#include "wide-int.h"
#include "rtl.h"
#include "options.h"
/* The floating point model used internally is not exactly IEEE 754
compliant, and close to the description in the ISO C99 standard,
@ -4982,3 +4984,25 @@ get_max_float (const struct real_format *fmt, char *buf, size_t len)
gcc_assert (strlen (buf) < len);
}
/* True if mode M has a NaN representation and
the treatment of NaN operands is important. */
bool
HONOR_NANS (machine_mode m)
{
return MODE_HAS_NANS (m) && !flag_finite_math_only;
}
bool
HONOR_NANS (const_tree t)
{
return HONOR_NANS (element_mode (t));
}
bool
HONOR_NANS (const_rtx x)
{
return HONOR_NANS (GET_MODE (x));
}

View File

@ -200,8 +200,9 @@ extern const struct real_format *
x * 0 into 0, are not correct for NaN operands, and are normally
disabled for modes with NaNs. The user can ask for them to be
done anyway using the -funsafe-math-optimizations switch. */
#define HONOR_NANS(MODE) \
(MODE_HAS_NANS (MODE) && !flag_finite_math_only)
extern bool HONOR_NANS (machine_mode);
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))

View File

@ -2552,12 +2552,12 @@ may_trap_p_1 (const_rtx x, unsigned flags)
when COMPARE is used, though many targets do make this distinction.
For instance, sparc uses CCFPE for compares which generate exceptions
and CCFP for compares which do not generate exceptions. */
if (HONOR_NANS (GET_MODE (x)))
if (HONOR_NANS (x))
return 1;
/* But often the compare has some CC mode, so check operand
modes as well. */
if (HONOR_NANS (GET_MODE (XEXP (x, 0)))
|| HONOR_NANS (GET_MODE (XEXP (x, 1))))
if (HONOR_NANS (XEXP (x, 0))
|| HONOR_NANS (XEXP (x, 1)))
return 1;
break;
@ -2573,7 +2573,7 @@ may_trap_p_1 (const_rtx x, unsigned flags)
case FIX:
/* Conversion of floating point might trap. */
if (flag_trapping_math && HONOR_NANS (GET_MODE (XEXP (x, 0))))
if (flag_trapping_math && HONOR_NANS (XEXP (x, 0)))
return 1;
break;

View File

@ -4754,7 +4754,7 @@ simplify_const_relational_operation (enum rtx_code code,
result except if they have side-effects. Even with NaNs we know
the result of unordered comparisons and, if signaling NaNs are
irrelevant, also the result of LT/GT/LTGT. */
if ((! HONOR_NANS (GET_MODE (trueop0))
if ((! HONOR_NANS (trueop0)
|| code == UNEQ || code == UNLE || code == UNGE
|| ((code == LT || code == GT || code == LTGT)
&& ! HONOR_SNANS (GET_MODE (trueop0))))

View File

@ -311,7 +311,7 @@ parse_predicate (tree cond, tree *op0, tree *op1)
enum tree_code code = parse_predicate (op, op0, op1);
return code == ERROR_MARK ? ERROR_MARK
: invert_tree_comparison (code, HONOR_NANS (TYPE_MODE (type)));
: invert_tree_comparison (code, HONOR_NANS (type));
}
return ERROR_MARK;

View File

@ -458,13 +458,13 @@ valid_lattice_transition (ccp_prop_value_t old_val, ccp_prop_value_t new_val)
to non-NaN. */
tree type = TREE_TYPE (new_val.value);
if (SCALAR_FLOAT_TYPE_P (type)
&& !HONOR_NANS (TYPE_MODE (type)))
&& !HONOR_NANS (type))
{
if (REAL_VALUE_ISNAN (TREE_REAL_CST (old_val.value)))
return true;
}
else if (VECTOR_FLOAT_TYPE_P (type)
&& !HONOR_NANS (TYPE_MODE (TREE_TYPE (type))))
&& !HONOR_NANS (type))
{
for (unsigned i = 0; i < VECTOR_CST_NELTS (old_val.value); ++i)
if (!REAL_VALUE_ISNAN
@ -475,7 +475,7 @@ valid_lattice_transition (ccp_prop_value_t old_val, ccp_prop_value_t new_val)
return true;
}
else if (COMPLEX_FLOAT_TYPE_P (type)
&& !HONOR_NANS (TYPE_MODE (TREE_TYPE (type))))
&& !HONOR_NANS (type))
{
if (!REAL_VALUE_ISNAN (TREE_REAL_CST (TREE_REALPART (old_val.value)))
&& !operand_equal_p (TREE_REALPART (old_val.value),

View File

@ -519,12 +519,12 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
/* Invert comparisons if necessary (and possible). */
if (inner_inv)
inner_cond_code = invert_tree_comparison (inner_cond_code,
HONOR_NANS (TYPE_MODE (TREE_TYPE (gimple_cond_lhs (inner_cond)))));
HONOR_NANS (gimple_cond_lhs (inner_cond)));
if (inner_cond_code == ERROR_MARK)
return false;
if (outer_inv)
outer_cond_code = invert_tree_comparison (outer_cond_code,
HONOR_NANS (TYPE_MODE (TREE_TYPE (gimple_cond_lhs (outer_cond)))));
HONOR_NANS (gimple_cond_lhs (outer_cond)));
if (outer_cond_code == ERROR_MARK)
return false;
/* Don't return false so fast, try maybe_fold_or_comparisons? */

View File

@ -932,7 +932,7 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
type = TREE_TYPE (PHI_RESULT (phi));
/* The optimization may be unsafe due to NaNs. */
if (HONOR_NANS (TYPE_MODE (type)))
if (HONOR_NANS (type))
return false;
cond = as_a <gcond *> (last_stmt (cond_bb));
@ -1355,8 +1355,7 @@ neg_replacement (basic_block cond_bb, basic_block middle_bb,
that's cheapest. */
if (invert)
{
bool honor_nans
= HONOR_NANS (TYPE_MODE (TREE_TYPE (gimple_cond_lhs (cond))));
bool honor_nans = HONOR_NANS (gimple_cond_lhs (cond));
enum tree_code new_code = invert_tree_comparison (cond_code, honor_nans);
/* If invert_tree_comparison was successful, then use its return

View File

@ -966,7 +966,7 @@ eliminate_using_constants (enum tree_code opcode,
case MULT_EXPR:
if (integer_zerop (oelast->op)
|| (FLOAT_TYPE_P (type)
&& !HONOR_NANS (TYPE_MODE (type))
&& !HONOR_NANS (type)
&& !HONOR_SIGNED_ZEROS (TYPE_MODE (type))
&& real_zerop (oelast->op)))
{

View File

@ -1197,8 +1197,7 @@ gimple_equal_p (same_succ same_succ, gimple s1, gimple s2)
!= bitmap_bit_p (same_succ->inverse, bb2->index));
if (inv_cond)
{
bool honor_nans
= HONOR_NANS (TYPE_MODE (TREE_TYPE (gimple_cond_lhs (s1))));
bool honor_nans = HONOR_NANS (t1);
code2 = invert_tree_comparison (code2, honor_nans);
}
return code1 == code2;