This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix 3.1 ICE on mplayer (regression from egcs 1.1.2 at least)


Hi!

The attached testcase ICEs on IA-32, because immediate_operand predicate
is used together with just I constraint in shift & compare patterns,
resulting in combine making those patterns but if it is anything which I
constraint doesn't grok, it will not reload.
The patch below fixes it and even ensures that if for some strange reason
shift by 0 followed by compare was not optimized out, we'd not match
the pattern.
PR middle-end/7245 is apparently the same bug.
Ok to commit branch/trunk?

BTW: I wonder whether const_int_1_operand shouldn't be killed and replaced
by const1_operand, any CONST_INT with INTVAL() == 1 should
be const1_rtx, shouldn't it?

2002-07-10  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.

	* gcc.c-torture/compile/20020710-1.c: New test.

--- gcc/config/i386/i386.c.jj	Wed Jul 10 11:37:30 2002
+++ gcc/config/i386/i386.c	Wed Jul 10 16:56:20 2002
@@ -2896,6 +2896,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.  */
 
--- gcc/config/i386/i386.h.jj	Wed Jun 19 15:18:06 2002
+++ gcc/config/i386/i386.h	Wed Jul 10 16:56:41 2002
@@ -3029,6 +3029,7 @@ extern int const svr4_dbx_register_map[F
 				       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}},			\
--- gcc/config/i386/i386.md.jj	Wed Jul 10 11:37:31 2002
+++ gcc/config/i386/i386.md	Wed Jul 10 17:00:12 2002
@@ -10950,7 +10950,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)))]
@@ -10989,7 +10989,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))))]
@@ -11114,7 +11114,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)))]
@@ -11278,7 +11278,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)))]
@@ -11628,7 +11628,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)))]
@@ -11642,7 +11642,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))))]
@@ -11714,7 +11714,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)))]
@@ -11786,7 +11786,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)))]
@@ -12019,7 +12019,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)))]
@@ -12033,7 +12033,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)))]
@@ -12105,7 +12105,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)))]
@@ -12177,7 +12177,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)))]
--- gcc/testsuite/gcc.c-torture/compile/20020710-1.c.jj	Wed Jul 10 17:04:51 2002
+++ gcc/testsuite/gcc.c-torture/compile/20020710-1.c	Wed Jul 10 17:09:23 2002
@@ -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;
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]