]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
fold-const.c (fold): Move the transformation of a comparison against the highest...
authorEric Botcazou <ebotcazou@multimania.com>
Fri, 17 May 2002 06:11:29 +0000 (06:11 +0000)
committerRichard Henderson <rth@gcc.gnu.org>
Fri, 17 May 2002 06:11:29 +0000 (23:11 -0700)
        * 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: r53543

gcc/ChangeLog
gcc/fold-const.c

index 4558ab9205ea5a0ecce5507fd52b3f085d2d129a..afeb064da3e32bef73bc3df0ceb2902b8125e4c1 100644 (file)
@@ -1,3 +1,11 @@
+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-16  Richard Henderson  <rth@redhat.com>
 
        PR c/3467
index 2169998612634290338fc4c715c7b90a35ec5338..98e81aa752680281889884fba3e18417cfd15ccb 100644 (file)
@@ -6490,7 +6490,125 @@ 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)))
+             switch (TREE_CODE (t))
+               {
+               case LE_EXPR:
+                 return fold (build (GE_EXPR, type,
+                                     convert (signed_type (TREE_TYPE (arg0)),
+                                              arg0),
+                                     convert (signed_type (TREE_TYPE (arg1)),
+                                              integer_zero_node)));
+               case GT_EXPR:
+                 return fold (build (LT_EXPR, type,
+                                     convert (signed_type (TREE_TYPE (arg0)),
+                                              arg0),
+                                     convert (signed_type (TREE_TYPE (arg1)),
+                                              integer_zero_node)));
+
+               default:
+                 break;
+               }
+
+            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 >= CST to X > (CST - 1) and X < CST to X <= (CST - 1)
+        if CST is positive.  */
       if (TREE_CODE (arg1) == INTEGER_CST
          && TREE_CODE (arg0) != INTEGER_CST
          && tree_int_cst_sgn (arg1) > 0)
@@ -6514,6 +6632,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.  */
@@ -6702,152 +6849,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)))
-             switch (TREE_CODE (t))
-               {
-               case LE_EXPR:
-                 return fold (build (GE_EXPR, type,
-                                     convert (signed_type (TREE_TYPE (arg0)),
-                                              arg0),
-                                     convert (signed_type (TREE_TYPE (arg1)),
-                                              integer_zero_node)));
-               case GT_EXPR:
-                 return fold (build (LT_EXPR, type,
-                                     convert (signed_type (TREE_TYPE (arg0)),
-                                              arg0),
-                                     convert (signed_type (TREE_TYPE (arg1)),
-                                              integer_zero_node)));
-
-               default:
-                 break;
-               }
-
-            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