This is the mail archive of the gcc@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]

Re: [RFA] dwarf2out.c:eliminate_regs() bug


Richard Guenther wrote:
On Sun, Sep 20, 2009 at 9:38 AM, Maxim Kuvyrkov <maxim@codesourcery.com> wrote:
...
This code uses eliminate_regs(), which implicitly assumes reload_completed
as it uses reg_eliminate[], which assumes that frame_pointer_needed is
properly set, which happens in ira.c.  However, in some cases this piece of
based_loc_descr() can be reached during inlining pass (see backtrace below).
 When called before reload, eliminate_regs() may return an inconsistent
result which is why the assert in based_loc_descr() fails.  In the
particular testcase I'm investigating, frame_pointer_needed is 0 (initial
value), but eliminate_regs returns stack_pointer_rtx because it is guided by
reg_eliminate information from the previous function which had
frame_pointer_needed set to 1.
...
I think you should avoid calling eliminate_regs for DECL_ABSTRACT
current_function_decl.  That should cover the inliner path.

Thanks for the insight. Do you mean something like the attached patch?


--
Maxim
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	(revision 261914)
+++ gcc/dwarf2out.c	(working copy)
@@ -9862,8 +9862,11 @@ based_loc_descr (rtx reg, HOST_WIDE_INT 
   /* We only use "frame base" when we're sure we're talking about the
      post-prologue local stack frame.  We do this by *not* running
      register elimination until this point, and recognizing the special
-     argument pointer and soft frame pointer rtx's.  */
-  if (reg == arg_pointer_rtx || reg == frame_pointer_rtx)
+     argument pointer and soft frame pointer rtx's.
+     We might get here during the inlining pass (DECL_ABSTRACT is true then),
+     so don't try eliminating registers in such a case.  */
+  if (!DECL_ABSTRACT (current_function_decl)
+      && (reg == arg_pointer_rtx || reg == frame_pointer_rtx))
     {
       rtx elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
 
@@ -12224,6 +12227,9 @@ compute_frame_pointer_to_fb_displacement
   offset += ARG_POINTER_CFA_OFFSET (current_function_decl);
 #endif
 
+  /* Make sure we don't try eliminating registers in abstract function.  */
+  gcc_assert (!DECL_ABSTRACT (current_function_decl));
+
   elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
   if (GET_CODE (elim) == PLUS)
     {
Index: gcc/reload1.c
===================================================================
--- gcc/reload1.c	(revision 261914)
+++ gcc/reload1.c	(working copy)
@@ -2867,6 +2867,7 @@ eliminate_regs_1 (rtx x, enum machine_mo
 rtx
 eliminate_regs (rtx x, enum machine_mode mem_mode, rtx insn)
 {
+  gcc_assert (reload_in_progress || reload_completed);
   return eliminate_regs_1 (x, mem_mode, insn, false);
 }
 

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