diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5a8d6fc9bcd28afd2c5f75bdbfe8cbf582ec3ba0..a804219ef1212073d61d4bb96e9646be3e22e6b6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+Thu Mar 28 16:35:31 2002  Jeffrey A Law  (law@redhat.com)
+
+	* combine.c (simplify_and_const_int): Make sure to apply mask
+	when force_to_mode returns a constant integer.  PR3311.
+
 2002-03-28  John David Anglin  <dave@hiauly1.hia.nrc.ca>
 
 	* pa-linux.h (LOCAL_LABEL_PREFIX): Define.
diff --git a/gcc/combine.c b/gcc/combine.c
index 0a61187071e49367a950b53378f2c061652549a0..adb034d80cab98ca1a9d4e9a8d16e4da90a10d52 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -7838,14 +7838,23 @@ simplify_and_const_int (x, mode, varop, constop)
   int i;
 
   /* Simplify VAROP knowing that we will be only looking at some of the
-     bits in it.  */
+     bits in it.
+
+     Note by passing in CONSTOP, we guarantee that the bits not set in
+     CONSTOP are not significant and will never be examined.  We must
+     ensure that is the case by explicitly masking out those bits
+     before returning.  */
   varop = force_to_mode (varop, mode, constop, NULL_RTX, 0);
 
-  /* If VAROP is a CLOBBER, we will fail so return it; if it is a
-     CONST_INT, we are done.  */
-  if (GET_CODE (varop) == CLOBBER || GET_CODE (varop) == CONST_INT)
+  /* If VAROP is a CLOBBER, we will fail so return it.  */
+  if (GET_CODE (varop) == CLOBBER)
     return varop;
 
+  /* If VAROP is a CONST_INT, then we need to apply the mask in CONSTOP
+     to VAROP and return the new constant.  */
+  if (GET_CODE (varop) == CONST_INT)
+    return GEN_INT (trunc_int_for_mode (INTVAL (varop) & constop, mode));
+
   /* See what bits may be nonzero in VAROP.  Unlike the general case of
      a call to nonzero_bits, here we don't care about bits outside
      MODE.  */