From 858214db144c6a1f271021102a6315ad1ecd9f51 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Sun, 25 Jun 2006 17:16:25 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 ++ gcc/fold-const.c | 82 ++++++++++-------------- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.c-torture/compile/20060625-1.c | 10 +++ 4 files changed, 54 insertions(+), 48 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/20060625-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6c8caa0..25513c6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2006-06-25 Eric Botcazou + + 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 * gimplify.c (gimplify_scalar_mode_aggregate_compare): New function. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index b54658d..5c592c3 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -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, - const_binop (MULT_EXPR, r1, r2, notrunc), - const_binop (MULT_EXPR, i1, i2, notrunc), - notrunc); - t2 = const_binop (MINUS_EXPR, - const_binop (MULT_EXPR, i1, r2, notrunc), - const_binop (MULT_EXPR, r1, i2, notrunc), - notrunc); + tree t1 + = const_binop (PLUS_EXPR, + const_binop (MULT_EXPR, r1, r2, notrunc), + const_binop (MULT_EXPR, i1, i2, notrunc), + notrunc); + 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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 644b44e..f1e1480 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2006-06-25 Eric Botcazou + + * gcc.c-torture/compile/20060625-1.c: New test. + 2006-06-25 Paul Thomas PR fortran/20867 diff --git a/gcc/testsuite/gcc.c-torture/compile/20060625-1.c b/gcc/testsuite/gcc.c-torture/compile/20060625-1.c new file mode 100644 index 0000000..37efb9d --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20060625-1.c @@ -0,0 +1,10 @@ +/* PR middle-end/28151 */ +/* Testcase by Steven Bosscher */ + +_Complex float b; + +void foo (void) +{ + _Complex float a = __FLT_MAX__; + b = __FLT_MAX__ + a; +} -- 2.7.4