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]

unsharing rtl too early


gcc.dg/980816-1.c fails on mn10300 apparently because we're unsharing
RTL too early.  Here's a simplified version of the testcase:

int foo(int a) {
  int w;
  return w/a;
}

% ./cc1 test.c
 foo
test.c: In function `foo':
test.c:4: Internal compiler error in `instantiate_virtual_regs_1', at function.c:3903

The insn on which this function crashes is:

(insn 11 8 13 (parallel[ 
            (set (reg:SI 24)
                (div:SI (mem/f:SI (plus:SI (reg:SI 19 virtual-stack-vars)
                            (const_int -4 [0xfffffffffffffffc])) 0)
                    (mem/f:SI (reg:SI 18 virtual-incoming-args) 0)))
            (set (reg:SI 25)
                (mod:SI (mem/f:SI (plus:SI (reg:SI 19 virtual-stack-vars)
                            (const_int -4 [0xfffffffffffffffc])) 0)
                    (mem/f:SI (reg:SI 18 virtual-incoming-args) 0)))
        ] ) -1 (nil)
    (nil))

The problem is that the first occurrence of (reg:SI 19) is shared with
the declaration of w, so it gets adjusted to use the frame pointer.
However, because instantiate_virtual_regs() is called after
unshare_all_rtl(), the second occurrence is no longer shared, so it's
not adjusted.  Then, when we try to instantiate (reg:SI 18), we fail,
because the insn doesn't match (the operands of the mod are dups of
those of the div).

The patch below fixes this problem.  Another solution would be to
arrange that unshare_all_rtl unshares declarations too, so that
instantiating them doesn't affect insns, or to instantiate
declarations only after instantiating insns.  I preferred to just move
unshare_all_rtl() after instantiate_all_regs(), that should even save
us from doing the work multiple times.  Ok to install?

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

	* toplev.c (rest_of_compilation): Unshare rtl after instantiating
	virtual registers.

Index: gcc/toplev.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.c,v
retrieving revision 1.338
diff -u -r1.338 toplev.c
--- gcc/toplev.c	2000/05/17 08:15:26	1.338
+++ gcc/toplev.c	2000/05/18 17:09:07
@@ -2807,17 +2807,18 @@
 
   insns = get_insns ();
 
-  /* Copy any shared structure that should not be shared.  */
-  unshare_all_rtl (current_function_decl, insns);
-
 #ifdef SETJMP_VIA_SAVE_AREA
-  /* This must be performed before virutal register instantiation.  */
+  /* This must be performed before virtual register instantiation.  */
   if (current_function_calls_alloca)
     optimize_save_area_alloca (insns);
 #endif
 
   /* Instantiate all virtual registers.  */
   instantiate_virtual_regs (current_function_decl, insns);
+
+  /* Copy any shared structure that should not be shared.  This must
+     be performed after virtual register instantiation.  */
+  unshare_all_rtl (current_function_decl, insns);
 
   /* Find all the EH handlers.  */
   find_exception_handler_labels ();

-- 
Alexandre Oliva    Enjoy Guaranį, see http://www.ic.unicamp.br/~oliva/
Cygnus Solutions, a Red Hat company        aoliva@{redhat, cygnus}.com
Free Software Developer and Evangelist    CS PhD student at IC-Unicamp
oliva@{lsd.ic.unicamp.br, gnu.org}   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]