]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
fold-const.c (fold_binary): Use the precision of the type instead of the size of...
authorEric Botcazou <ebotcazou@adacore.com>
Fri, 1 Dec 2006 22:46:45 +0000 (22:46 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Fri, 1 Dec 2006 22:46:45 +0000 (22:46 +0000)
* 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.

From-SVN: r119422

gcc/ChangeLog
gcc/fold-const.c

index f09a8232772dee550c9a449d9c59aeaec21e6cde..f322b66e2e1edf07a8342ba71becf1ca1c548045 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 b19b7688a2dcb1f78938073757db7292b34d60be..fce41c2bdb1287aa0b1a2ab234064bcf4afa8e71 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));
                  }
              }
          }