mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-07 14:57:21 +08:00
combine.c (do_SUBST): Sanity check substitutions of CONST_INTs...
* combine.c (do_SUBST): Sanity check substitutions of CONST_INTs, and reject them in SUBREGs and ZERO_EXTENDs. (subst): Simplify SUBREG or ZERO_EXTEND instead of SUBSTing a CONST_INT into its operand. (known_cond): Likewise, for ZERO_EXTEND. * simplify-rtx.c (simplify_unary_operation): Fix condition to allow for simplification of wide modes. Reject CONST_INTs in ZERO_EXTEND when their actual mode is not given. From-SVN: r49920
This commit is contained in:
parent
8e8d61f5c1
commit
4161da1219
@ -1,3 +1,14 @@
|
||||
2002-02-20 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* combine.c (do_SUBST): Sanity check substitutions of
|
||||
CONST_INTs, and reject them in SUBREGs and ZERO_EXTENDs.
|
||||
(subst): Simplify SUBREG or ZERO_EXTEND instead of SUBSTing a
|
||||
CONST_INT into its operand.
|
||||
(known_cond): Likewise, for ZERO_EXTEND.
|
||||
* simplify-rtx.c (simplify_unary_operation): Fix condition to
|
||||
allow for simplification of wide modes. Reject CONST_INTs in
|
||||
ZERO_EXTEND when their actual mode is not given.
|
||||
|
||||
2002-02-20 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* c-decl.c (pushdecl): If no global declaration is found for an
|
||||
|
@ -424,6 +424,33 @@ do_SUBST (into, newval)
|
||||
if (oldval == newval)
|
||||
return;
|
||||
|
||||
/* We'd like to catch as many invalid transformations here as
|
||||
possible. Unfortunately, there are way too many mode changes
|
||||
that are perfectly valid, so we'd waste too much effort for
|
||||
little gain doing the checks here. Focus on catching invalid
|
||||
transformations involving integer constants. */
|
||||
if (GET_MODE_CLASS (GET_MODE (oldval)) == MODE_INT
|
||||
&& GET_CODE (newval) == CONST_INT)
|
||||
{
|
||||
/* Sanity check that we're replacing oldval with a CONST_INT
|
||||
that is a valid sign-extension for the original mode. */
|
||||
if (INTVAL (newval) != trunc_int_for_mode (INTVAL (newval),
|
||||
GET_MODE (oldval)))
|
||||
abort ();
|
||||
|
||||
/* Replacing the operand of a SUBREG or a ZERO_EXTEND with a
|
||||
CONST_INT is not valid, because after the replacement, the
|
||||
original mode would be gone. Unfortunately, we can't tell
|
||||
when do_SUBST is called to replace the operand thereof, so we
|
||||
perform this test on oldval instead, checking whether an
|
||||
invalid replacement took place before we got here. */
|
||||
if ((GET_CODE (oldval) == SUBREG
|
||||
&& GET_CODE (SUBREG_REG (oldval)) == CONST_INT)
|
||||
|| (GET_CODE (oldval) == ZERO_EXTEND
|
||||
&& GET_CODE (XEXP (oldval, 0)) == CONST_INT))
|
||||
abort ();
|
||||
}
|
||||
|
||||
if (undobuf.frees)
|
||||
buf = undobuf.frees, undobuf.frees = buf->next;
|
||||
else
|
||||
@ -3505,7 +3532,24 @@ subst (x, from, to, in_dest, unique_copy)
|
||||
if (GET_CODE (new) == CLOBBER && XEXP (new, 0) == const0_rtx)
|
||||
return new;
|
||||
|
||||
SUBST (XEXP (x, i), new);
|
||||
if (GET_CODE (new) == CONST_INT && GET_CODE (x) == SUBREG)
|
||||
{
|
||||
x = simplify_subreg (GET_MODE (x), new,
|
||||
GET_MODE (SUBREG_REG (x)),
|
||||
SUBREG_BYTE (x));
|
||||
if (! x)
|
||||
abort ();
|
||||
}
|
||||
else if (GET_CODE (new) == CONST_INT
|
||||
&& GET_CODE (x) == ZERO_EXTEND)
|
||||
{
|
||||
x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
|
||||
new, GET_MODE (XEXP (x, 0)));
|
||||
if (! x)
|
||||
abort ();
|
||||
}
|
||||
else
|
||||
SUBST (XEXP (x, i), new);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7449,6 +7493,31 @@ known_cond (x, cond, reg, val)
|
||||
|
||||
return x;
|
||||
}
|
||||
/* We don't have to handle SIGN_EXTEND here, because even in the
|
||||
case of replacing something with a modeless CONST_INT, a
|
||||
CONST_INT is already (supposed to be) a valid sign extension for
|
||||
its narrower mode, which implies it's already properly
|
||||
sign-extended for the wider mode. Now, for ZERO_EXTEND, the
|
||||
story is different. */
|
||||
else if (code == ZERO_EXTEND)
|
||||
{
|
||||
enum machine_mode inner_mode = GET_MODE (XEXP (x, 0));
|
||||
rtx new, r = known_cond (XEXP (x, 0), cond, reg, val);
|
||||
|
||||
if (XEXP (x, 0) != r)
|
||||
{
|
||||
/* We must simplify the zero_extend here, before we lose
|
||||
track of the original inner_mode. */
|
||||
new = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
|
||||
r, inner_mode);
|
||||
if (new)
|
||||
return new;
|
||||
else
|
||||
SUBST (XEXP (x, 0), r);
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
fmt = GET_RTX_FORMAT (code);
|
||||
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
|
||||
|
@ -528,8 +528,10 @@ simplify_unary_operation (code, mode, op, op_mode)
|
||||
break;
|
||||
|
||||
case ZERO_EXTEND:
|
||||
/* When zero-extending a CONST_INT, we need to know its
|
||||
original mode. */
|
||||
if (op_mode == VOIDmode)
|
||||
op_mode = mode;
|
||||
abort ();
|
||||
if (GET_MODE_BITSIZE (op_mode) == HOST_BITS_PER_WIDE_INT)
|
||||
{
|
||||
/* If we were really extending the mode,
|
||||
@ -587,7 +589,8 @@ simplify_unary_operation (code, mode, op, op_mode)
|
||||
|
||||
/* We can do some operations on integer CONST_DOUBLEs. Also allow
|
||||
for a DImode operation on a CONST_INT. */
|
||||
else if (GET_MODE (trueop) == VOIDmode && width <= HOST_BITS_PER_INT * 2
|
||||
else if (GET_MODE (trueop) == VOIDmode
|
||||
&& width <= HOST_BITS_PER_WIDE_INT * 2
|
||||
&& (GET_CODE (trueop) == CONST_DOUBLE
|
||||
|| GET_CODE (trueop) == CONST_INT))
|
||||
{
|
||||
@ -631,8 +634,10 @@ simplify_unary_operation (code, mode, op, op_mode)
|
||||
break;
|
||||
|
||||
case ZERO_EXTEND:
|
||||
if (op_mode == VOIDmode
|
||||
|| GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT)
|
||||
if (op_mode == VOIDmode)
|
||||
abort ();
|
||||
|
||||
if (GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT)
|
||||
return 0;
|
||||
|
||||
hv = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user