aboutsummaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2002-02-20 23:15:00 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2002-02-20 23:15:00 +0000
commit4161da12190d52eb1d622354e6ea67f67195c73c (patch)
tree55c3d095668c86b8d785d6a6b95f142a8823cd52 /gcc/combine.c
parent8e8d61f5c1ddd2e55ae3c32347af851eaeb83e0a (diff)
downloadgcc-4161da12190d52eb1d622354e6ea67f67195c73c.zip
gcc-4161da12190d52eb1d622354e6ea67f67195c73c.tar.gz
gcc-4161da12190d52eb1d622354e6ea67f67195c73c.tar.bz2
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
Diffstat (limited to 'gcc/combine.c')
-rw-r--r--gcc/combine.c71
1 files changed, 70 insertions, 1 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index eb82531..dba7997 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -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--)