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 ICE in do_SUBST


Hi!

The following testcase ICEs on IA-32, because combine creates invalid
CONST_INT (0xf6 in QImode IOR operation) and then tries to substitute it.
As sign-extended CONST_INTs are now mandatory, I don't see any other
solution than to kill the offending code (force_to_mode above it already
properly truncates it for the mode).
It is a regression from 3.0.x (like all other do_SUBST ICEs).
Ok to commit if testing succeeds?

2002-05-17  Jakub Jelinek  <jakub@redhat.com>

	* combine.c (force_to_mode): Don't clear CONST_INT bits outside of
	mode.

	* gcc.dg/20020517-1.c: New test.

--- gcc/testsuite/gcc.dg/20020517-1.c.jj	Fri May 17 00:31:03 2002
+++ gcc/testsuite/gcc.dg/20020517-1.c	Fri May 17 00:36:48 2002
@@ -0,0 +1,28 @@
+/* This testcase caused ICE in do_SUBST on IA-32, because 0xf6 constant
+   was not sign-extended for QImode.  */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-options "-O2 -mcpu=i686" { target i?86-*-* } } */
+
+#include <limits.h>
+
+void abort (void);
+void exit (int);
+
+void foo (void)
+{
+  int i;
+  char *p;
+
+  p = (char *) &i;
+  *p = -10;
+  if (* (unsigned char *) p != 0x100 - 10)
+    abort ();
+}
+
+int main (void)
+{
+  if (UCHAR_MAX == 255)
+    foo ();
+  exit (0);
+}
--- gcc/combine.c.jj	Thu May  2 12:12:00 2002
+++ gcc/combine.c	Fri May 17 00:28:00 2002
@@ -6914,14 +6914,6 @@ force_to_mode (x, mode, mask, reg, just_
 				     force_to_mode (XEXP (x, 1), mode, mask,
 						    reg, next_select));
 
-      /* If OP1 is a CONST_INT and X is an IOR or XOR, clear bits outside
-	 MASK since OP1 might have been sign-extended but we never want
-	 to turn on extra bits, since combine might have previously relied
-	 on them being off.  */
-      if (GET_CODE (op1) == CONST_INT && (code == IOR || code == XOR)
-	  && (INTVAL (op1) & mask) != 0)
-	op1 = GEN_INT (INTVAL (op1) & mask);
-
       if (op_mode != GET_MODE (x) || op0 != XEXP (x, 0) || op1 != XEXP (x, 1))
 	x = gen_binary (code, op_mode, op0, op1);
       break;

	Jakub


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