[PATCH] Fix i386 ICE (simplify_subreg volatile mem issue)

Jakub Jelinek jakub@redhat.com
Mon Mar 4 05:49:00 GMT 2002


Hi!

The following patch fixes an unrecognizable instruction on IA-32:
this is related to http://gcc.gnu.org/ml/gcc/2001-06/msg00656.html
but as IA-32 has movdi instruction (well, movdi expander which in
some cases just splits instructions),
((subreg:SI (mem/v:DI (reg/f:SI 60) 2) 4))
is never simplified and never recognized.

This is a regression against 3.0.x.

Below is one possible fix for this exact testcase, though I'm not sure
if other similar issues are lurking somewhere. This fix is the right thing
for arches which have native instructions to load/store 2*wordsize IMHO
as there it forces the volatile value to be read by one insn, not several.
On the other side, it slightly pesimizes flag store if there is no
native 2*wordsize move instruction.
Another solution could be to kill MEM_VOLATILE_P test in simplify_subreg
either completely, or allow (subreg (mem/v ())) be simplified at least
during initial code generation.
Another is to do the volatile check in gen_highpart and do something for
volatile mems (in the following testcase, the low part was expanded
into SImode load without any complain while only high part resulted in
SImode subreg of DImove volatile memory).

2002-03-04  Jakub Jelinek  <jakub@redhat.com>

	* expmed.c (emit_store_flag): Don't test BITS_PER_WORD * 2
	wide volatile memory by parts.

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

--- testsuite/gcc.c-torture/compile/20020304-1.c.jj	Thu Aug 30 22:30:55 2001
+++ testsuite/gcc.c-torture/compile/20020304-1.c	Mon Mar  4 13:01:56 2002
@@ -0,0 +1,10 @@
+/* This testcase ICEd because a SUBREG of MEM/v was never
+   simplified.  */
+volatile unsigned long long *a;
+
+unsigned char
+foo (void)
+{
+  unsigned char b = (*a != 0);
+  return b;
+}
--- gcc/expmed.c.jj	Mon Mar  4 12:13:17 2002
+++ gcc/expmed.c	Mon Mar  4 14:43:44 2002
@@ -4278,7 +4278,8 @@ emit_store_flag (target, code, op0, op1,
      the comparison into one involving a single word.  */
   if (GET_MODE_BITSIZE (mode) == BITS_PER_WORD * 2
       && GET_MODE_CLASS (mode) == MODE_INT
-      && op1 == const0_rtx)
+      && op1 == const0_rtx
+      && (GET_CODE (op0) != MEM || ! MEM_VOLATILE_P (op0)))
     {
       if (code == EQ || code == NE)
 	{

	Jakub



More information about the Gcc-patches mailing list