This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix ICE in do_SUBST
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 17 May 2002 00:35:39 +0200
- Subject: [PATCH] Fix ICE in do_SUBST
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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