PATCH: if -fpic then don't consider PIC_OFFSET_TABLE_REGNUM updates dead

Toshi Morita tm2@best.com
Thu Mar 15 02:19:00 GMT 2001


This patch fixes the bug I posted earlier to gcc-bugs,

GCC for target sh-elf is aborting when compiling rengine.i from stress-1.17
with the options: -O2 -m4-single-only -ml -fpic.

Basically, propogate_one_insn is called with this rtx:

(insn 69 68 71 (set (reg:SI 12 r12)
        (plus:SI (reg:SI 12 r12)
            (reg:SI 0 r0))) -1 (nil)
    (nil))

control enters this code:

  if (flags & PROP_SCAN_DEAD_CODE)
    {
      insn_is_dead = insn_dead_p (pbi, PATTERN (insn), 0, REG_NOTES (insn));
      libcall_is_dead = (insn_is_dead && note != 0
                         && libcall_dead_p (pbi, note, insn));
    }

  /* If an instruction consists of just dead store(s) on final pass,
     delete it.  */
  if ((flags & PROP_KILL_DEAD_CODE) && insn_is_dead)
    {
      /* If we're trying to delete a prologue or epilogue instruction
         that isn't flagged as possibly being dead, something is wrong.
         But if we are keeping the stack pointer depressed, we might well
         be deleting insns that are used to compute the amount to update
         it by, so they are fine.  */
      if (reload_completed
          && !(TREE_CODE (TREE_TYPE (current_function_decl)) == FUNCTION_TYPE
                && (TYPE_RETURNS_STACK_DEPRESSED
                    (TREE_TYPE (current_function_decl))))
          && (((HAVE_epilogue || HAVE_prologue)
               && prologue_epilogue_contains (insn))
              || (HAVE_sibcall_epilogue
                  && sibcall_epilogue_contains (insn)))
          && find_reg_note (insn, REG_MAYBE_DEAD, NULL_RTX) == 0)
        abort ();

so basically, insn_dead_p returns true for this rtx, then the "If we're trying to delete
a prologue or epilogue instruction..." code is executed, and it's determined
the insns is in either the prologue or epilogue and has no REG_MAYBE_DEAD note, so
the abort is called.

The problem appears to be in insn_dead_p.

This insn is in the prologue/epilogue because r12 is the PIC_OFFSET_TABLE_REGNUM,
If -fpic is specified, then updates to the PIC_OFFSET_TABLE_REGNUM should never
be considered dead.

(It's very bizarre that nobody has ever noticed this problem in all the years that
 GCC has supported PIC...)

Here's a patch (successfully bootstrapped on i686-linux):

Thu Mar 15 02:18:26 PST 2001  Toshiyasu Morita  (toshiyasu.morita@hsa.hitachi.com)

	* flow.c (insn_dead_p): Sets of PIC_OFFSET_TABLE_REGNUM are always live if
	flag_pic is set.

*** flow.c.bak	Thu Mar 15 17:01:53 2001
--- flow.c	Thu Mar 15 17:18:24 2001
***************
*** 4477,4482 ****
--- 4477,4488 ----
  	      if (regno == STACK_POINTER_REGNUM)
  		return 0;
  
+ #ifdef PIC_OFFSET_TABLE_REGNUM 
+               /* Make sure insns to set the PIC offset table register aren't deleted.  */
+               if (flag_pic && regno == PIC_OFFSET_TABLE_REGNUM)
+                 return 0;
+ #endif
+ 
  	      /* ??? These bits might be redundant with the force live bits
  		 in calculate_global_regs_live.  We would delete from
  		 sequential sets; whether this actually affects real code

With this patch, the file compiles succesfully.

Also, it would be greatly appreciated if someone would peruse my previous two patches:

http://gcc.gnu.org/ml/gcc-patches/2001-03/msg00624.html
http://gcc.gnu.org/ml/gcc-patches/2001-03/msg00374.html

Toshi



More information about the Gcc-patches mailing list