aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey A Law <law@cygnus.com>1997-08-29 22:14:07 +0000
committerJeff Law <law@gcc.gnu.org>1997-08-29 16:14:07 -0600
commit63e7fe9ba41df48e63a3a837a340f2e872421d4e (patch)
tree7d9d57ce58d730a09cfd1ea2569dc58950c18cba
parenteb7b11fd0742ac1377e3b6338feec6fc2e64200e (diff)
downloadgcc-63e7fe9ba41df48e63a3a837a340f2e872421d4e.zip
gcc-63e7fe9ba41df48e63a3a837a340f2e872421d4e.tar.gz
gcc-63e7fe9ba41df48e63a3a837a340f2e872421d4e.tar.bz2
pa.md (reload_peepholes): Make sure operand is a REG before examining REGNO.
* pa.md (reload_peepholes): Make sure operand is a REG before examining REGNO. Allow general registers too. Fixes sporatic c-torture failure. Remove last change to fold-const.c and c-decl.c From-SVN: r15000
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/c-decl.c19
-rw-r--r--gcc/config/pa/pa.md14
-rw-r--r--gcc/fold-const.c334
4 files changed, 169 insertions, 208 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2e06e8b..dd03361 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 316ada7..b556d08 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -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))
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index 2f13795..1844a6e 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -4835,8 +4835,8 @@
;; 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
@@ -4844,6 +4844,8 @@
&& 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]))"
"*
@@ -4871,9 +4873,9 @@
}")
(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
@@ -4881,7 +4883,9 @@
&& 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]))"
"*
{
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index f62dd94..10b13f3 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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;
}
-/* 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)