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]

Re: [testcase] CSE bug


On Jul 23, 2001, Richard Henderson <rth@redhat.com> wrote:

> On Mon, Jul 23, 2001 at 04:35:59PM +0200, Jakub Jelinek wrote:

>> But remove_invalid_subreg_refs(60,0,SImode) invalidates only
>> (subreg:SI (reg:DI 60) 0),
>> (which in fact was not needed if invalidate_skipped_block recorded somewhere
>> that only part of the register needs to be invalidated and which one) and
>> from this point on, (subreg:SI (reg:DI 60) 4) is handled like if nobody
>> would ever touch it.
>> Any ideas what's the right way to fix this?

> Alex, didn't you have a patch that touched on this sort
> of thing?  Did it ever get reviewed?

Yeah, the description sounds somewhat similar, but there a number of
function names that don't ring any bells right now.  The problem
originally showed up on mn10300-elf, with a C++ test case, IIRC.

I got some feedback, but never an official approval or rejection.
Here's the patch file, created on Nov 18, 2000:

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* cse.c (invalidate) [REG]: Invalidate all SUBREGs of the REG.
	(lookup_for_remove): Handle SUBREGs.

Index: gcc/cse.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cse.c,v
retrieving revision 1.164
diff -u -p -r1.164 cse.c
--- gcc/cse.c 2000/11/07 22:49:51 1.164
+++ gcc/cse.c 2000/11/18 22:27:04
@@ -1481,6 +1481,17 @@ lookup_for_remove (x, hash, mode)
 	    && REGNO (p->exp) == regno)
 	  return p;
     }
+  else if (GET_CODE (x) == SUBREG && GET_CODE (SUBREG_REG (x)) == REG)
+    {
+      unsigned int regno = REGNO (SUBREG_REG (x));
+
+      /* Don't check the machine mode when comparing SUBREGs.  */
+      for (p = table[hash]; p; p = p->next_same_hash)
+	if (GET_CODE (p->exp) == SUBREG
+	    && GET_CODE (SUBREG_REG (p->exp)) == REG
+	    && REGNO (SUBREG_REG (p->exp)) == regno)
+	  return p;
+    }
   else
     {
       for (p = table[hash]; p; p = p->next_same_hash)
@@ -1880,9 +1891,21 @@ invalidate (x, full_mode)
 	    /* Because a register can be referenced in more than one mode,
 	       we might have to remove more than one table entry.  */
 	    struct table_elt *elt;
+	    int i;
 
 	    while ((elt = lookup_for_remove (x, hash, GET_MODE (x))))
 	      remove_from_table (elt, hash);
+
+	    /* Since multi-word PSEUDOS may also be referenced through
+	       SUBREGs, we attempt to remove such subregs too.  */
+	    for (i = 0; i * UNITS_PER_WORD < GET_MODE_SIZE (GET_MODE (x)); i++)
+	      {
+		rtx subreg = gen_rtx_SUBREG (VOIDmode, x, i);
+		unsigned hash = HASH (subreg, VOIDmode);
+
+		while ((elt = lookup_for_remove (subreg, hash, VOIDmode)))
+		  remove_from_table (elt, hash);
+	      }
 	  }
 	else
 	  {
Index: gcc/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* gcc.c-torture/execute/20001118-1.c: New test.

Index: gcc/testsuite/gcc.c-torture/execute/20001118-1.c
===================================================================
RCS file: 20001118-1.c
diff -N 20001118-1.c
--- /dev/null	Tue May  5 13:32:27 1998
+++ gcc/testsuite/gcc.c-torture/execute/20001118-1.c Sat Nov 18 14:27:06 2000
@@ -0,0 +1,32 @@
+/* Copyright 2000 Free Software Foundation
+   Origin: Jason Merrill <jason@redhat.com>.  */
+
+union foo {
+  void (*pfn)();
+  short delta2;
+};
+
+struct pmf {
+  short delta;
+  short index;
+  union foo u;
+};
+
+void f () { }
+
+int main ()
+{
+  struct pmf pf = { 0, -1, { &f } };
+
+  struct pmf pg = (pf.index > 0
+		   ? (struct pmf){ pf.delta, pf.index,{ delta2: pf.u.delta2 }}
+		   : (struct pmf){ pf.delta, pf.index,{ pfn: pf.u.pfn }});
+
+  pf = (pg.index > 0
+	? (struct pmf){ pg.delta, pg.index,{ delta2: pg.u.delta2 }}
+	: (struct pmf){ pg.delta, pg.index,{ pfn: pg.u.pfn }});
+
+  if (pf.u.pfn != &f)
+    abort ();
+  exit (0);
+}

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                  aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist    *Please* write to mailing lists, not to me

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