diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 14440b5bfdeb0a68115042d5c67e857ed6ff16e4..8e16cb3cd32dbba9d6798c548cfb79673a2e0d33 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2002-07-15  Jakub Jelinek  <jakub@redhat.com>
+
+	PR middle-end/7245
+	* config/i386/i386.c (const_int_1_31_operand): New.
+	* config/i386/i386.h (PREDICATE_CODES): Add it.
+	* config/i386/i386.md (ashlsi3_cmp, ashlsi3_cmp_zext, ashlhi3_cmp,
+	ashlqi3_cmp, ashrsi3_cmp, ashrsi3_cmp_zext, ashrhi3_cmp, ashrqi3_cmp,
+	lshrsi3_cmp, lshrsi3_cmp_zext, lshrhi3_cmp, lshrqi3_cmp): Use it.
+
 2002-07-14  Alan Modra  <amodra@bigpond.net.au>
 
 	PR target/7282
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index b21737f984cc5a2d9f4bc9c1a58bb9d2b48b0477..4800949d3ad0ff7653f8c23994905526e372acac 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2838,6 +2838,18 @@ const_int_1_operand (op, mode)
   return (GET_CODE (op) == CONST_INT && INTVAL (op) == 1);
 }
 
+/* Return nonzero if OP is CONST_INT >= 1 and <= 31 (a valid operand
+   for shift & compare patterns, as shifting by 0 does not change flags),
+   else return zero.  */
+
+int
+const_int_1_31_operand (op, mode)
+     rtx op;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+  return (GET_CODE (op) == CONST_INT && INTVAL (op) >= 1 && INTVAL (op) <= 31);
+}
+
 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
    reference and a constant.  */
 
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 7098275a0f89a2acec873ce1d8afdce5cf05c74f..826e77890d747f5f36b086cb72635b9e199315d9 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -3142,6 +3142,7 @@ do {						\
 				       SYMBOL_REF, LABEL_REF}},		\
   {"shiftdi_operand", {SUBREG, REG, MEM}},				\
   {"const_int_1_operand", {CONST_INT}},					\
+  {"const_int_1_31_operand", {CONST_INT}},				\
   {"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}},			\
   {"aligned_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,	\
 		       LABEL_REF, SUBREG, REG, MEM}},			\
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 419d45c76729df23746ff409b9aa23516fafb33a..d75ddee4415207cbe900ad7e334aaca73378d53f 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -10687,7 +10687,7 @@
   [(set (reg 17)
 	(compare
 	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
-		     (match_operand:QI 2 "immediate_operand" "I"))
+		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
 	  (const_int 0)))
    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
 	(ashift:SI (match_dup 1) (match_dup 2)))]
@@ -10726,7 +10726,7 @@
   [(set (reg 17)
 	(compare
 	  (ashift:SI (match_operand:SI 1 "register_operand" "0")
-		     (match_operand:QI 2 "immediate_operand" "I"))
+		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
 	  (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=r")
 	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
@@ -10851,7 +10851,7 @@
   [(set (reg 17)
 	(compare
 	  (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
-		     (match_operand:QI 2 "immediate_operand" "I"))
+		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
 	  (const_int 0)))
    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
 	(ashift:HI (match_dup 1) (match_dup 2)))]
@@ -11015,7 +11015,7 @@
   [(set (reg 17)
 	(compare
 	  (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
-		     (match_operand:QI 2 "immediate_operand" "I"))
+		     (match_operand:QI 2 "const_int_1_31_operand" "I"))
 	  (const_int 0)))
    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
 	(ashift:QI (match_dup 1) (match_dup 2)))]
@@ -11365,7 +11365,7 @@
   [(set (reg 17)
 	(compare
 	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
-		       (match_operand:QI 2 "immediate_operand" "I"))
+		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
 	  (const_int 0)))
    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
 	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
@@ -11379,7 +11379,7 @@
   [(set (reg 17)
 	(compare
 	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
-		       (match_operand:QI 2 "immediate_operand" "I"))
+		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
 	  (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=r")
 	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
@@ -11451,7 +11451,7 @@
   [(set (reg 17)
 	(compare
 	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
-		       (match_operand:QI 2 "immediate_operand" "I"))
+		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
 	  (const_int 0)))
    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
 	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
@@ -11551,7 +11551,7 @@
   [(set (reg 17)
 	(compare
 	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
-		       (match_operand:QI 2 "immediate_operand" "I"))
+		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
 	  (const_int 0)))
    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
 	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
@@ -11784,7 +11784,7 @@
   [(set (reg 17)
 	(compare
 	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
-		       (match_operand:QI 2 "immediate_operand" "I"))
+		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
 	  (const_int 0)))
    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
 	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
@@ -11798,7 +11798,7 @@
   [(set (reg 17)
 	(compare
 	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
-		       (match_operand:QI 2 "immediate_operand" "I"))
+		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
 	  (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=r")
 	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
@@ -11870,7 +11870,7 @@
   [(set (reg 17)
 	(compare
 	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
-		       (match_operand:QI 2 "immediate_operand" "I"))
+		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
 	  (const_int 0)))
    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
 	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
@@ -11970,7 +11970,7 @@
   [(set (reg 17)
 	(compare
 	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
-		       (match_operand:QI 2 "immediate_operand" "I"))
+		       (match_operand:QI 2 "const_int_1_31_operand" "I"))
 	  (const_int 0)))
    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
 	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f9f6bb64997016386b7509acd4f3c61c7633b6d8..4883daf0ef0b0f6fbcc047d9d731b264146312a4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2002-07-15  Jakub Jelinek  <jakub@redhat.com>
+
+	* gcc.c-torture/compile/20020710-1.c: New test.
+
 Thu Jul 11 15:39:21 2002  J"orn Rennecke <joern.rennecke@superh.com>
                           Andrew Pinski  <pinskia@physics.uc.edu>
 
diff --git a/gcc/testsuite/gcc.c-torture/compile/20020710-1.c b/gcc/testsuite/gcc.c-torture/compile/20020710-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..bf6c9066cdd738b00dc0bf51ff1b7cae310fbbb0
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20020710-1.c
@@ -0,0 +1,12 @@
+/* Red Hat bugzilla #68395
+   PR middle-end/7245
+   This testcase ICEd on IA-32 because shift & compare patterns
+   predicates allowed any immediate, but constraints allowed only
+   numbers from 1 to 31.  */
+
+void foo (int *x, unsigned int y)
+{
+  int a = y >> -13;
+  if (a)
+    *x = a;
+}