OSDN Git Service

* pa.md (reload_peepholes): Make sure operand is a REG before
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 29 Aug 1997 22:14:07 +0000 (22:14 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 29 Aug 1997 22:14:07 +0000 (22:14 +0000)
        examining REGNO.  Allow general registers too.
Fixes sporatic c-torture failure.

Remove last change to fold-const.c and c-decl.c

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

gcc/ChangeLog
gcc/c-decl.c
gcc/config/pa/pa.md
gcc/fold-const.c

index 2e06e8b..dd03361 100644 (file)
@@ -1,3 +1,8 @@
+Fri Aug 29 16:13:51 1997  Jeffrey A Law  (law@cygnus.com)
+
+       * pa.md (reload_peepholes): Make sure operand is a REG before
+       examining REGNO.  Allow general registers too.
+
 Fri Aug 29 11:42:04 1997  Jim Wilson  <wilson@cygnus.com>
 
        * varasm.c (mark_constants): Don't look inside CONST_DOUBLEs.
@@ -85,11 +90,6 @@ Wed Aug 27 01:56:18 1997  Doug Evans  <dje@seba.cygnus.com>
 
        * loop.c (combine_movables): Earlier insns don't match later ones.
 
-       * c-decl.c (grokdeclarator): If array index or size calculations
-       overflow, issue an error.
-       * fold-const.c (int_const_binop): New static function.
-       (const_binop, size_binop): Call it.
-
 Wed Aug 27 01:24:25 1997  H.J. Lu   (hjl@gnu.ai.mit.edu)
 
        * config/linux.h (CC1_SPEC): Define it only if not defined.
index 316ada7..b556d08 100644 (file)
@@ -4672,18 +4672,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
                                   convert (index_type, size),
                                   convert (index_type, size_one_node)));
 
-             /* If that overflowed, the array is too big.
-                ??? While a size of INT_MAX+1 technically shouldn't cause
-                an overflow (because we subtract 1), the overflow is recorded
-                during the conversion to index_type, before the subtraction.
-                Handling this case seems like an unnecessary complication.  */
-             if (TREE_OVERFLOW (itype))
-               {
-                 error ("size of array `%s' is too large", name);
-                 type = error_mark_node;
-                 continue;
-               }
-
              if (size_varies)
                itype = variable_size (itype);
              itype = build_index_type (itype);
@@ -4859,13 +4847,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
 
   /* Now TYPE has the actual type.  */
 
-  /* Did array size calculations overflow?  */
-
-  if (TREE_CODE (type) == ARRAY_TYPE
-      && TYPE_SIZE (type)
-      && TREE_OVERFLOW (TYPE_SIZE (type)))
-    error ("size of array `%s' is too large", name);
-
   /* If this is declaring a typedef name, return a TYPE_DECL.  */
 
   if (specbits & (1 << (int) RID_TYPEDEF))
index 2f13795..1844a6e 100644 (file)
 ;; Clean up turds left by reload.
 (define_peephole
   [(set (match_operand 0 "reg_or_nonsymb_mem_operand" "")
-       (match_operand 1 "register_operand" "f"))
-   (set (match_operand 2 "register_operand" "f")
+       (match_operand 1 "register_operand" "fr"))
+   (set (match_operand 2 "register_operand" "fr")
        (match_dup 0))]
   "! TARGET_SOFT_FLOAT
    && GET_CODE (operands[0]) == MEM
    && GET_MODE (operands[0]) == GET_MODE (operands[1])
    && GET_MODE (operands[0]) == GET_MODE (operands[2])
    && GET_MODE (operands[0]) == DFmode
+   && GET_CODE (operands[1]) == REG
+   && GET_CODE (operands[2]) == REG
    && REGNO_REG_CLASS (REGNO (operands[1]))
       == REGNO_REG_CLASS (REGNO (operands[2]))"
   "*
 }")
 
 (define_peephole
-  [(set (match_operand 0 "register_operand" "f")
+  [(set (match_operand 0 "register_operand" "fr")
        (match_operand 1 "reg_or_nonsymb_mem_operand" ""))
-   (set (match_operand 2 "register_operand" "f")
+   (set (match_operand 2 "register_operand" "fr")
        (match_dup 1))]
   "! TARGET_SOFT_FLOAT
    && GET_CODE (operands[1]) == MEM
    && GET_MODE (operands[0]) == GET_MODE (operands[1])
    && GET_MODE (operands[0]) == GET_MODE (operands[2])
    && GET_MODE (operands[0]) == DFmode
-   && REGNO_REG_CLASS (REGNO (operands[1]))
+   && GET_CODE (operands[0]) == REG
+   && GET_CODE (operands[2]) == REG
+   && REGNO_REG_CLASS (REGNO (operands[0]))
       == REGNO_REG_CLASS (REGNO (operands[2]))"
   "*
 {
index f62dd94..10b13f3 100644 (file)
@@ -62,7 +62,6 @@ int div_and_round_double      PROTO((enum tree_code, int, HOST_WIDE_INT,
                                       HOST_WIDE_INT *));
 static int split_tree          PROTO((tree, enum tree_code, tree *,
                                       tree *, int *));
-static tree int_const_binop    PROTO((enum tree_code, tree, tree, int, int));
 static tree const_binop                PROTO((enum tree_code, tree, tree, int));
 static tree fold_convert       PROTO((tree, tree));
 static enum tree_code invert_tree_comparison PROTO((enum tree_code));
@@ -1052,215 +1051,192 @@ split_tree (in, code, varp, conp, varsignp)
   return 0;
 }
 \f
-/* Combine two integer constants ARG1 and ARG2 under operation CODE
+/* Combine two constants ARG1 and ARG2 under operation CODE
    to produce a new constant.
+   We assume ARG1 and ARG2 have the same data type,
+   or at least are the same kind of constant and the same machine mode.
 
-   If NOTRUNC is nonzero, do not truncate the result to fit the data type.
-   If FORSIZE is nonzero, compute overflow for unsigned types.  */
+   If NOTRUNC is nonzero, do not truncate the result to fit the data type.  */
 
 static tree
-int_const_binop (code, arg1, arg2, notrunc, forsize)
+const_binop (code, arg1, arg2, notrunc)
      enum tree_code code;
      register tree arg1, arg2;
-     int notrunc, forsize;
+     int notrunc;
 {
-  HOST_WIDE_INT int1l, int1h, int2l, int2h;
-  HOST_WIDE_INT low, hi;
-  HOST_WIDE_INT garbagel, garbageh;
-  register tree t;
-  int uns = TREE_UNSIGNED (TREE_TYPE (arg1));
-  int overflow = 0;
-  int no_overflow = 0;
-
-  int1l = TREE_INT_CST_LOW (arg1);
-  int1h = TREE_INT_CST_HIGH (arg1);
-  int2l = TREE_INT_CST_LOW (arg2);
-  int2h = TREE_INT_CST_HIGH (arg2);
+  STRIP_NOPS (arg1); STRIP_NOPS (arg2);
 
-  switch (code)
+  if (TREE_CODE (arg1) == INTEGER_CST)
     {
-    case BIT_IOR_EXPR:
-      low = int1l | int2l, hi = int1h | int2h;
-      break;
+      register HOST_WIDE_INT int1l = TREE_INT_CST_LOW (arg1);
+      register HOST_WIDE_INT int1h = TREE_INT_CST_HIGH (arg1);
+      HOST_WIDE_INT int2l = TREE_INT_CST_LOW (arg2);
+      HOST_WIDE_INT int2h = TREE_INT_CST_HIGH (arg2);
+      HOST_WIDE_INT low, hi;
+      HOST_WIDE_INT garbagel, garbageh;
+      register tree t;
+      int uns = TREE_UNSIGNED (TREE_TYPE (arg1));
+      int overflow = 0;
+      int no_overflow = 0;
 
-    case BIT_XOR_EXPR:
-      low = int1l ^ int2l, hi = int1h ^ int2h;
-      break;
+      switch (code)
+       {
+       case BIT_IOR_EXPR:
+         low = int1l | int2l, hi = int1h | int2h;
+         break;
 
-    case BIT_AND_EXPR:
-      low = int1l & int2l, hi = int1h & int2h;
-      break;
+       case BIT_XOR_EXPR:
+         low = int1l ^ int2l, hi = int1h ^ int2h;
+         break;
 
-    case BIT_ANDTC_EXPR:
-      low = int1l & ~int2l, hi = int1h & ~int2h;
-      break;
+       case BIT_AND_EXPR:
+         low = int1l & int2l, hi = int1h & int2h;
+         break;
 
-    case RSHIFT_EXPR:
-      int2l = - int2l;
-    case LSHIFT_EXPR:
-      /* It's unclear from the C standard whether shifts can overflow.
-        The following code ignores overflow; perhaps a C standard
-        interpretation ruling is needed.  */
-      lshift_double (int1l, int1h, int2l,
-                    TYPE_PRECISION (TREE_TYPE (arg1)),
-                    &low, &hi,
-                    !uns);
-      no_overflow = 1;
-      break;
+       case BIT_ANDTC_EXPR:
+         low = int1l & ~int2l, hi = int1h & ~int2h;
+         break;
 
-    case RROTATE_EXPR:
-      int2l = - int2l;
-    case LROTATE_EXPR:
-      lrotate_double (int1l, int1h, int2l,
-                     TYPE_PRECISION (TREE_TYPE (arg1)),
-                     &low, &hi);
-      break;
+       case RSHIFT_EXPR:
+         int2l = - int2l;
+       case LSHIFT_EXPR:
+         /* It's unclear from the C standard whether shifts can overflow.
+            The following code ignores overflow; perhaps a C standard
+            interpretation ruling is needed.  */
+         lshift_double (int1l, int1h, int2l,
+                        TYPE_PRECISION (TREE_TYPE (arg1)),
+                        &low, &hi,
+                        !uns);
+         no_overflow = 1;
+         break;
 
-    case PLUS_EXPR:
-      overflow = add_double (int1l, int1h, int2l, int2h, &low, &hi);
-      break;
+       case RROTATE_EXPR:
+         int2l = - int2l;
+       case LROTATE_EXPR:
+         lrotate_double (int1l, int1h, int2l,
+                         TYPE_PRECISION (TREE_TYPE (arg1)),
+                         &low, &hi);
+         break;
 
-    case MINUS_EXPR:
-      neg_double (int2l, int2h, &low, &hi);
-      add_double (int1l, int1h, low, hi, &low, &hi);
-      overflow = overflow_sum_sign (hi, int2h, int1h);
-      break;
+       case PLUS_EXPR:
+         overflow = add_double (int1l, int1h, int2l, int2h, &low, &hi);
+         break;
 
-    case MULT_EXPR:
-      overflow = mul_double (int1l, int1h, int2l, int2h, &low, &hi);
-      break;
+       case MINUS_EXPR:
+         neg_double (int2l, int2h, &low, &hi);
+         add_double (int1l, int1h, low, hi, &low, &hi);
+         overflow = overflow_sum_sign (hi, int2h, int1h);
+         break;
 
-    case TRUNC_DIV_EXPR:
-    case FLOOR_DIV_EXPR: case CEIL_DIV_EXPR:
-    case EXACT_DIV_EXPR:
-      /* This is a shortcut for a common special case.  */
-      if (int2h == 0 && int2l > 0
-         && ! TREE_CONSTANT_OVERFLOW (arg1)
-         && ! TREE_CONSTANT_OVERFLOW (arg2)
-         && int1h == 0 && int1l >= 0)
-       {
-         if (code == CEIL_DIV_EXPR)
-           int1l += int2l - 1;
-         low = int1l / int2l, hi = 0;
+       case MULT_EXPR:
+         overflow = mul_double (int1l, int1h, int2l, int2h, &low, &hi);
          break;
-       }
 
-      /* ... fall through ... */
+       case TRUNC_DIV_EXPR:
+       case FLOOR_DIV_EXPR: case CEIL_DIV_EXPR:
+       case EXACT_DIV_EXPR:
+         /* This is a shortcut for a common special case.  */
+         if (int2h == 0 && int2l > 0
+             && ! TREE_CONSTANT_OVERFLOW (arg1)
+             && ! TREE_CONSTANT_OVERFLOW (arg2)
+             && int1h == 0 && int1l >= 0)
+           {
+             if (code == CEIL_DIV_EXPR)
+               int1l += int2l - 1;
+             low = int1l / int2l, hi = 0;
+             break;
+           }
 
-    case ROUND_DIV_EXPR: 
-      if (int2h == 0 && int2l == 1)
-       {
-         low = int1l, hi = int1h;
-         break;
-       }
-      if (int1l == int2l && int1h == int2h
-         && ! (int1l == 0 && int1h == 0))
-       {
-         low = 1, hi = 0;
-         break;
-       }
-      overflow = div_and_round_double (code, uns,
-                                      int1l, int1h, int2l, int2h,
-                                      &low, &hi, &garbagel, &garbageh);
-      break;
+         /* ... fall through ... */
 
-    case TRUNC_MOD_EXPR:
-    case FLOOR_MOD_EXPR: case CEIL_MOD_EXPR:
-      /* This is a shortcut for a common special case.  */
-      if (int2h == 0 && int2l > 0
-         && ! TREE_CONSTANT_OVERFLOW (arg1)
-         && ! TREE_CONSTANT_OVERFLOW (arg2)
-         && int1h == 0 && int1l >= 0)
-       {
-         if (code == CEIL_MOD_EXPR)
-           int1l += int2l - 1;
-         low = int1l % int2l, hi = 0;
+       case ROUND_DIV_EXPR: 
+         if (int2h == 0 && int2l == 1)
+           {
+             low = int1l, hi = int1h;
+             break;
+           }
+         if (int1l == int2l && int1h == int2h
+             && ! (int1l == 0 && int1h == 0))
+           {
+             low = 1, hi = 0;
+             break;
+           }
+         overflow = div_and_round_double (code, uns,
+                                          int1l, int1h, int2l, int2h,
+                                          &low, &hi, &garbagel, &garbageh);
          break;
-       }
 
-      /* ... fall through ... */
+       case TRUNC_MOD_EXPR:
+       case FLOOR_MOD_EXPR: case CEIL_MOD_EXPR:
+         /* This is a shortcut for a common special case.  */
+         if (int2h == 0 && int2l > 0
+             && ! TREE_CONSTANT_OVERFLOW (arg1)
+             && ! TREE_CONSTANT_OVERFLOW (arg2)
+             && int1h == 0 && int1l >= 0)
+           {
+             if (code == CEIL_MOD_EXPR)
+               int1l += int2l - 1;
+             low = int1l % int2l, hi = 0;
+             break;
+           }
 
-    case ROUND_MOD_EXPR: 
-      overflow = div_and_round_double (code, uns,
-                                      int1l, int1h, int2l, int2h,
-                                      &garbagel, &garbageh, &low, &hi);
-      break;
+         /* ... fall through ... */
 
-    case MIN_EXPR:
-    case MAX_EXPR:
-      if (uns)
-       {
-         low = (((unsigned HOST_WIDE_INT) int1h
-                 < (unsigned HOST_WIDE_INT) int2h)
-                || (((unsigned HOST_WIDE_INT) int1h
-                     == (unsigned HOST_WIDE_INT) int2h)
-                    && ((unsigned HOST_WIDE_INT) int1l
-                        < (unsigned HOST_WIDE_INT) int2l)));
+       case ROUND_MOD_EXPR: 
+         overflow = div_and_round_double (code, uns,
+                                          int1l, int1h, int2l, int2h,
+                                          &garbagel, &garbageh, &low, &hi);
+         break;
+
+       case MIN_EXPR:
+       case MAX_EXPR:
+         if (uns)
+           {
+             low = (((unsigned HOST_WIDE_INT) int1h
+                     < (unsigned HOST_WIDE_INT) int2h)
+                    || (((unsigned HOST_WIDE_INT) int1h
+                         == (unsigned HOST_WIDE_INT) int2h)
+                        && ((unsigned HOST_WIDE_INT) int1l
+                            < (unsigned HOST_WIDE_INT) int2l)));
+           }
+         else
+           {
+             low = ((int1h < int2h)
+                    || ((int1h == int2h)
+                        && ((unsigned HOST_WIDE_INT) int1l
+                            < (unsigned HOST_WIDE_INT) int2l)));
+           }
+         if (low == (code == MIN_EXPR))
+           low = int1l, hi = int1h;
+         else
+           low = int2l, hi = int2h;
+         break;
+
+       default:
+         abort ();
        }
+    got_it:
+      if (TREE_TYPE (arg1) == sizetype && hi == 0
+         && low >= 0 && low <= TREE_INT_CST_LOW (TYPE_MAX_VALUE (sizetype))
+         && ! overflow
+         && ! TREE_OVERFLOW (arg1) && ! TREE_OVERFLOW (arg2))
+       t = size_int (low);
       else
        {
-         low = ((int1h < int2h)
-                || ((int1h == int2h)
-                    && ((unsigned HOST_WIDE_INT) int1l
-                        < (unsigned HOST_WIDE_INT) int2l)));
+         t = build_int_2 (low, hi);
+         TREE_TYPE (t) = TREE_TYPE (arg1);
        }
-      if (low == (code == MIN_EXPR))
-       low = int1l, hi = int1h;
-      else
-       low = int2l, hi = int2h;
-      break;
-
-    default:
-      abort ();
-    }
 
-  if (TREE_TYPE (arg1) == sizetype && hi == 0
-      && low >= 0 && low <= TREE_INT_CST_LOW (TYPE_MAX_VALUE (sizetype))
-      && ! overflow
-      && ! TREE_OVERFLOW (arg1) && ! TREE_OVERFLOW (arg2))
-    t = size_int (low);
-  else
-    {
-      t = build_int_2 (low, hi);
-      TREE_TYPE (t) = TREE_TYPE (arg1);
+      TREE_OVERFLOW (t)
+       = ((notrunc ? !uns && overflow
+           : force_fit_type (t, overflow && !uns) && ! no_overflow)
+          | TREE_OVERFLOW (arg1)
+          | TREE_OVERFLOW (arg2));
+      TREE_CONSTANT_OVERFLOW (t) = (TREE_OVERFLOW (t)
+                                   | TREE_CONSTANT_OVERFLOW (arg1)
+                                   | TREE_CONSTANT_OVERFLOW (arg2));
+      return t;
     }
-
-  TREE_OVERFLOW (t)
-    = ((notrunc ? (!uns || forsize) && overflow
-       : force_fit_type (t, (!uns || forsize) && overflow) && ! no_overflow)
-       | TREE_OVERFLOW (arg1)
-       | TREE_OVERFLOW (arg2));
-  /* If we're doing a size calculation, unsigned arithmetic does overflow.
-     So check if force_fit_type truncated the value.  */
-  if (forsize
-      && ! TREE_OVERFLOW (t)
-      && (TREE_INT_CST_HIGH (t) != hi
-         || TREE_INT_CST_LOW (t) != low))
-    TREE_OVERFLOW (t) = 1;
-  TREE_CONSTANT_OVERFLOW (t) = (TREE_OVERFLOW (t)
-                               | TREE_CONSTANT_OVERFLOW (arg1)
-                               | TREE_CONSTANT_OVERFLOW (arg2));
-  return t;
-}
-
-/* Combine two constants ARG1 and ARG2 under operation CODE
-   to produce a new constant.
-   We assume ARG1 and ARG2 have the same data type,
-   or at least are the same kind of constant and the same machine mode.
-
-   If NOTRUNC is nonzero, do not truncate the result to fit the data type.  */
-
-static tree
-const_binop (code, arg1, arg2, notrunc)
-     enum tree_code code;
-     register tree arg1, arg2;
-     int notrunc;
-{
-  STRIP_NOPS (arg1); STRIP_NOPS (arg2);
-
-  if (TREE_CODE (arg1) == INTEGER_CST)
-    return int_const_binop (code, arg1, arg2, notrunc, 0);
-
 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
   if (TREE_CODE (arg1) == REAL_CST)
     {
@@ -1474,7 +1450,7 @@ size_binop (code, arg0, arg1)
        return arg1;
 
       /* Handle general case of two integer constants.  */
-      return int_const_binop (code, arg0, arg1, 0, 1);
+      return const_binop (code, arg0, arg1, 0);
     }
 
   if (arg0 == error_mark_node || arg1 == error_mark_node)