[multiple changes]
2006-12-01 Zdenek Dvorak <dvorakz@suse.cz> PR tree-optimization/29921 * tree-ssa-ccp.c (canonicalize_float_value): New function. (set_lattice_value): Use canonicalize_float_value. 2006-12-01 H.J. Lu <hongjiu.lu@intel.com> Zdenek Dvorak <dvorakz@suse.cz> PR tree-optimization/29921 * gcc.dg/pr29921-2.c: New test. From-SVN: r119401
This commit is contained in:
parent
b66b813d47
commit
fbb5445b5d
4 changed files with 89 additions and 0 deletions
|
@ -1,3 +1,9 @@
|
|||
2006-12-01 Zdenek Dvorak <dvorakz@suse.cz>
|
||||
|
||||
PR tree-optimization/29921
|
||||
* tree-ssa-ccp.c (canonicalize_float_value): New function.
|
||||
(set_lattice_value): Use canonicalize_float_value.
|
||||
|
||||
2006-11-30 Andrew Pinski <andrew_pinski@playstation.sony.com>
|
||||
|
||||
* config/spu/spu.c (spu_builtin_range): Move from spu-c.c
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2006-12-01 H.J. Lu <hongjiu.lu@intel.com>
|
||||
Zdenek Dvorak <dvorakz@suse.cz>
|
||||
|
||||
PR tree-optimization/29921
|
||||
* gcc.dg/pr29921-2.c: New test.
|
||||
|
||||
2006-11-30 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* gcc.dg/i386-cpuid.h (bit_SSE3): New.
|
||||
|
|
27
gcc/testsuite/gcc.dg/pr29921-2.c
Normal file
27
gcc/testsuite/gcc.dg/pr29921-2.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
/* With -ffast-math, the latice value for sum2 used to change from NaN to
|
||||
VARYING, in turn causing the lattice value of sum1 * sum2 change from
|
||||
NaN to 0 (since sum1 is believed to be 0 at that moment, and
|
||||
0 * VARYING = 0 with -ffast-math), which caused an ICE. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -ffast-math" } */
|
||||
|
||||
int
|
||||
foo (float *array, int end)
|
||||
{
|
||||
int i;
|
||||
float sum1, sum2;
|
||||
|
||||
sum2 = 0;
|
||||
for (i = 0; i < end; i++)
|
||||
sum2 = sum2+array[i];
|
||||
sum2 = 1./sum2;
|
||||
sum1 = 0.;
|
||||
for (i = 0; i < end; i++)
|
||||
sum1 = sum1+array[i];
|
||||
sum1 = sum1 * sum2;
|
||||
if (-10.0 / sum1 < 5.E-5)
|
||||
end = 0;
|
||||
return end;
|
||||
}
|
||||
|
|
@ -418,6 +418,54 @@ set_value_varying (tree var)
|
|||
val->mem_ref = NULL_TREE;
|
||||
}
|
||||
|
||||
/* For float types, modify the value of VAL to make ccp work correctly
|
||||
for non-standard values (-0, NaN):
|
||||
|
||||
If HONOR_SIGNED_ZEROS is false, and VAL = -0, we canonicalize it to 0.
|
||||
If HONOR_NANS is false, and VAL is NaN, we canonicalize it to UNDEFINED.
|
||||
This is to fix the following problem (see PR 29921): Suppose we have
|
||||
|
||||
x = 0.0 * y
|
||||
|
||||
and we set value of y to NaN. This causes value of x to be set to NaN.
|
||||
When we later determine that y is in fact VARYING, fold uses the fact
|
||||
that HONOR_NANS is false, and we try to change the value of x to 0,
|
||||
causing an ICE. With HONOR_NANS being false, the real appearance of
|
||||
NaN would cause undefined behavior, though, so claiming that y (and x)
|
||||
are UNDEFINED initially is correct. */
|
||||
|
||||
static void
|
||||
canonicalize_float_value (prop_value_t *val)
|
||||
{
|
||||
enum machine_mode mode;
|
||||
tree type;
|
||||
REAL_VALUE_TYPE d;
|
||||
|
||||
if (val->lattice_val != CONSTANT
|
||||
|| TREE_CODE (val->value) != REAL_CST)
|
||||
return;
|
||||
|
||||
d = TREE_REAL_CST (val->value);
|
||||
type = TREE_TYPE (val->value);
|
||||
mode = TYPE_MODE (type);
|
||||
|
||||
if (!HONOR_SIGNED_ZEROS (mode)
|
||||
&& REAL_VALUE_MINUS_ZERO (d))
|
||||
{
|
||||
val->value = build_real (type, dconst0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!HONOR_NANS (mode)
|
||||
&& REAL_VALUE_ISNAN (d))
|
||||
{
|
||||
val->lattice_val = UNDEFINED;
|
||||
val->value = NULL;
|
||||
val->mem_ref = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the value for variable VAR to NEW_VAL. Return true if the new
|
||||
value is different from VAR's previous value. */
|
||||
|
||||
|
@ -426,6 +474,8 @@ set_lattice_value (tree var, prop_value_t new_val)
|
|||
{
|
||||
prop_value_t *old_val = get_value (var);
|
||||
|
||||
canonicalize_float_value (&new_val);
|
||||
|
||||
/* Lattice transitions must always be monotonically increasing in
|
||||
value. If *OLD_VAL and NEW_VAL are the same, return false to
|
||||
inform the caller that this was a non-transition. */
|
||||
|
|
Loading…
Add table
Reference in a new issue