OSDN Git Service

* fold-const.c (tree_expr_nonzero_p): Add function prototype.
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 19 Jul 2004 12:45:44 +0000 (12:45 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 19 Jul 2004 12:45:44 +0000 (12:45 +0000)
(fold) <EQ_EXPR>: Move tree_expr_nonzero_p optimization from
fold_relational_const to here, i.e. "(x | 5) == 0" -> false.
(fold) (UNEQ_EXPR>: Add optimizations for unordered comparisons
of the form "x op x" where op is UNLE, UNGE, UNEQ or LTGT.
(fold_relational_const): Tidy up handling of floating point
comparisons by calling real_compare.  Remove tree_expr_nonzero_p
transformation; fold_relational_const assumes constant operands.

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

gcc/ChangeLog
gcc/fold-const.c

index 3433fbb..12667fd 100644 (file)
@@ -1,3 +1,14 @@
+2004-07-19  Roger Sayle  <roger@eyesopen.com>
+
+       * fold-const.c (tree_expr_nonzero_p): Add function prototype.
+       (fold) <EQ_EXPR>: Move tree_expr_nonzero_p optimization from
+       fold_relational_const to here, i.e. "(x | 5) == 0" -> false.
+       (fold) (UNEQ_EXPR>: Add optimizations for unordered comparisons
+       of the form "x op x" where op is UNLE, UNGE, UNEQ or LTGT.
+       (fold_relational_const): Tidy up handling of floating point
+       comparisons by calling real_compare.  Remove tree_expr_nonzero_p
+       transformation; fold_relational_const assumes constant operands.
+
 2004-07-19  Gabriel Dos Reis  <gdr@integrable-solution.net>
 
        * doc/sourcebuild.texi: Add libcpp, now that CPP has its own
 2004-07-19  Gabriel Dos Reis  <gdr@integrable-solution.net>
 
        * doc/sourcebuild.texi: Add libcpp, now that CPP has its own
index bc1e877..7c6b665 100644 (file)
@@ -137,6 +137,7 @@ static tree fold_not_const (tree, tree);
 static tree fold_relational_const (enum tree_code, tree, tree, tree);
 static tree fold_relational_hi_lo (enum tree_code *, const tree,
                                    tree *, tree *);
 static tree fold_relational_const (enum tree_code, tree, tree, tree);
 static tree fold_relational_hi_lo (enum tree_code *, const tree,
                                    tree *, tree *);
+static bool tree_expr_nonzero_p (tree);
 
 /* We know that A1 + B1 = SUM1, using 2's complement arithmetic and ignoring
    overflow.  Suppose A, B and SUM have the same respective signs as A1, B1,
 
 /* We know that A1 + B1 = SUM1, using 2's complement arithmetic and ignoring
    overflow.  Suppose A, B and SUM have the same respective signs as A1, B1,
@@ -8638,9 +8639,14 @@ fold (tree expr)
            return t1;
        }
 
            return t1;
        }
 
-      /* Both ARG0 and ARG1 are known to be constants at this point.  */
+      if ((code == EQ_EXPR || code == NE_EXPR)
+         && !TREE_SIDE_EFFECTS (arg0)
+         && integer_zerop (arg1)
+         && tree_expr_nonzero_p (arg0))
+       return constant_boolean_node (code==NE_EXPR, type);
+
       t1 = fold_relational_const (code, type, arg0, arg1);
       t1 = fold_relational_const (code, type, arg0, arg1);
-      return (t1 == NULL_TREE ? t : t1);
+      return t1 == NULL_TREE ? t : t1;
 
     case UNORDERED_EXPR:
     case ORDERED_EXPR:
 
     case UNORDERED_EXPR:
     case ORDERED_EXPR:
@@ -8679,6 +8685,16 @@ fold (tree expr)
          return omit_one_operand (type, t1, arg0);
        }
 
          return omit_one_operand (type, t1, arg0);
        }
 
+      /* Simplify unordered comparison of something with itself.  */
+      if ((code == UNLE_EXPR || code == UNGE_EXPR || code == UNEQ_EXPR)
+         && operand_equal_p (arg0, arg1, 0))
+       return constant_boolean_node (1, type);
+
+      if (code == LTGT_EXPR
+         && !flag_trapping_math
+         && operand_equal_p (arg0, arg1, 0))
+       return constant_boolean_node (0, type);
+
       /* Fold (double)float1 CMP (double)float2 into float1 CMP float2.  */
       {
        tree targ0 = strip_float_extensions (arg0);
       /* Fold (double)float1 CMP (double)float2 into float1 CMP float2.  */
       {
        tree targ0 = strip_float_extensions (arg0);
@@ -10394,9 +10410,11 @@ fold_relational_const (enum tree_code code, tree type, tree op0, tree op1)
 
   if (TREE_CODE (op0) == REAL_CST && TREE_CODE (op1) == REAL_CST)
     {
 
   if (TREE_CODE (op0) == REAL_CST && TREE_CODE (op1) == REAL_CST)
     {
+      const REAL_VALUE_TYPE *c0 = TREE_REAL_CST_PTR (op0);
+      const REAL_VALUE_TYPE *c1 = TREE_REAL_CST_PTR (op1);
+
       /* Handle the cases where either operand is a NaN.  */
       /* Handle the cases where either operand is a NaN.  */
-      if (REAL_VALUE_ISNAN (TREE_REAL_CST (op0))
-          || REAL_VALUE_ISNAN (TREE_REAL_CST (op1)))
+      if (real_isnan (c0) || real_isnan (c1))
        {
          switch (code)
            {
        {
          switch (code)
            {
@@ -10432,37 +10450,7 @@ fold_relational_const (enum tree_code code, tree type, tree op0, tree op1)
          return constant_boolean_node (result, type);
        }
 
          return constant_boolean_node (result, type);
        }
 
-      /* From here on we're sure there are no NaNs.  */
-      switch (code)
-       {
-       case ORDERED_EXPR:
-         return constant_boolean_node (true, type);
-
-       case UNORDERED_EXPR:
-         return constant_boolean_node (false, type);
-
-       case UNLT_EXPR:
-         code = LT_EXPR;
-         break;
-       case UNLE_EXPR:
-         code = LE_EXPR;
-         break;
-       case UNGT_EXPR:
-         code = GT_EXPR;
-         break;
-       case UNGE_EXPR:
-         code = GE_EXPR;
-         break;
-       case UNEQ_EXPR:
-         code = EQ_EXPR;
-         break;
-       case LTGT_EXPR:
-         code = NE_EXPR;
-         break;
-
-       default:
-         break;
-       }
+      return constant_boolean_node (real_compare (code, c0, c1), type);
     }
 
   /* From here on we only handle LT, LE, GT, GE, EQ and NE.
     }
 
   /* From here on we only handle LT, LE, GT, GE, EQ and NE.
@@ -10503,21 +10491,6 @@ fold_relational_const (enum tree_code code, tree type, tree op0, tree op1)
       else
        result = INT_CST_LT (op0, op1);
     }
       else
        result = INT_CST_LT (op0, op1);
     }
-
-  else if (code == EQ_EXPR && !TREE_SIDE_EFFECTS (op0)
-           && integer_zerop (op1) && tree_expr_nonzero_p (op0))
-    result = 0;
-
-  /* Two real constants can be compared explicitly.  */
-  else if (TREE_CODE (op0) == REAL_CST && TREE_CODE (op1) == REAL_CST)
-    {
-      if (code == EQ_EXPR)
-       result = REAL_VALUES_EQUAL (TREE_REAL_CST (op0),
-                                   TREE_REAL_CST (op1));
-      else
-       result = REAL_VALUES_LESS (TREE_REAL_CST (op0),
-                                  TREE_REAL_CST (op1));
-    }
   else
     return NULL_TREE;
 
   else
     return NULL_TREE;