[multiple changes]
authorRichard Henderson <rth@gcc.gnu.org>
Wed, 15 May 2002 20:39:55 +0000 (13:39 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 15 May 2002 20:39:55 +0000 (13:39 -0700)
2002-05-15  Jakub Jelinek  <jakub@redhat.com>

        * fold-const.c (fold): Fix a typo.

2002-05-15  Eric Botcazou  <ebotcazou@multimania.com>

        * fold-const.c (fold) [LT_EXPR]: Move the transformation of a
        comparison against the highest or lowest integer value before
        the 'X >= CST to X > (CST - 1)' and 'X < CST to X <= (CST - 1)'
        transformation and that of an unsigned comparison against 0
        right after.

From-SVN: r53493

gcc/ChangeLog
gcc/fold-const.c

index 9b74f2cc298d4af79061e9034b74d72f75036191..14caa87842dfd0bfc78578485471e743766bfb5e 100644 (file)
@@ -1,3 +1,15 @@
+2002-05-15  Jakub Jelinek  <jakub@redhat.com>
+
+       * fold-const.c (fold): Fix a typo.
+
+2002-05-15  Eric Botcazou  <ebotcazou@multimania.com>
+
+       * fold-const.c (fold) [LT_EXPR]: Move the transformation of a
+       comparison against the highest or lowest integer value before
+       the 'X >= CST to X > (CST - 1)' and 'X < CST to X <= (CST - 1)'
+       transformation and that of an unsigned comparison against 0
+       right after.
+
 2002-05-15  Richard Henderson  <rth@redhat.com>
 
        * varasm.c (merge_weak): Error for any weakening after definition.
index 2a9f6c6ee7cc462fa971f3deb272d223b63cb1ab..0744ada154d048a6427a916358f0610ee7721507 100644 (file)
@@ -5962,7 +5962,117 @@ fold (expr)
          }
       }
 
-      /* Change X >= CST to X > (CST - 1) if CST is positive.  */
+      /* Comparisons with the highest or lowest possible integer of
+        the specified size will have known values and an unsigned
+        <= 0x7fffffff can be simplified.  */
+      {
+       int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg1)));
+
+       if (TREE_CODE (arg1) == INTEGER_CST
+           && ! TREE_CONSTANT_OVERFLOW (arg1)
+           && width <= HOST_BITS_PER_WIDE_INT
+           && (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
+               || POINTER_TYPE_P (TREE_TYPE (arg1))))
+         {
+           if (TREE_INT_CST_HIGH (arg1) == 0
+               && (TREE_INT_CST_LOW (arg1)
+                   == ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1)
+               && ! TREE_UNSIGNED (TREE_TYPE (arg1)))
+             switch (TREE_CODE (t))
+               {
+               case GT_EXPR:
+                 return omit_one_operand (type,
+                                          convert (type, integer_zero_node),
+                                          arg0);
+               case GE_EXPR:
+                 TREE_SET_CODE (t, EQ_EXPR);
+                 break;
+
+               case LE_EXPR:
+                 return omit_one_operand (type,
+                                          convert (type, integer_one_node),
+                                          arg0);
+               case LT_EXPR:
+                 TREE_SET_CODE (t, NE_EXPR);
+                 break;
+
+               default:
+                 break;
+               }
+
+           else if (TREE_INT_CST_HIGH (arg1) == -1
+                    && (TREE_INT_CST_LOW (arg1)
+                        == ((unsigned HOST_WIDE_INT) -1 << (width - 1)))
+                    && ! TREE_UNSIGNED (TREE_TYPE (arg1)))
+             switch (TREE_CODE (t))
+               {
+               case LT_EXPR:
+                 return omit_one_operand (type,
+                                          convert (type, integer_zero_node),
+                                          arg0);
+               case LE_EXPR:
+                 TREE_SET_CODE (t, EQ_EXPR);
+                 break;
+
+               case GE_EXPR:
+                 return omit_one_operand (type,
+                                          convert (type, integer_one_node),
+                                          arg0);
+               case GT_EXPR:
+                 TREE_SET_CODE (t, NE_EXPR);
+                 break;
+
+               default:
+                 break;
+               }
+
+           else if (TREE_INT_CST_HIGH (arg1) == 0
+                    && (TREE_INT_CST_LOW (arg1)
+                        == ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1)
+                    && TREE_UNSIGNED (TREE_TYPE (arg1))
+                    /* signed_type does not work on pointer types.  */
+                    && INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
+             {
+               if (TREE_CODE (t) == LE_EXPR || TREE_CODE (t) == GT_EXPR)
+                 {
+                   tree st0, st1;
+                   st0 = (*lang_hooks.types.signed_type) (TREE_TYPE (arg0));
+                   st1 = (*lang_hooks.types.signed_type) (TREE_TYPE (arg1));
+                   return fold
+                     (build (TREE_CODE (t) == LE_EXPR ? GE_EXPR: LT_EXPR,
+                             type, convert (st0, arg0),
+                             convert (st1, integer_zero_node)));
+                 }
+             }
+            else if (TREE_INT_CST_HIGH (arg1) == 0
+                    && (TREE_INT_CST_LOW (arg1)
+                        == ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1)
+                    && TREE_UNSIGNED (TREE_TYPE (arg1)))
+              switch (TREE_CODE (t))
+                {
+                case GT_EXPR:
+                  return omit_one_operand (type,
+                                           convert (type, integer_zero_node),
+                                           arg0);
+                case GE_EXPR:
+                  TREE_SET_CODE (t, EQ_EXPR);
+                  break;
+
+                case LE_EXPR:
+                  return omit_one_operand (type,
+                                           convert (type, integer_one_node),
+                                           arg0);
+                case LT_EXPR:
+                  TREE_SET_CODE (t, NE_EXPR);
+                  break;
+
+                default:
+                  break;
+                }
+         }
+      }
+
+      /* Change X >= C to X > C-1 and X < C to X <= C-1 if C is positive.  */
       if (TREE_CODE (arg1) == INTEGER_CST
          && TREE_CODE (arg0) != INTEGER_CST
          && tree_int_cst_sgn (arg1) > 0)
@@ -5986,6 +6096,35 @@ fold (expr)
            }
        }
 
+      /* An unsigned comparison against 0 can be simplified.  */
+      if (integer_zerop (arg1)
+         && (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
+             || POINTER_TYPE_P (TREE_TYPE (arg1)))
+         && TREE_UNSIGNED (TREE_TYPE (arg1)))
+       {
+         switch (TREE_CODE (t))
+           {
+           case GT_EXPR:
+             code = NE_EXPR;
+             TREE_SET_CODE (t, NE_EXPR);
+             break;
+           case LE_EXPR:
+             code = EQ_EXPR;
+             TREE_SET_CODE (t, EQ_EXPR);
+             break;
+           case GE_EXPR:
+             return omit_one_operand (type,
+                                      convert (type, integer_one_node),
+                                      arg0);
+           case LT_EXPR:
+             return omit_one_operand (type,
+                                      convert (type, integer_zero_node),
+                                      arg0);
+           default:
+             break;
+           }
+       }
+
       /* If this is an EQ or NE comparison of a constant with a PLUS_EXPR or
         a MINUS_EXPR of a constant, we can convert it into a comparison with
         a revised constant as long as no overflow occurs.  */
@@ -6191,145 +6330,6 @@ fold (expr)
            }
        }
 
-      /* An unsigned comparison against 0 can be simplified.  */
-      if (integer_zerop (arg1)
-         && (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
-             || POINTER_TYPE_P (TREE_TYPE (arg1)))
-         && TREE_UNSIGNED (TREE_TYPE (arg1)))
-       {
-         switch (TREE_CODE (t))
-           {
-           case GT_EXPR:
-             code = NE_EXPR;
-             TREE_SET_CODE (t, NE_EXPR);
-             break;
-           case LE_EXPR:
-             code = EQ_EXPR;
-             TREE_SET_CODE (t, EQ_EXPR);
-             break;
-           case GE_EXPR:
-             return omit_one_operand (type,
-                                      convert (type, integer_one_node),
-                                      arg0);
-           case LT_EXPR:
-             return omit_one_operand (type,
-                                      convert (type, integer_zero_node),
-                                      arg0);
-           default:
-             break;
-           }
-       }
-
-      /* Comparisons with the highest or lowest possible integer of
-        the specified size will have known values and an unsigned
-        <= 0x7fffffff can be simplified.  */
-      {
-       int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg1)));
-
-       if (TREE_CODE (arg1) == INTEGER_CST
-           && ! TREE_CONSTANT_OVERFLOW (arg1)
-           && width <= HOST_BITS_PER_WIDE_INT
-           && (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
-               || POINTER_TYPE_P (TREE_TYPE (arg1))))
-         {
-           if (TREE_INT_CST_HIGH (arg1) == 0
-               && (TREE_INT_CST_LOW (arg1)
-                   == ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1)
-               && ! TREE_UNSIGNED (TREE_TYPE (arg1)))
-             switch (TREE_CODE (t))
-               {
-               case GT_EXPR:
-                 return omit_one_operand (type,
-                                          convert (type, integer_zero_node),
-                                          arg0);
-               case GE_EXPR:
-                 TREE_SET_CODE (t, EQ_EXPR);
-                 break;
-
-               case LE_EXPR:
-                 return omit_one_operand (type,
-                                          convert (type, integer_one_node),
-                                          arg0);
-               case LT_EXPR:
-                 TREE_SET_CODE (t, NE_EXPR);
-                 break;
-
-               default:
-                 break;
-               }
-
-           else if (TREE_INT_CST_HIGH (arg1) == -1
-                    && (TREE_INT_CST_LOW (arg1)
-                        == ((unsigned HOST_WIDE_INT) 1 << (width - 1)))
-                    && ! TREE_UNSIGNED (TREE_TYPE (arg1)))
-             switch (TREE_CODE (t))
-               {
-               case LT_EXPR:
-                 return omit_one_operand (type,
-                                          convert (type, integer_zero_node),
-                                          arg0);
-               case LE_EXPR:
-                 TREE_SET_CODE (t, EQ_EXPR);
-                 break;
-
-               case GE_EXPR:
-                 return omit_one_operand (type,
-                                          convert (type, integer_one_node),
-                                          arg0);
-               case GT_EXPR:
-                 TREE_SET_CODE (t, NE_EXPR);
-                 break;
-
-               default:
-                 break;
-               }
-
-           else if (TREE_INT_CST_HIGH (arg1) == 0
-                    && (TREE_INT_CST_LOW (arg1)
-                        == ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1)
-                    && TREE_UNSIGNED (TREE_TYPE (arg1))
-                    /* signed_type does not work on pointer types.  */
-                    && INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
-             {
-               if (TREE_CODE (t) == LE_EXPR || TREE_CODE (t) == GT_EXPR)
-                 {
-                   tree st0, st1;
-                   st0 = (*lang_hooks.types.signed_type) (TREE_TYPE (arg0));
-                   st1 = (*lang_hooks.types.signed_type) (TREE_TYPE (arg1));
-                   return fold
-                     (build (TREE_CODE (t) == LE_EXPR ? GE_EXPR: LT_EXPR,
-                             type, convert (st0, arg0),
-                             convert (st1, integer_zero_node)));
-                 }
-             }
-            else if (TREE_INT_CST_HIGH (arg1) == 0
-                    && (TREE_INT_CST_LOW (arg1)
-                        == ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1)
-                    && TREE_UNSIGNED (TREE_TYPE (arg1)))
-              switch (TREE_CODE (t))
-                {
-                case GT_EXPR:
-                  return omit_one_operand (type,
-                                           convert (type, integer_zero_node),
-                                           arg0);
-                case GE_EXPR:
-                  TREE_SET_CODE (t, EQ_EXPR);
-                  break;
-
-                case LE_EXPR:
-                  return omit_one_operand (type,
-                                           convert (type, integer_one_node),
-                                           arg0);
-                case LT_EXPR:
-                  TREE_SET_CODE (t, NE_EXPR);
-                  break;
-
-                default:
-                  break;
-                }
-         }
-      }
-
       /* If we are comparing an expression that just has comparisons
         of two integer values, arithmetic expressions of those comparisons,
         and constants, we can simplify it.  There are only three cases