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> 2006-06-24 Olivier Hainque <hainque@adacore.com>
* gimplify.c (gimplify_scalar_mode_aggregate_compare): New function. * 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) ...@@ -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 /* 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 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. */ If NOTRUNC is nonzero, do not truncate the result to fit the data type. */
static tree static tree
const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc) 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 (arg1);
STRIP_NOPS (arg2); STRIP_NOPS (arg2);
...@@ -1613,7 +1618,6 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc) ...@@ -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 /* Don't constant fold this floating point operation if
the result has overflowed and flag_trapping_math. */ the result has overflowed and flag_trapping_math. */
if (flag_trapping_math if (flag_trapping_math
&& MODE_HAS_INFINITIES (mode) && MODE_HAS_INFINITIES (mode)
&& REAL_VALUE_ISINF (result) && REAL_VALUE_ISINF (result)
...@@ -1625,7 +1629,6 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc) ...@@ -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 result may dependent upon the run-time rounding mode and
flag_rounding_math is set, or if GCC's software emulation flag_rounding_math is set, or if GCC's software emulation
is unable to accurately represent the result. */ is unable to accurately represent the result. */
if ((flag_rounding_math if ((flag_rounding_math
|| (REAL_MODE_FORMAT_COMPOSITE_P (mode) || (REAL_MODE_FORMAT_COMPOSITE_P (mode)
&& !flag_unsafe_math_optimizations)) && !flag_unsafe_math_optimizations))
...@@ -1649,78 +1652,61 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc) ...@@ -1649,78 +1652,61 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
tree i1 = TREE_IMAGPART (arg1); tree i1 = TREE_IMAGPART (arg1);
tree r2 = TREE_REALPART (arg2); tree r2 = TREE_REALPART (arg2);
tree i2 = TREE_IMAGPART (arg2); tree i2 = TREE_IMAGPART (arg2);
tree t; tree real, imag;
switch (code) switch (code)
{ {
case PLUS_EXPR: 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: case MINUS_EXPR:
t = build_complex (type, real = const_binop (code, r1, r2, notrunc);
const_binop (MINUS_EXPR, r1, r2, notrunc), imag = const_binop (code, i1, i2, notrunc);
const_binop (MINUS_EXPR, i1, i2, notrunc));
break; break;
case MULT_EXPR: case MULT_EXPR:
t = build_complex (type, real = const_binop (MINUS_EXPR,
const_binop (MINUS_EXPR, const_binop (MULT_EXPR, r1, r2, notrunc),
const_binop (MULT_EXPR, const_binop (MULT_EXPR, i1, i2, notrunc),
r1, r2, notrunc), notrunc);
const_binop (MULT_EXPR, imag = const_binop (PLUS_EXPR,
i1, i2, notrunc), const_binop (MULT_EXPR, r1, i2, notrunc),
notrunc), const_binop (MULT_EXPR, i1, r2, notrunc),
const_binop (PLUS_EXPR, notrunc);
const_binop (MULT_EXPR,
r1, i2, notrunc),
const_binop (MULT_EXPR,
i1, r2, notrunc),
notrunc));
break; break;
case RDIV_EXPR: case RDIV_EXPR:
{ {
tree t1, t2, real, imag;
tree magsquared tree magsquared
= const_binop (PLUS_EXPR, = const_binop (PLUS_EXPR,
const_binop (MULT_EXPR, r2, r2, notrunc), const_binop (MULT_EXPR, r2, r2, notrunc),
const_binop (MULT_EXPR, i2, i2, notrunc), const_binop (MULT_EXPR, i2, i2, notrunc),
notrunc); notrunc);
tree t1
t1 = const_binop (PLUS_EXPR, = const_binop (PLUS_EXPR,
const_binop (MULT_EXPR, r1, r2, notrunc), const_binop (MULT_EXPR, r1, r2, notrunc),
const_binop (MULT_EXPR, i1, i2, notrunc), const_binop (MULT_EXPR, i1, i2, notrunc),
notrunc); notrunc);
t2 = const_binop (MINUS_EXPR, tree t2
const_binop (MULT_EXPR, i1, r2, notrunc), = const_binop (MINUS_EXPR,
const_binop (MULT_EXPR, r1, i2, notrunc), const_binop (MULT_EXPR, i1, r2, notrunc),
notrunc); const_binop (MULT_EXPR, r1, i2, notrunc),
notrunc);
if (INTEGRAL_TYPE_P (TREE_TYPE (r1))) if (INTEGRAL_TYPE_P (TREE_TYPE (r1)))
{ code = TRUNC_DIV_EXPR;
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;
}
t = build_complex (type, real, imag); real = const_binop (code, t1, magsquared, notrunc);
imag = const_binop (code, t2, magsquared, notrunc);
} }
break; break;
default: default:
return NULL_TREE; return NULL_TREE;
} }
return t;
if (real && imag)
return build_complex (type, real, imag);
} }
return NULL_TREE; 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> 2006-06-25 Paul Thomas <pault@gcc.gnu.org>
PR fortran/20867 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