Commit 858214db by Eric Botcazou Committed by Eric Botcazou

re PR middle-end/28151 (ICE with complex math)

	PR middle-end/28151
	* fold-const.c (const_binop): Be prepared for self returning zero.
	Simplify code handling complex values.

From-SVN: r114992
parent 036d1f6a
2006-06-25 Eric Botcazou <ebotcazou@adacore.com>
PR middle-end/28151
* fold-const.c (const_binop): Be prepared for self returning zero.
Simplify code handling complex values.
2006-06-24 Olivier Hainque <hainque@adacore.com>
* gimplify.c (gimplify_scalar_mode_aggregate_compare): New function.
......
......@@ -1544,13 +1544,18 @@ int_const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
/* Combine two constants ARG1 and ARG2 under operation CODE to produce a new
constant. We assume ARG1 and ARG2 have the same data type, or at least
are the same kind of constant and the same machine mode.
are the same kind of constant and the same machine mode. Return zero if
combining the constants is not allowed in the current operating mode.
If NOTRUNC is nonzero, do not truncate the result to fit the data type. */
static tree
const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
{
/* Sanity check for the recursive cases. */
if (!arg1 || !arg2)
return NULL_TREE;
STRIP_NOPS (arg1);
STRIP_NOPS (arg2);
......@@ -1613,7 +1618,6 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
/* Don't constant fold this floating point operation if
the result has overflowed and flag_trapping_math. */
if (flag_trapping_math
&& MODE_HAS_INFINITIES (mode)
&& REAL_VALUE_ISINF (result)
......@@ -1625,7 +1629,6 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
result may dependent upon the run-time rounding mode and
flag_rounding_math is set, or if GCC's software emulation
is unable to accurately represent the result. */
if ((flag_rounding_math
|| (REAL_MODE_FORMAT_COMPOSITE_P (mode)
&& !flag_unsafe_math_optimizations))
......@@ -1649,78 +1652,61 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
tree i1 = TREE_IMAGPART (arg1);
tree r2 = TREE_REALPART (arg2);
tree i2 = TREE_IMAGPART (arg2);
tree t;
tree real, imag;
switch (code)
{
case PLUS_EXPR:
t = build_complex (type,
const_binop (PLUS_EXPR, r1, r2, notrunc),
const_binop (PLUS_EXPR, i1, i2, notrunc));
break;
case MINUS_EXPR:
t = build_complex (type,
const_binop (MINUS_EXPR, r1, r2, notrunc),
const_binop (MINUS_EXPR, i1, i2, notrunc));
real = const_binop (code, r1, r2, notrunc);
imag = const_binop (code, i1, i2, notrunc);
break;
case MULT_EXPR:
t = build_complex (type,
const_binop (MINUS_EXPR,
const_binop (MULT_EXPR,
r1, r2, notrunc),
const_binop (MULT_EXPR,
i1, i2, notrunc),
notrunc),
const_binop (PLUS_EXPR,
const_binop (MULT_EXPR,
r1, i2, notrunc),
const_binop (MULT_EXPR,
i1, r2, notrunc),
notrunc));
real = const_binop (MINUS_EXPR,
const_binop (MULT_EXPR, r1, r2, notrunc),
const_binop (MULT_EXPR, i1, i2, notrunc),
notrunc);
imag = const_binop (PLUS_EXPR,
const_binop (MULT_EXPR, r1, i2, notrunc),
const_binop (MULT_EXPR, i1, r2, notrunc),
notrunc);
break;
case RDIV_EXPR:
{
tree t1, t2, real, imag;
tree magsquared
= const_binop (PLUS_EXPR,
const_binop (MULT_EXPR, r2, r2, notrunc),
const_binop (MULT_EXPR, i2, i2, notrunc),
notrunc);
t1 = const_binop (PLUS_EXPR,
tree t1
= const_binop (PLUS_EXPR,
const_binop (MULT_EXPR, r1, r2, notrunc),
const_binop (MULT_EXPR, i1, i2, notrunc),
notrunc);
t2 = const_binop (MINUS_EXPR,
tree t2
= const_binop (MINUS_EXPR,
const_binop (MULT_EXPR, i1, r2, notrunc),
const_binop (MULT_EXPR, r1, i2, notrunc),
notrunc);
if (INTEGRAL_TYPE_P (TREE_TYPE (r1)))
{
real = const_binop (TRUNC_DIV_EXPR, t1, magsquared, notrunc);
imag = const_binop (TRUNC_DIV_EXPR, t2, magsquared, notrunc);
}
else
{
real = const_binop (RDIV_EXPR, t1, magsquared, notrunc);
imag = const_binop (RDIV_EXPR, t2, magsquared, notrunc);
if (!real || !imag)
return NULL_TREE;
}
code = TRUNC_DIV_EXPR;
t = build_complex (type, real, imag);
real = const_binop (code, t1, magsquared, notrunc);
imag = const_binop (code, t2, magsquared, notrunc);
}
break;
default:
return NULL_TREE;
}
return t;
if (real && imag)
return build_complex (type, real, imag);
}
return NULL_TREE;
}
......
2006-06-25 Eric Botcazou <ebotcazou@adacore.com>
* gcc.c-torture/compile/20060625-1.c: New test.
2006-06-25 Paul Thomas <pault@gcc.gnu.org>
PR fortran/20867
/* PR middle-end/28151 */
/* Testcase by Steven Bosscher <stevenb.gcc@gmail.com> */
_Complex float b;
void foo (void)
{
_Complex float a = __FLT_MAX__;
b = __FLT_MAX__ + a;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment