re PR tree-optimization/22035 (complex float comparison broken)
authorRichard Henderson <rth@redhat.com>
Thu, 16 Jun 2005 18:09:34 +0000 (11:09 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 16 Jun 2005 18:09:34 +0000 (11:09 -0700)
        PR tree-opt/22035
        * builtins.c (fold_builtin_complex_mul): Remove.
        (fold_builtin_complex_div): Remove.
        (fold_builtin_1): Don't call them.
        * fold-const.c (fold_complex_add, fold_complex_mult_parts,
        fold_complex_mult, fold_complex_div_parts, fold_complex_div): Remove.
        (fold_binary): Don't call them.  Don't expand complex comparisons to
        elementary comparisons.
        * tree-complex.c (init_dont_simulate_again): Enhance search for
        stmts that require decomposition.
        (complex_visit_stmt): Handle RETURN_EXPR properly.
        (create_components): Handle no referenced variables properly.
        * tree.h (fold_complex_mult_parts): Remove.
        (fold_complex_div_parts): Remove.

From-SVN: r101086

gcc/ChangeLog
gcc/builtins.c
gcc/fold-const.c
gcc/tree-complex.c
gcc/tree.h

index 40e204c462cb7aac5b982b02c4263b7e54bd180a..f3dff19d71eb5b3773db4f5253c7c4b8fee09dbc 100644 (file)
@@ -1,3 +1,20 @@
+2005-06-16  Richard Henderson  <rth@redhat.com>
+
+       PR tree-opt/22035
+       * builtins.c (fold_builtin_complex_mul): Remove.
+       (fold_builtin_complex_div): Remove.
+       (fold_builtin_1): Don't call them.
+       * fold-const.c (fold_complex_add, fold_complex_mult_parts,
+       fold_complex_mult, fold_complex_div_parts, fold_complex_div): Remove.
+       (fold_binary): Don't call them.  Don't expand complex comparisons to
+       elementary comparisons.
+       * tree-complex.c (init_dont_simulate_again): Enhance search for 
+       stmts that require decomposition.
+       (complex_visit_stmt): Handle RETURN_EXPR properly.
+       (create_components): Handle no referenced variables properly.
+       * tree.h (fold_complex_mult_parts): Remove.
+       (fold_complex_div_parts): Remove.
+
 2005-06-16  Richard Guenther  <rguenth@gcc.gnu.org>
 
        * doc/extend.texi: Document sseregparm target attribute.
index cdc5cebcbc6dea3bcc5c076ebbde0bd488fb803b..b0e3f40a9425541ef5b9df7dd55042240490be6b 100644 (file)
@@ -8430,44 +8430,6 @@ fold_builtin_unordered_cmp (tree fndecl, tree arglist,
                       fold (build2 (code, type, arg0, arg1))));
 }
 
-/* Fold a call to one of the external complex multiply libcalls.  */
-
-static tree
-fold_builtin_complex_mul (tree type, tree arglist)
-{
-  tree ar, ai, br, bi;
-
-  if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, REAL_TYPE,
-                        REAL_TYPE, VOID_TYPE))
-    return NULL;
-
-  ar = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
-  ai = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
-  br = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
-  bi = TREE_VALUE (arglist);
-
-  return fold_complex_mult_parts (type, ar, ai, br, bi);
-}
-
-/* Fold a call to one of the external complex division libcalls.  */
-
-static tree
-fold_builtin_complex_div (tree type, tree arglist)
-{
-  tree ar, ai, br, bi;
-
-  if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, REAL_TYPE,
-                        REAL_TYPE, VOID_TYPE))
-    return NULL;
-
-  ar = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
-  ai = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
-  br = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
-  bi = TREE_VALUE (arglist);
-
-  return fold_complex_div_parts (type, ar, ai, br, bi, RDIV_EXPR);
-}
-
 /* Used by constant folding to simplify calls to builtin functions.  EXP is
    the CALL_EXPR of a call to a builtin function.  IGNORE is true if the
    result of the function call is ignored.  This function returns NULL_TREE
@@ -8826,12 +8788,6 @@ fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
       break;
 
     default:
-      if (fcode >= BUILT_IN_COMPLEX_MUL_MIN
-         && fcode <= BUILT_IN_COMPLEX_MUL_MAX)
-       return fold_builtin_complex_mul (type, arglist);
-      if (fcode >= BUILT_IN_COMPLEX_DIV_MIN
-         && fcode <= BUILT_IN_COMPLEX_DIV_MAX)
-       return fold_builtin_complex_div (type, arglist);
       break;
     }
 
index 2c1bd15b3654501dd34f7aaf777b3dde5231e53c..8433d1dfd9889acee0ad9fe175deaf6c80d5fc0d 100644 (file)
@@ -6493,300 +6493,6 @@ fold_to_nonsharp_ineq_using_bound (tree ineq, tree bound)
   return fold_build2 (GE_EXPR, type, a, y);
 }
 
-/* Fold complex addition when both components are accessible by parts.
-   Return non-null if successful.  CODE should be PLUS_EXPR for addition,
-   or MINUS_EXPR for subtraction.  */
-
-static tree
-fold_complex_add (tree type, tree ac, tree bc, enum tree_code code)
-{
-  tree ar, ai, br, bi, rr, ri, inner_type;
-
-  if (TREE_CODE (ac) == COMPLEX_EXPR)
-    ar = TREE_OPERAND (ac, 0), ai = TREE_OPERAND (ac, 1);
-  else if (TREE_CODE (ac) == COMPLEX_CST)
-    ar = TREE_REALPART (ac), ai = TREE_IMAGPART (ac);
-  else
-    return NULL;
-
-  if (TREE_CODE (bc) == COMPLEX_EXPR)
-    br = TREE_OPERAND (bc, 0), bi = TREE_OPERAND (bc, 1);
-  else if (TREE_CODE (bc) == COMPLEX_CST)
-    br = TREE_REALPART (bc), bi = TREE_IMAGPART (bc);
-  else
-    return NULL;
-
-  inner_type = TREE_TYPE (type);
-
-  rr = fold_build2 (code, inner_type, ar, br); 
-  ri = fold_build2 (code, inner_type, ai, bi); 
-
-  return fold_build2 (COMPLEX_EXPR, type, rr, ri);
-}
-
-/* Perform some simplifications of complex multiplication when one or more
-   of the components are constants or zeros.  Return non-null if successful.  */
-
-tree
-fold_complex_mult_parts (tree type, tree ar, tree ai, tree br, tree bi)
-{
-  tree rr, ri, inner_type, zero;
-  bool ar0, ai0, br0, bi0, bi1;
-
-  inner_type = TREE_TYPE (type);
-  zero = NULL;
-
-  if (SCALAR_FLOAT_TYPE_P (inner_type))
-    {
-      ar0 = ai0 = br0 = bi0 = bi1 = false;
-
-      /* We're only interested in +0.0 here, thus we don't use real_zerop.  */
-
-      if (TREE_CODE (ar) == REAL_CST
-         && REAL_VALUES_IDENTICAL (TREE_REAL_CST (ar), dconst0))
-       ar0 = true, zero = ar;
-
-      if (TREE_CODE (ai) == REAL_CST
-         && REAL_VALUES_IDENTICAL (TREE_REAL_CST (ai), dconst0))
-       ai0 = true, zero = ai;
-
-      if (TREE_CODE (br) == REAL_CST
-         && REAL_VALUES_IDENTICAL (TREE_REAL_CST (br), dconst0))
-       br0 = true, zero = br;
-
-      if (TREE_CODE (bi) == REAL_CST)
-       {
-         if (REAL_VALUES_IDENTICAL (TREE_REAL_CST (bi), dconst0))
-           bi0 = true, zero = bi;
-         else if (REAL_VALUES_IDENTICAL (TREE_REAL_CST (bi), dconst1))
-           bi1 = true;
-       }
-    }
-  else
-    {
-      ar0 = integer_zerop (ar);
-      if (ar0)
-       zero = ar;
-      ai0 = integer_zerop (ai);
-      if (ai0)
-       zero = ai;
-      br0 = integer_zerop (br);
-      if (br0)
-       zero = br;
-      bi0 = integer_zerop (bi);
-      if (bi0)
-       {
-         zero = bi;
-         bi1 = false;
-       }
-      else
-       bi1 = integer_onep (bi);
-    }
-
-  /* We won't optimize anything below unless something is zero.  */
-  if (zero == NULL)
-    return NULL;
-
-  if (ai0 && br0 && bi1)
-    {
-      rr = zero;
-      ri = ar;
-    }
-  else if (ai0 && bi0)
-    {
-      rr = fold_build2 (MULT_EXPR, inner_type, ar, br);
-      ri = zero;
-    }
-  else if (ai0 && br0)
-    {
-      rr = zero;
-      ri = fold_build2 (MULT_EXPR, inner_type, ar, bi);
-    }
-  else if (ar0 && bi0)
-    {
-      rr = zero;
-      ri = fold_build2 (MULT_EXPR, inner_type, ai, br);
-    }
-  else if (ar0 && br0)
-    {
-      rr = fold_build2 (MULT_EXPR, inner_type, ai, bi);
-      rr = fold_build1 (NEGATE_EXPR, inner_type, rr);
-      ri = zero;
-    }
-  else if (bi0)
-    {
-      rr = fold_build2 (MULT_EXPR, inner_type, ar, br);
-      ri = fold_build2 (MULT_EXPR, inner_type, ai, br);
-    }
-  else if (ai0)
-    {
-      rr = fold_build2 (MULT_EXPR, inner_type, ar, br);
-      ri = fold_build2 (MULT_EXPR, inner_type, ar, bi);
-    }
-  else if (br0)
-    {
-      rr = fold_build2 (MULT_EXPR, inner_type, ai, bi);
-      rr = fold_build1 (NEGATE_EXPR, inner_type, rr);
-      ri = fold_build2 (MULT_EXPR, inner_type, ar, bi);
-    }
-  else if (ar0)
-    {
-      rr = fold_build2 (MULT_EXPR, inner_type, ai, bi);
-      rr = fold_build1 (NEGATE_EXPR, inner_type, rr);
-      ri = fold_build2 (MULT_EXPR, inner_type, ai, br);
-    }
-  else
-    return NULL;
-
-  return fold_build2 (COMPLEX_EXPR, type, rr, ri);
-}
-
-static tree
-fold_complex_mult (tree type, tree ac, tree bc)
-{
-  tree ar, ai, br, bi;
-
-  if (TREE_CODE (ac) == COMPLEX_EXPR)
-    ar = TREE_OPERAND (ac, 0), ai = TREE_OPERAND (ac, 1);
-  else if (TREE_CODE (ac) == COMPLEX_CST)
-    ar = TREE_REALPART (ac), ai = TREE_IMAGPART (ac);
-  else
-    return NULL;
-
-  if (TREE_CODE (bc) == COMPLEX_EXPR)
-    br = TREE_OPERAND (bc, 0), bi = TREE_OPERAND (bc, 1);
-  else if (TREE_CODE (bc) == COMPLEX_CST)
-    br = TREE_REALPART (bc), bi = TREE_IMAGPART (bc);
-  else
-    return NULL;
-
-  return fold_complex_mult_parts (type, ar, ai, br, bi);
-}
-
-/* Perform some simplifications of complex division when one or more of
-   the components are constants or zeros.  Return non-null if successful.  */
-
-tree
-fold_complex_div_parts (tree type, tree ar, tree ai, tree br, tree bi,
-                       enum tree_code code)
-{
-  tree rr, ri, inner_type, zero;
-  bool ar0, ai0, br0, bi0, bi1;
-
-  inner_type = TREE_TYPE (type);
-  zero = NULL;
-
-  if (SCALAR_FLOAT_TYPE_P (inner_type))
-    {
-      ar0 = ai0 = br0 = bi0 = bi1 = false;
-
-      /* We're only interested in +0.0 here, thus we don't use real_zerop.  */
-
-      if (TREE_CODE (ar) == REAL_CST
-         && REAL_VALUES_IDENTICAL (TREE_REAL_CST (ar), dconst0))
-       ar0 = true, zero = ar;
-
-      if (TREE_CODE (ai) == REAL_CST
-         && REAL_VALUES_IDENTICAL (TREE_REAL_CST (ai), dconst0))
-       ai0 = true, zero = ai;
-
-      if (TREE_CODE (br) == REAL_CST
-         && REAL_VALUES_IDENTICAL (TREE_REAL_CST (br), dconst0))
-       br0 = true, zero = br;
-
-      if (TREE_CODE (bi) == REAL_CST)
-       {
-         if (REAL_VALUES_IDENTICAL (TREE_REAL_CST (bi), dconst0))
-           bi0 = true, zero = bi;
-         else if (REAL_VALUES_IDENTICAL (TREE_REAL_CST (bi), dconst1))
-           bi1 = true;
-       }
-    }
-  else
-    {
-      ar0 = integer_zerop (ar);
-      if (ar0)
-       zero = ar;
-      ai0 = integer_zerop (ai);
-      if (ai0)
-       zero = ai;
-      br0 = integer_zerop (br);
-      if (br0)
-       zero = br;
-      bi0 = integer_zerop (bi);
-      if (bi0)
-       {
-         zero = bi;
-         bi1 = false;
-       }
-      else
-       bi1 = integer_onep (bi);
-    }
-
-  /* We won't optimize anything below unless something is zero.  */
-  if (zero == NULL)
-    return NULL;
-
-  if (ai0 && bi0)
-    {
-      rr = fold_build2 (code, inner_type, ar, br);
-      ri = zero;
-    }
-  else if (ai0 && br0)
-    {
-      rr = zero;
-      ri = fold_build2 (code, inner_type, ar, bi);
-      ri = fold_build1 (NEGATE_EXPR, inner_type, ri);
-    }
-  else if (ar0 && bi0)
-    {
-      rr = zero;
-      ri = fold_build2 (code, inner_type, ai, br);
-    }
-  else if (ar0 && br0)
-    {
-      rr = fold_build2 (code, inner_type, ai, bi);
-      ri = zero;
-    }
-  else if (bi0)
-    {
-      rr = fold_build2 (code, inner_type, ar, br);
-      ri = fold_build2 (code, inner_type, ai, br);
-    }
-  else if (br0)
-    {
-      rr = fold_build2 (code, inner_type, ai, bi);
-      ri = fold_build2 (code, inner_type, ar, bi);
-      ri = fold_build1 (NEGATE_EXPR, inner_type, ri);
-    }
-  else
-    return NULL;
-
-  return fold_build2 (COMPLEX_EXPR, type, rr, ri);
-}
-
-static tree
-fold_complex_div (tree type, tree ac, tree bc, enum tree_code code)
-{
-  tree ar, ai, br, bi;
-
-  if (TREE_CODE (ac) == COMPLEX_EXPR)
-    ar = TREE_OPERAND (ac, 0), ai = TREE_OPERAND (ac, 1);
-  else if (TREE_CODE (ac) == COMPLEX_CST)
-    ar = TREE_REALPART (ac), ai = TREE_IMAGPART (ac);
-  else
-    return NULL;
-
-  if (TREE_CODE (bc) == COMPLEX_EXPR)
-    br = TREE_OPERAND (bc, 0), bi = TREE_OPERAND (bc, 1);
-  else if (TREE_CODE (bc) == COMPLEX_CST)
-    br = TREE_REALPART (bc), bi = TREE_IMAGPART (bc);
-  else
-    return NULL;
-
-  return fold_complex_div_parts (type, ar, ai, br, bi, code);
-}
-
 /* Fold a unary expression of code CODE and type TYPE with operand
    OP0.  Return the folded expression if folding is successful.
    Otherwise, return NULL_TREE.  */
@@ -7418,13 +7124,6 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
          && integer_onep (arg1))
        return fold_build1 (NEGATE_EXPR, type, TREE_OPERAND (arg0, 0));
 
-      if (TREE_CODE (type) == COMPLEX_TYPE)
-       {
-         tem = fold_complex_add (type, arg0, arg1, PLUS_EXPR);
-         if (tem)
-           return tem;
-       }
-
       if (! FLOAT_TYPE_P (type))
        {
          if (integer_zerop (arg1))
@@ -7870,13 +7569,6 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
          && integer_all_onesp (arg0))
        return fold_build1 (BIT_NOT_EXPR, type, arg1);
 
-      if (TREE_CODE (type) == COMPLEX_TYPE)
-       {
-         tem = fold_complex_add (type, arg0, arg1, MINUS_EXPR);
-         if (tem)
-           return tem;
-       }
-
       if (! FLOAT_TYPE_P (type))
        {
          if (! wins && integer_zerop (arg0))
@@ -8033,13 +7725,6 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
                            negate_expr (arg0),
                            TREE_OPERAND (arg1, 0));
 
-      if (TREE_CODE (type) == COMPLEX_TYPE)
-       {
-         tem = fold_complex_mult (type, arg0, arg1);
-         if (tem)
-           return tem;
-       }
-
       if (! FLOAT_TYPE_P (type))
        {
          if (integer_zerop (arg1))
@@ -8501,13 +8186,6 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
                                TREE_OPERAND (arg1, 0));
        }
 
-      if (TREE_CODE (type) == COMPLEX_TYPE)
-       {
-         tem = fold_complex_div (type, arg0, arg1, code);
-         if (tem)
-           return tem;
-       }
-
       if (flag_unsafe_math_optimizations)
        {
          enum built_in_function fcode = builtin_mathfn_code (arg1);
@@ -8631,12 +8309,6 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
          && 0 != (tem = extract_muldiv (op0, arg1, code, NULL_TREE)))
        return fold_convert (type, tem);
 
-      if (TREE_CODE (type) == COMPLEX_TYPE)
-       {
-         tem = fold_complex_div (type, arg0, arg1, code);
-         if (tem)
-           return tem;
-       }
       goto binary;
 
     case CEIL_MOD_EXPR:
@@ -9926,34 +9598,6 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
            }
        }
 
-      /* If this is a comparison of complex values and either or both sides
-        are a COMPLEX_EXPR or COMPLEX_CST, it is best to split up the
-        comparisons and join them with a TRUTH_ANDIF_EXPR or TRUTH_ORIF_EXPR.
-        This may prevent needless evaluations.  */
-      if ((code == EQ_EXPR || code == NE_EXPR)
-         && TREE_CODE (TREE_TYPE (arg0)) == COMPLEX_TYPE
-         && (TREE_CODE (arg0) == COMPLEX_EXPR
-             || TREE_CODE (arg1) == COMPLEX_EXPR
-             || TREE_CODE (arg0) == COMPLEX_CST
-             || TREE_CODE (arg1) == COMPLEX_CST))
-       {
-         tree subtype = TREE_TYPE (TREE_TYPE (arg0));
-         tree real0, imag0, real1, imag1;
-
-         arg0 = save_expr (arg0);
-         arg1 = save_expr (arg1);
-         real0 = fold_build1 (REALPART_EXPR, subtype, arg0);
-         imag0 = fold_build1 (IMAGPART_EXPR, subtype, arg0);
-         real1 = fold_build1 (REALPART_EXPR, subtype, arg1);
-         imag1 = fold_build1 (IMAGPART_EXPR, subtype, arg1);
-
-         return fold_build2 ((code == EQ_EXPR ? TRUTH_ANDIF_EXPR
-                              : TRUTH_ORIF_EXPR),
-                             type,
-                             fold_build2 (code, type, real0, real1),
-                             fold_build2 (code, type, imag0, imag1));
-       }
-
       /* Optimize comparisons of strlen vs zero to a compare of the
         first character of the string vs zero.  To wit,
                strlen(ptr) == 0   =>  *ptr == 0
index 1fa76a900c3aebc0366af0da0b368a470abe776c..a4c7329d3dd47e14dd08efd1fe48d3431cca2949 100644 (file)
@@ -150,7 +150,7 @@ init_dont_simulate_again (void)
   basic_block bb;
   block_stmt_iterator bsi;
   tree phi;
-  bool saw_a_complex_value = false;
+  bool saw_a_complex_op = false;
 
   FOR_EACH_BB (bb)
     {
@@ -159,21 +159,62 @@ init_dont_simulate_again (void)
 
       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
        {
-         tree stmt = bsi_stmt (bsi);
+         tree orig_stmt, stmt, rhs = NULL;
          bool dsa = true;
 
-         if (TREE_CODE (stmt) == MODIFY_EXPR
-             && is_complex_reg (TREE_OPERAND (stmt, 0)))
+         orig_stmt = stmt = bsi_stmt (bsi);
+         switch (TREE_CODE (stmt))
            {
-             dsa = false;
-             saw_a_complex_value = true;
+           case RETURN_EXPR:
+             stmt = TREE_OPERAND (stmt, 0);
+             if (!stmt || TREE_CODE (stmt) != MODIFY_EXPR)
+               break;
+             /* FALLTHRU */
+
+           case MODIFY_EXPR:
+             dsa = !is_complex_reg (TREE_OPERAND (stmt, 0));
+             rhs = TREE_OPERAND (stmt, 1);
+             break;
+
+           case COND_EXPR:
+             rhs = TREE_OPERAND (stmt, 0);
+             break;
+
+           default:
+             break;
            }
 
-         DONT_SIMULATE_AGAIN (stmt) = dsa;
+         if (rhs)
+           switch (TREE_CODE (rhs))
+             {
+             case EQ_EXPR:
+             case NE_EXPR:
+               rhs = TREE_OPERAND (rhs, 0);
+               /* FALLTHRU */
+
+             case PLUS_EXPR:
+             case MINUS_EXPR:
+             case MULT_EXPR:
+             case TRUNC_DIV_EXPR:
+             case CEIL_DIV_EXPR:
+             case FLOOR_DIV_EXPR:
+             case ROUND_DIV_EXPR:
+             case RDIV_EXPR:
+             case NEGATE_EXPR:
+             case CONJ_EXPR:
+               if (TREE_CODE (TREE_TYPE (rhs)) == COMPLEX_TYPE)
+                 saw_a_complex_op = true;
+               break;
+
+             default:
+               break;
+             }
+
+         DONT_SIMULATE_AGAIN (orig_stmt) = dsa;
        }
     }
 
-  return saw_a_complex_value;
+  return saw_a_complex_op;
 }
 
 
@@ -189,6 +230,8 @@ complex_visit_stmt (tree stmt, edge *taken_edge_p ATTRIBUTE_UNUSED,
 
   /* These conditions should be satisfied due to the initial filter
      set up in init_dont_simulate_again.  */
+  if (TREE_CODE (stmt) == RETURN_EXPR)
+    stmt = TREE_OPERAND (stmt, 0);
   gcc_assert (TREE_CODE (stmt) == MODIFY_EXPR);
 
   lhs = TREE_OPERAND (stmt, 0);
@@ -308,6 +351,9 @@ create_components (void)
   size_t k, n;
 
   n = num_referenced_vars;
+  if (n == 0)
+    return;
+
   complex_variable_components = VEC_alloc (tree, heap, 2*n);
   VEC_safe_grow (tree, heap, complex_variable_components, 2*n);
 
index e2e646fa54f40e63ec348d3682fd37a0f0da7d63..c434f2fe509e3c8a47fa772e31589b91bca219aa 100644 (file)
@@ -3611,9 +3611,6 @@ extern tree build_fold_indirect_ref (tree);
 extern tree fold_indirect_ref (tree);
 extern tree constant_boolean_node (int, tree);
 extern tree build_low_bits_mask (tree, unsigned);
-extern tree fold_complex_mult_parts (tree, tree, tree, tree, tree);
-extern tree fold_complex_div_parts (tree, tree, tree, tree, tree,
-                                   enum tree_code);
 
 extern bool tree_swap_operands_p (tree, tree, bool);
 extern enum tree_code swap_tree_comparison (enum tree_code);