This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
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);
}