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]

Re: More bug in reload_reg_free_for_value_p in reload1.c


> Hi,
> 
> There is another bug in reload_reg_free_for_value_p in reload1.c. The
> result is manager.c in linuxthreads is miscompiled on x86. I am
> enclosing 3 files here. manager1.c, ok.S and bad.S. bad.S is compiled
> from manager1.c with -fPIC -march=pentium -mcpu=pentium -S -O and ok.S
> is bad.S plus a fix by hand.
> 
> If I backed out the reload_reg_free_for_value_p change, manager1.c is
> compiled fine.

Thanks.

I have appended a patch.  Does this fix your problem?

Jim, Jeff, can this go in?

Tue Jun  2 20:51:57 1998  J"orn Rennecke <amylaar@cygnus.co.uk>

	* reload1.c (reload_reg_free_for_value_p): New arguments out and
	reloadnum.  Changed all callers.

Index: reload1.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/reload1.c,v
retrieving revision 1.33
diff -p -r1.33 reload1.c
*** reload1.c	1998/05/21 11:52:31	1.33
--- reload1.c	1998/06/02 19:52:12
*************** static void clear_reload_reg_in_use	PROT
*** 378,384 ****
  					       enum machine_mode));
  static int reload_reg_free_p		PROTO((int, int, enum reload_type));
  static int reload_reg_free_before_p	PROTO((int, int, enum reload_type));
! static int reload_reg_free_for_value_p	PROTO((int, int, enum reload_type, rtx));
  static int reload_reg_reaches_end_p	PROTO((int, int, enum reload_type));
  static int allocate_reload_reg		PROTO((int, rtx, int, int));
  static void choose_reload_regs		PROTO((rtx, rtx));
--- 378,384 ----
  					       enum machine_mode));
  static int reload_reg_free_p		PROTO((int, int, enum reload_type));
  static int reload_reg_free_before_p	PROTO((int, int, enum reload_type));
! static int reload_reg_free_for_value_p	PROTO((int, int, enum reload_type, rtx, rtx, int));
  static int reload_reg_reaches_end_p	PROTO((int, int, enum reload_type));
  static int allocate_reload_reg		PROTO((int, rtx, int, int));
  static void choose_reload_regs		PROTO((rtx, rtx));
*************** int reload_spill_index[MAX_RELOADS];
*** 4983,4997 ****
  /* Return 1 if the value in reload reg REGNO, as used by a reload
     needed for the part of the insn specified by OPNUM and TYPE,
     may be used to load VALUE into it.
!    Other read-only reloads with the same value do not conflict.
     The caller has to make sure that there is no conflict with the return
     register.  */
  static int
! reload_reg_free_for_value_p (regno, opnum, type, value)
       int regno;
       int opnum;
       enum reload_type type;
!      rtx value;
  {
    int time1;
    int i;
--- 4983,5002 ----
  /* Return 1 if the value in reload reg REGNO, as used by a reload
     needed for the part of the insn specified by OPNUM and TYPE,
     may be used to load VALUE into it.
!    Other read-only reloads with the same value do not conflict,
!    unless OUT is non-zero and these other reloads have to life while
!    output reloads live.
!    RELOADNUM is the number of the reload we want to load this value for;
!    that reload does not conflict with itself.
     The caller has to make sure that there is no conflict with the return
     register.  */
  static int
! reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum)
       int regno;
       int opnum;
       enum reload_type type;
!      rtx value, out;
!      int reloadnum;
  {
    int time1;
    int i;
*************** reload_reg_free_for_value_p (regno, opnu
*** 5048,5086 ****
        if (reg && GET_CODE (reg) == REG
  	  && ((unsigned) regno - true_regnum (reg)
  	      <= HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg)) - 1U)
! 	  && (! reload_in[i] || ! rtx_equal_p (reload_in[i], value)
! 	      || reload_out[i]))
  	{
! 	  int time2;
! 	  switch (reload_when_needed[i])
  	    {
! 	    case RELOAD_FOR_OTHER_ADDRESS:
! 	      time2 = 0;
! 	      break;
! 	    case RELOAD_FOR_INPADDR_ADDRESS:
! 	      time2 = reload_opnum[i] * 4 + 1;
! 	      break;
! 	    case RELOAD_FOR_INPUT_ADDRESS:
! 	      time2 = reload_opnum[i] * 4 + 2;
! 	      break;
! 	    case RELOAD_FOR_INPUT:
! 	      time2 = reload_opnum[i] * 4 + 3;
! 	      break;
! 	    case RELOAD_FOR_OUTPUT:
! 	    /* All RELOAD_FOR_OUTPUT reloads become live just after the
! 	       instruction is executed.  */
! 	      time2 = MAX_RECOG_OPERANDS * 4;
! 	      break;
! 	    /* The first RELOAD_FOR_OUTPUT_ADDRESS reload conflicts with the
! 	       RELOAD_FOR_OUTPUT reloads, so assign it the same time value.  */
! 	    case RELOAD_FOR_OUTPUT_ADDRESS:
! 	      time2 = MAX_RECOG_OPERANDS * 4 + reload_opnum[i];
! 	      break;
! 	    default:
! 	      time2 = 0;
  	    }
- 	  if (time1 >= time2)
- 	    return 0;
  	}
      }
    return 1;
--- 5053,5105 ----
        if (reg && GET_CODE (reg) == REG
  	  && ((unsigned) regno - true_regnum (reg)
  	      <= HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg)) - 1U)
! 	  && i != reloadnum)
  	{
! 	  if (out
! 	      && reload_when_needed[i] != RELOAD_FOR_INPUT
! 	      && reload_when_needed[i] != RELOAD_FOR_INPUT_ADDRESS
! 	      && reload_when_needed[i] != RELOAD_FOR_INPADDR_ADDRESS)
! 	    return 0;
! 	  if (! reload_in[i] || ! rtx_equal_p (reload_in[i], value)
! 	      || reload_out[i])
  	    {
! 	      int time2;
! 	      switch (reload_when_needed[i])
! 		{
! 		case RELOAD_FOR_OTHER_ADDRESS:
! 		  time2 = 0;
! 		  break;
! 		case RELOAD_FOR_INPADDR_ADDRESS:
! 		  time2 = reload_opnum[i] * 4 + 1;
! 		  break;
! 		case RELOAD_FOR_INPUT_ADDRESS:
! 		  time2 = reload_opnum[i] * 4 + 2;
! 		  break;
! 		case RELOAD_FOR_INPUT:
! 		  time2 = reload_opnum[i] * 4 + 3;
! 		  break;
! 		case RELOAD_FOR_OUTPUT:
! 		/* All RELOAD_FOR_OUTPUT reloads become live just after the
! 		   instruction is executed.  */
! 		  time2 = MAX_RECOG_OPERANDS * 4;
! 		  break;
! 		/* The first RELOAD_FOR_OUTPUT_ADDRESS reload conflicts with the
! 		   RELOAD_FOR_OUTPUT reloads, so assign it the same time value.  */
! 		case RELOAD_FOR_OUTPUT_ADDRESS:
! 		  time2 = MAX_RECOG_OPERANDS * 4 + reload_opnum[i];
! 		  break;
! 		case RELOAD_OTHER:
! 		  if (! reload_in[i] || rtx_equal_p (reload_in[i], value))
! 		    {
! 		      time2 = MAX_RECOG_OPERANDS * 4;
! 		      break;
! 		    }
! 		default:
! 		  time2 = 0;
! 		}
! 	      if (time1 >= time2)
! 		return 0;
  	    }
  	}
      }
    return 1;
*************** allocate_reload_reg (r, insn, last_reloa
*** 5160,5173 ****
  
  	  if ((reload_reg_free_p (spill_regs[i], reload_opnum[r],
  				  reload_when_needed[r])
! 	       || (reload_in[r] && ! reload_out[r]
  		      /* We check reload_reg_used to make sure we
  			 don't clobber the return register.  */
  		   && ! TEST_HARD_REG_BIT (reload_reg_used, spill_regs[i])
  		   && reload_reg_free_for_value_p (spill_regs[i],
  						  reload_opnum[r],
  						  reload_when_needed[r],
! 						  reload_in[r])))
  	      && TEST_HARD_REG_BIT (reg_class_contents[class], spill_regs[i])
  	      && HARD_REGNO_MODE_OK (spill_regs[i], reload_mode[r])
  	      /* Look first for regs to share, then for unshared.  But
--- 5179,5193 ----
  
  	  if ((reload_reg_free_p (spill_regs[i], reload_opnum[r],
  				  reload_when_needed[r])
! 	       || (reload_in[r]
  		      /* We check reload_reg_used to make sure we
  			 don't clobber the return register.  */
  		   && ! TEST_HARD_REG_BIT (reload_reg_used, spill_regs[i])
  		   && reload_reg_free_for_value_p (spill_regs[i],
  						  reload_opnum[r],
  						  reload_when_needed[r],
! 						  reload_in[r],
! 						  reload_out[r], r)))
  	      && TEST_HARD_REG_BIT (reg_class_contents[class], spill_regs[i])
  	      && HARD_REGNO_MODE_OK (spill_regs[i], reload_mode[r])
  	      /* Look first for regs to share, then for unshared.  But
*************** choose_reload_regs (insn, avoid_return_r
*** 5634,5640 ****
  							reload_when_needed[r]))
  			  || reload_reg_free_for_value_p (i, reload_opnum[r],
  							  reload_when_needed[r],
! 							  reload_in[r])))
  		    {
  		      /* If a group is needed, verify that all the subsequent
  			 registers still have their values intact.  */
--- 5654,5661 ----
  							reload_when_needed[r]))
  			  || reload_reg_free_for_value_p (i, reload_opnum[r],
  							  reload_when_needed[r],
! 							  reload_in[r],
! 							  reload_out[r], r)))
  		    {
  		      /* If a group is needed, verify that all the subsequent
  			 registers still have their values intact.  */
*************** choose_reload_regs (insn, avoid_return_r
*** 5741,5747 ****
  			     || reload_reg_free_for_value_p (regno,
  							     reload_opnum[r],
  							     reload_when_needed[r],
! 							     reload_in[r])))
  		      || ! TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[r]],
  					      regno)))
  		equiv = 0;
--- 5762,5769 ----
  			     || reload_reg_free_for_value_p (regno,
  							     reload_opnum[r],
  							     reload_when_needed[r],
! 							     reload_in[r],
! 							     reload_out[r], r)))
  		      || ! TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[r]],
  					      regno)))
  		equiv = 0;
*************** choose_reload_regs (insn, avoid_return_r
*** 5924,5930 ****
  		|| reload_reg_free_for_value_p (true_regnum (reload_reg_rtx[r]),
  						reload_opnum[r],
  						reload_when_needed[r],
! 						reload_in[r])))
  	reload_inherited[r] = 0;
        /* If we can inherit a RELOAD_FOR_INPUT, then we do not need its related
  	 RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_INPADDR_ADDRESS reloads.
--- 5946,5953 ----
  		|| reload_reg_free_for_value_p (true_regnum (reload_reg_rtx[r]),
  						reload_opnum[r],
  						reload_when_needed[r],
! 						reload_in[r],
! 						reload_out[r], r)))
  	reload_inherited[r] = 0;
        /* If we can inherit a RELOAD_FOR_INPUT, then we do not need its related
  	 RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_INPADDR_ADDRESS reloads.


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