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

Re: Death of stupid causes death of IRIX?


On Mon, Jan 24, 2000 at 11:41:05PM -0800, Mark Mitchell wrote:
> The bug appears to be that somehow a structure return value is
> being clobbered in some way before it reaches the caller...

Try this.  The bootstrap hasn't finished yet here, and I'm off to bed.

The problem was that FUNCTION_OUTGOING_VALUE was giving us a BLKmode
register instead of a TImode register.  Why we weren't aborting, I'm
not sure.  Anyway, it resulted in too few registers being kept live
at the end of the function. 

I can't think of why this wouldn't have shown up at -O1 before now.
By rights it should have started failing here:

  Sat Oct  9 12:18:16 1999  Richard Henderson  <rth@cygnus.com>



r~


	* Makefile.in (flow.o): Depend on $(EXPR_H).
	* flow.c (mark_regs_live_at_end): Use hard_function_value, i.e.
	duplicate the structure of diddle_return_value for keeping regs live.

Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Makefile.in,v
retrieving revision 1.371
diff -c -p -d -r1.371 Makefile.in
*** Makefile.in	2000/01/25 05:59:17	1.371
--- Makefile.in	2000/01/25 13:31:28
*************** unroll.o : unroll.c $(CONFIG_H) system.h
*** 1571,1577 ****
     varray.h 
  flow.o : flow.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h insn-config.h \
     $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
!    insn-flags.h function.h except.h
  combine.o : combine.c $(CONFIG_H) system.h $(RTL_H) flags.h function.h \
     insn-config.h insn-flags.h insn-codes.h insn-attr.h $(REGS_H) $(EXPR_H) \
     $(BASIC_BLOCK_H) $(RECOG_H) real.h hard-reg-set.h toplev.h
--- 1571,1577 ----
     varray.h 
  flow.o : flow.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h insn-config.h \
     $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
!    insn-flags.h function.h except.h $(EXPR_H)
  combine.o : combine.c $(CONFIG_H) system.h $(RTL_H) flags.h function.h \
     insn-config.h insn-flags.h insn-codes.h insn-attr.h $(REGS_H) $(EXPR_H) \
     $(BASIC_BLOCK_H) $(RECOG_H) real.h hard-reg-set.h toplev.h
Index: flow.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/flow.c,v
retrieving revision 1.208
diff -c -p -d -r1.208 flow.c
*** flow.c	2000/01/23 23:10:09	1.208
--- flow.c	2000/01/25 13:31:28
*************** Boston, MA 02111-1307, USA.  */
*** 133,138 ****
--- 133,139 ----
  #include "except.h"
  #include "toplev.h"
  #include "recog.h"
+ #include "expr.h"
  #include "insn-flags.h"
  
  #include "obstack.h"
*************** static void
*** 2782,2788 ****
  mark_regs_live_at_end (set)
       regset set;
  {
!   tree type;
    int i;
  
    /* If exiting needs the right stack value, consider the stack pointer
--- 2783,2790 ----
  mark_regs_live_at_end (set)
       regset set;
  {
!   tree return_decl, return_type;
!   rtx return_reg;
    int i;
  
    /* If exiting needs the right stack value, consider the stack pointer
*************** mark_regs_live_at_end (set)
*** 2841,2880 ****
  
    /* Mark function return value.  */
  
!   type = TREE_TYPE (DECL_RESULT (current_function_decl));
!   if (type != void_type_node)
      {
!       rtx outgoing;
! 
!       if (current_function_returns_struct
! 	  || current_function_returns_pcc_struct)
! 	type = build_pointer_type (type);
! 
! #ifdef FUNCTION_OUTGOING_VALUE
!       outgoing = FUNCTION_OUTGOING_VALUE (type, current_function_decl);
! #else
!       outgoing = FUNCTION_VALUE (type, current_function_decl);
! #endif
! 
!       if (GET_CODE (outgoing) == REG)
! 	mark_reg (set, outgoing);
!       else if (GET_CODE (outgoing) == PARALLEL)
  	{
! 	  int len = XVECLEN (outgoing, 0);
  
  	  /* Check for a NULL entry, used to indicate that the parameter
  	     goes on the stack and in registers.  */
! 	  i = (XEXP (XVECEXP (outgoing, 0, 0), 0) ? 0 : 1);
  
  	  for ( ; i < len; ++i)
  	    {
! 	      rtx r = XVECEXP (outgoing, 0, i);
  	      if (GET_CODE (r) == REG)
  		mark_reg (set, r);
  	    }
  	}
-       else
- 	abort ();
      }
  }
  
--- 2843,2876 ----
  
    /* Mark function return value.  */
  
!   return_decl = DECL_RESULT (current_function_decl);
!   return_type = TREE_TYPE (return_decl);
!   return_reg = DECL_RTL (return_decl);
!   if (return_reg)
      {
!       if (GET_CODE (return_reg) == REG
! 	  && REGNO (return_reg) < FIRST_PSEUDO_REGISTER)
  	{
! 	  /* Use hard_function_value to avoid examining a BLKmode register.  */
! 	  return_reg
! 	    = hard_function_value (return_type, current_function_decl, 1);
! 	  mark_reg (set, return_reg);
! 	}
!       else if (GET_CODE (return_reg) == PARALLEL)
! 	{
! 	  int len = XVECLEN (return_reg, 0);
  
  	  /* Check for a NULL entry, used to indicate that the parameter
  	     goes on the stack and in registers.  */
! 	  i = (XEXP (XVECEXP (return_reg, 0, 0), 0) ? 0 : 1);
  
  	  for ( ; i < len; ++i)
  	    {
! 	      rtx r = XVECEXP (return_reg, 0, i);
  	      if (GET_CODE (r) == REG)
  		mark_reg (set, r);
  	    }
  	}
      }
  }
  

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