diff options
author | Jeffrey A Law <law@cygnus.com> | 1997-08-29 22:14:07 +0000 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1997-08-29 16:14:07 -0600 |
commit | 63e7fe9ba41df48e63a3a837a340f2e872421d4e (patch) | |
tree | 7d9d57ce58d730a09cfd1ea2569dc58950c18cba /gcc | |
parent | eb7b11fd0742ac1377e3b6338feec6fc2e64200e (diff) | |
download | gcc-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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/c-decl.c | 19 | ||||
-rw-r--r-- | gcc/config/pa/pa.md | 14 | ||||
-rw-r--r-- | gcc/fold-const.c | 334 |
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) |