recog.c (validate_replace_rtx_1): Consider subregs when replacing a register with...
authorRichard Henderson <rth@redhat.com>
Fri, 10 Nov 2000 00:07:52 +0000 (16:07 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Fri, 10 Nov 2000 00:07:52 +0000 (16:07 -0800)
        * recog.c (validate_replace_rtx_1): Consider subregs when
        replacing a register with a constant inside a sign/zero_extend.

From-SVN: r37352

gcc/ChangeLog
gcc/recog.c

index e0fe0ed2fd065e33a94b5f5daae0ef67ee15ea10..d8dde6af720a5b7dca50ebe922328296c07c1f02 100644 (file)
@@ -1,5 +1,8 @@
 2000-11-09  Richard Henderson  <rth@redhat.com>
 
+       * recog.c (validate_replace_rtx_1): Consider subregs when
+       replacing a register with a constant inside a sign/zero_extend.
+
        * config/alpha/linux.h (HANDLE_PRAGMA_PACK_PUSH_POP): Define.
 
 2000-11-09  Geoffrey Keating  <geoffk@redhat.com>
index b8b532e24037b814f47b3c6cb411e1e5e2080335..c01f884ebb4fdb9d4c113cdee048f3a949a5e4d9 100644 (file)
@@ -480,14 +480,29 @@ validate_replace_rtx_1 (loc, from, to, object)
       /* In these cases, the operation to be performed depends on the mode
         of the operand.  If we are replacing the operand with a VOIDmode
         constant, we lose the information.  So try to simplify the operation
-        in that case.  If it fails, substitute in something that we know
-        won't be recognized.  */
+        in that case.  */
       if (GET_MODE (to) == VOIDmode
-         && rtx_equal_p (XEXP (x, 0), from))
+         && (rtx_equal_p (XEXP (x, 0), from)
+             || (GET_CODE (XEXP (x, 0)) == SUBREG
+                 && rtx_equal_p (SUBREG_REG (XEXP (x, 0)), from))))
        {
-         rtx new = simplify_unary_operation (code, GET_MODE (x), to,
-                                             GET_MODE (from));
-         if (new == 0)
+         rtx new = NULL_RTX;
+
+         /* If there is a subreg involved, crop to the portion of the
+            constant that we are interested in.  */
+         if (GET_CODE (XEXP (x, 0)) == SUBREG)
+           to = operand_subword (to, SUBREG_WORD (XEXP (x, 0)),
+                                 0, GET_MODE (from));
+
+         /* If the above didn't fail, perform the extension from the
+            mode of the operand (and not the mode of FROM).  */
+         if (to)
+           new = simplify_unary_operation (code, GET_MODE (x), to,
+                                           GET_MODE (XEXP (x, 0)));
+
+         /* If any of the above failed, substitute in something that
+            we know won't be recognized.  */
+         if (!new)
            new = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
 
          validate_change (object, loc, new, 1);