OSDN Git Service

* fold-const.c (fold_binary) <LT_EXPR>: Use the precision of the
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 1 Dec 2006 22:46:45 +0000 (22:46 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 1 Dec 2006 22:46:45 +0000 (22:46 +0000)
type instead of the size of its mode to compute the highest and
lowest possible values.  Still check the size of the mode before
flipping the signedness of the comparison.

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

gcc/ChangeLog
gcc/fold-const.c

index f09a823..f322b66 100644 (file)
@@ -1,3 +1,10 @@
+2006-12-01  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * fold-const.c (fold_binary) <LT_EXPR>: Use the precision of the
+       type instead of the size of its mode to compute the highest and
+       lowest possible values.  Still check the size of the mode before
+       flipping the signedness of the comparison.
+
 2006-12-01  Trevor Smigiel  <trevor_smigiel@playstation.sony.com>
 
        * config/spu/predicates.md (spu_mov_operand): Add.
index b19b768..fce41c2 100644 (file)
@@ -7758,24 +7758,24 @@ fold_minmax (enum tree_code code, tree type, tree op0, tree op1)
   else
     gcc_unreachable ();
 
-  /* MIN (MAX (a, b), b) == b.  */
+  /* MIN (MAX (a, b), b) == b.  */
   if (TREE_CODE (op0) == compl_code
       && operand_equal_p (TREE_OPERAND (op0, 1), op1, 0))
     return omit_one_operand (type, op1, TREE_OPERAND (op0, 0));
 
-  /* MIN (MAX (b, a), b) == b.  */
+  /* MIN (MAX (b, a), b) == b.  */
   if (TREE_CODE (op0) == compl_code
       && operand_equal_p (TREE_OPERAND (op0, 0), op1, 0)
       && reorder_operands_p (TREE_OPERAND (op0, 1), op1))
     return omit_one_operand (type, op1, TREE_OPERAND (op0, 1));
 
-  /* MIN (a, MAX (a, b)) == a.  */
+  /* MIN (a, MAX (a, b)) == a.  */
   if (TREE_CODE (op1) == compl_code
       && operand_equal_p (op0, TREE_OPERAND (op1, 0), 0)
       && reorder_operands_p (op0, TREE_OPERAND (op1, 1)))
     return omit_one_operand (type, op0, TREE_OPERAND (op1, 1));
 
-  /* MIN (a, MAX (b, a)) == a.  */
+  /* MIN (a, MAX (b, a)) == a.  */
   if (TREE_CODE (op1) == compl_code
       && operand_equal_p (op0, TREE_OPERAND (op1, 1), 0)
       && reorder_operands_p (op0, TREE_OPERAND (op1, 0)))
@@ -10994,15 +10994,15 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
        }
 
       /* Comparisons with the highest or lowest possible integer of
-        the specified size will have known values.  */
+        the specified precision will have known values.  */
       {
-       int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg1)));
+       tree arg1_type = TREE_TYPE (arg1);
+       unsigned int width = TYPE_PRECISION (arg1_type);
 
        if (TREE_CODE (arg1) == INTEGER_CST
            && ! TREE_CONSTANT_OVERFLOW (arg1)
            && width <= 2 * HOST_BITS_PER_WIDE_INT
-           && (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
-               || POINTER_TYPE_P (TREE_TYPE (arg1))))
+           && (INTEGRAL_TYPE_P (arg1_type) || POINTER_TYPE_P (arg1_type)))
          {
            HOST_WIDE_INT signed_max_hi;
            unsigned HOST_WIDE_INT signed_max_lo;
@@ -11015,7 +11015,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
                signed_max_hi = 0;
                max_hi = 0;
 
-               if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
+               if (TYPE_UNSIGNED (arg1_type))
                  {
                    max_lo = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1;
                    min_lo = 0;
@@ -11037,7 +11037,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
                max_lo = -1;
                min_lo = 0;
 
-               if (TYPE_UNSIGNED (TREE_TYPE (arg1)))
+               if (TYPE_UNSIGNED (arg1_type))
                  {
                    max_hi = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1;
                    min_hi = 0;
@@ -11124,9 +11124,14 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
 
            else if (TREE_INT_CST_HIGH (arg1) == signed_max_hi
                     && TREE_INT_CST_LOW (arg1) == signed_max_lo
-                    && TYPE_UNSIGNED (TREE_TYPE (arg1))
+                    && TYPE_UNSIGNED (arg1_type)
+                    /* We will flip the signedness of the comparison operator
+                       associated with the mode of arg1, so the sign bit is
+                       specified by this mode.  Check that arg1 is the signed
+                       max associated with this sign bit.  */
+                    && width == GET_MODE_BITSIZE (TYPE_MODE (arg1_type))
                     /* signed_type does not work on pointer types.  */
-                    && INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
+                    && INTEGRAL_TYPE_P (arg1_type))
              {
                /* The following case also applies to X < signed_max+1
                   and X >= signed_max+1 because previous transformations.  */
@@ -11136,8 +11141,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
                    st0 = lang_hooks.types.signed_type (TREE_TYPE (arg0));
                    st1 = lang_hooks.types.signed_type (TREE_TYPE (arg1));
                    return fold_build2 (code == LE_EXPR ? GE_EXPR: LT_EXPR,
-                                       type, fold_convert (st0, arg0),
-                                       build_int_cst (st1, 0));
+                                       type, fold_convert (st0, arg0),
+                                       build_int_cst (st1, 0));
                  }
              }
          }