diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 14bd7a7d8fd709171e36fc2b9c84796b40a5e2f4..e1984f4d1106d269ab48e00d3d882691f559dfdd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+Thu Feb 21 16:20:46 2002  Alexandre Oliva  <aoliva@redhat.com>
+
+	* rtlanal.c (replace_rtx): Don't make a CONST_INT the operand of
+	SUBREG or ZERO_EXTEND.
+
 Thu Feb 21 15:35:46 2002  J"orn Rennecke <joern.rennecke@superh.com>
 
 	* sh.h (current_function_anonymous_args): Remove.
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 37f1e64910acebee9188b8d25936ea59b7900662..5f338e86e2f91d03149987ba91c135ca9c0a784b 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -2417,6 +2417,40 @@ replace_rtx (x, from, to)
   if (x == 0)
     return 0;
 
+  if (GET_CODE (x) == SUBREG)
+    {
+      rtx new = replace_rtx (SUBREG_REG (x), from, to);
+
+      if (GET_CODE (new) == CONST_INT)
+	{
+	  x = simplify_subreg (GET_MODE (x), new,
+			       GET_MODE (SUBREG_REG (x)),
+			       SUBREG_BYTE (x));
+	  if (! x)
+	    abort ();
+	}
+      else
+	SUBREG_REG (x) = new;
+
+      return x;
+    }
+  else if (GET_CODE (x) == ZERO_EXTEND)
+    {
+      rtx new = replace_rtx (XEXP (x, 0), from, to);
+
+      if (GET_CODE (new) == CONST_INT)
+	{
+	  x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
+					new, GET_MODE (XEXP (x, 0)));
+	  if (! x)
+	    abort ();
+	}
+      else
+	XEXP (x, 0) = new;
+
+      return x;
+    }
+
   fmt = GET_RTX_FORMAT (GET_CODE (x));
   for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
     {