IMO the test case is invalid, but as always an ICE is unacceptable.

I can imagine there are some legitimate uses for absconding with
the hard frame pointer, under -fomit-frame-pointer plus knowledge
that the code is simple enough.

Previously when we got into this situation, we'd silently smash the
hard frame pointer.  The user would find out the problem only through
testing.  But the dwarf2cfi pass has consistency checks that trigger.

This patch preserves the "simple enough" case while generating an
error early enough that the dwarf2cfi pass doesn't run.

Tested on i386 and ppc64.


r~
        * reginfo.c (global_regs_decl): Globalize.
        * rtl.h (global_regs_decl): Declare.
        * ira.c (do_reload): Diagnose frame_pointer_needed and it
        reserved via global_regs.


diff --git a/gcc/ira.c b/gcc/ira.c
index cebacf5..3409e4a 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -5530,6 +5530,18 @@ do_reload (void)
   if (need_dce && optimize)
     run_fast_dce ();
 
+  /* Diagnose uses of the hard frame pointer when it is used as a global
+     register.  Often we can get away with letting the user appropriate
+     the frame pointer, but we should let them know when code generation
+     makes that impossible.  */
+  if (global_regs[HARD_FRAME_POINTER_REGNUM] && frame_pointer_needed)
+    {
+      tree decl = global_regs_decl[HARD_FRAME_POINTER_REGNUM];
+      error_at (DECL_SOURCE_LOCATION (current_function_decl),
+                "frame pointer required, but reserved");
+      inform (DECL_SOURCE_LOCATION (decl), "for %qD", decl);
+    }
+
   timevar_pop (TV_IRA);
 }
 
diff --git a/gcc/reginfo.c b/gcc/reginfo.c
index efaa0cb..f3aaa61 100644
--- a/gcc/reginfo.c
+++ b/gcc/reginfo.c
@@ -86,7 +86,7 @@ static const char initial_call_really_used_regs[] = 
CALL_REALLY_USED_REGISTERS;
 char global_regs[FIRST_PSEUDO_REGISTER];
 
 /* Declaration for the global register. */
-static tree GTY(()) global_regs_decl[FIRST_PSEUDO_REGISTER];
+tree GTY(()) global_regs_decl[FIRST_PSEUDO_REGISTER];
 
 /* Same information as REGS_INVALIDATED_BY_CALL but in regset form to be used
    in dataflow more conveniently.  */
diff --git a/gcc/rtl.h b/gcc/rtl.h
index e7d60ee..10ee818 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2795,6 +2795,8 @@ extern void _fatal_insn (const char *, const_rtx, const 
char *, int, const char
 #define fatal_insn_not_found(insn) \
        _fatal_insn_not_found (insn, __FILE__, __LINE__, __FUNCTION__)
 
+/* reginfo.c */
+extern tree GTY(()) global_regs_decl[FIRST_PSEUDO_REGISTER];
 
 
 #endif /* ! GCC_RTL_H */

Reply via email to