Commit 63e7fe9b by Jeffrey A Law Committed by Jeff Law

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
parent eb7b11fd
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.
......
......@@ -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))
......
......@@ -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]))"
"*
{
......
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment