fold-const.c (const_binop): Avoid performing the FP operation at compile-time...

* fold-const.c (const_binop): Avoid performing the FP operation at
	compile-time, if either operand is NaN and we honor signaling NaNs,
	or if we're dividing by zero and either flag_trapping_math is set
	or the desired mode doesn't support infinities.
	(fold_initializer): New function to fold an expression ignoring any
	potential run-time exceptions or traps.
	* tree.h (fold_initializer): Prototype here.
	* c-typeck.c (build_binary_op): Move to the end of the file so
	that intializer_stack is in scope.  If constructing an initializer,
	i.e. when initializer_stack is not NULL, use fold_initializer to
	fold expressions.
	* simplify-rtx.c (simplify_binary_operation): Likewise, avoid
	performing FP operations at compile-time, if they would raise an
	exception at run-time.

From-SVN: r69533
This commit is contained in:
Roger Sayle 2003-07-18 00:26:51 +00:00 committed by Roger Sayle
parent 35c77862c9
commit 3e4093b64f
5 changed files with 801 additions and 736 deletions

View File

@ -1,3 +1,20 @@
2003-07-17 Roger Sayle <roger@eyesopen.com>
* fold-const.c (const_binop): Avoid performing the FP operation at
compile-time, if either operand is NaN and we honor signaling NaNs,
or if we're dividing by zero and either flag_trapping_math is set
or the desired mode doesn't support infinities.
(fold_initializer): New function to fold an expression ignoring any
potential run-time exceptions or traps.
* tree.h (fold_initializer): Prototype here.
* c-typeck.c (build_binary_op): Move to the end of the file so
that intializer_stack is in scope. If constructing an initializer,
i.e. when initializer_stack is not NULL, use fold_initializer to
fold expressions.
* simplify-rtx.c (simplify_binary_operation): Likewise, avoid
performing FP operations at compile-time, if they would raise an
exception at run-time.
2003-07-17 Geoffrey Keating <geoffk@apple.com>
PR 11498

File diff suppressed because it is too large Load Diff

View File

@ -1228,14 +1228,31 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
if (TREE_CODE (arg1) == REAL_CST)
{
enum machine_mode mode;
REAL_VALUE_TYPE d1;
REAL_VALUE_TYPE d2;
REAL_VALUE_TYPE value;
tree t;
tree t, type;
d1 = TREE_REAL_CST (arg1);
d2 = TREE_REAL_CST (arg2);
type = TREE_TYPE (arg1);
mode = TYPE_MODE (type);
/* Don't perform operation if we honor signaling NaNs and
either operand is a NaN. */
if (HONOR_SNANS (mode)
&& (REAL_VALUE_ISNAN (d1) || REAL_VALUE_ISNAN (d2)))
return NULL_TREE;
/* Don't perform operation if it would raise a division
by zero exception. */
if (code == RDIV_EXPR
&& REAL_VALUES_EQUAL (d2, dconst0)
&& (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
return NULL_TREE;
/* If either operand is a NaN, just return it. Otherwise, set up
for floating-point trap; we return an overflow. */
if (REAL_VALUE_ISNAN (d1))
@ -1245,9 +1262,7 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
REAL_ARITHMETIC (value, code, d1, d2);
t = build_real (TREE_TYPE (arg1),
real_value_truncate (TYPE_MODE (TREE_TYPE (arg1)),
value));
t = build_real (type, real_value_truncate (mode, value));
TREE_OVERFLOW (t)
= (force_fit_type (t, 0)
@ -7886,6 +7901,31 @@ fold (tree expr)
} /* switch (code) */
}
/* Perform constant folding and related simplification of intializer
expression EXPR. This behaves identically to "fold" but ignores
potential run-time traps and exceptions that fold must preserve. */
tree
fold_initializer (tree expr)
{
int saved_signaling_nans = flag_signaling_nans;
int saved_trapping_math = flag_trapping_math;
int saved_trapv = flag_trapv;
tree result;
flag_signaling_nans = 0;
flag_trapping_math = 0;
flag_trapv = 0;
result = fold (expr);
flag_signaling_nans = saved_signaling_nans;
flag_trapping_math = saved_trapping_math;
flag_trapv = saved_trapv;
return result;
}
/* Determine if first argument is a multiple of second argument. Return 0 if
it is not, or we cannot easily determined it to be.

View File

@ -929,9 +929,13 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
f0 = real_value_truncate (mode, f0);
f1 = real_value_truncate (mode, f1);
if (HONOR_SNANS (mode)
&& (REAL_VALUE_ISNAN (f0) || REAL_VALUE_ISNAN (f1)))
return 0;
if (code == DIV
&& !MODE_HAS_INFINITIES (mode)
&& REAL_VALUES_EQUAL (f1, dconst0))
&& REAL_VALUES_EQUAL (f1, dconst0)
&& (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
return 0;
REAL_ARITHMETIC (value, rtx_to_tree_code (code), f0, f1);

View File

@ -2715,6 +2715,7 @@ extern void using_eh_for_cleanups (void);
subexpressions are not changed. */
extern tree fold (tree);
extern tree fold_initializer (tree);
extern tree fold_single_bit_test (enum tree_code, tree, tree, tree);
extern int force_fit_type (tree, int);