OSDN Git Service

PR middle-end/28151
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 25 Jun 2006 17:16:25 +0000 (17:16 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 25 Jun 2006 17:16:25 +0000 (17:16 +0000)
* fold-const.c (const_binop): Be prepared for self returning zero.
Simplify code handling complex values.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@114992 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/20060625-1.c [new file with mode: 0644]

index 6c8caa0..25513c6 100644 (file)
@@ -1,3 +1,9 @@
+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.
index b54658d..5c592c3 100644 (file)
@@ -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;
 }
 
index 644b44e..f1e1480 100644 (file)
@@ -1,3 +1,7 @@
+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
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 (file)
index 0000000..37efb9d
--- /dev/null
@@ -0,0 +1,10 @@
+/* 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;
+}