mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-24 05:58:56 +08:00
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:
parent
35c77862c9
commit
3e4093b64f
@ -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
|
||||
|
1463
gcc/c-typeck.c
1463
gcc/c-typeck.c
File diff suppressed because it is too large
Load Diff
@ -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.
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user