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

cse bugfix



Franz Sirl did most of the grunt work for this bugfix.

Basically the ppc-linux port would sometimes create assembly code which
had label1-label2 expressions.  If label1 and label2 are in different
sections, then the assembler would choke.

The root cause of the problem was cse created a REG_EQUAL note of the
form (const (minus (label_ref) (label_ref))).  That REG_EQUAL note would
get promoted to a REG_EQUIV note by the register allocators.

That REG_EQUIV note was used as an equivalence by reload for a pseudo which
did not get a hard register.  Reload substituted the equivalent expression
for uses of the pseudo, which led to the bogus assembly code.

This patch fixes the problem by not allowing CSE to generate the bogus
REG_EQUIV note in the first place

Thanks Franz!

Sun Feb 28 00:50:28 1999  Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
                          Jeffrey A Law  (law@cygnus.com)

        * cse.c (fold_rtx): Update comments for (const (minus (label) (label)))
        case.
        (cse_insn): Avoid creating a bogus REG_EQUAL note for
        (const (minus (label) (label)))
        (record_jump_cond): Fix mismatched paren in comment.


Index: cse.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cse.c,v
retrieving revision 1.44.2.2
diff -c -3 -p -r1.44.2.2 cse.c
*** cse.c	1998/12/30 23:39:53	1.44.2.2
--- cse.c	1999/02/28 07:38:29
*************** fold_rtx (x, insn)
*** 5167,5173 ****
  		    /* Indicate this is a constant.  This isn't a 
  		       valid form of CONST, but it will only be used
  		       to fold the next insns and then discarded, so
! 		       it should be safe.  */
  		    return gen_rtx_CONST (GET_MODE (new), new);
  		  }
  	      }
--- 5167,5177 ----
  		    /* Indicate this is a constant.  This isn't a 
  		       valid form of CONST, but it will only be used
  		       to fold the next insns and then discarded, so
! 		       it should be safe.
! 
! 		       Note this expression must be explicitly discarded,
! 		       by cse_insn, else it may end up in a REG_EQUAL note
! 		       and "escape" to cause problems elsewhere.  */
  		    return gen_rtx_CONST (GET_MODE (new), new);
  		  }
  	      }
*************** record_jump_cond (code, mode, op0, op1, 
*** 5913,5919 ****
    /* If OP0 and OP1 are known equal, and either is a paradoxical SUBREG,
       we know that they are also equal in the smaller mode (this is also
       true for all smaller modes whether or not there is a SUBREG, but
!      is not worth testing for with no SUBREG.  */
  
    /* Note that GET_MODE (op0) may not equal MODE.  */
    if (code == EQ && GET_CODE (op0) == SUBREG
--- 5917,5923 ----
    /* If OP0 and OP1 are known equal, and either is a paradoxical SUBREG,
       we know that they are also equal in the smaller mode (this is also
       true for all smaller modes whether or not there is a SUBREG, but
!      is not worth testing for with no SUBREG).  */
  
    /* Note that GET_MODE (op0) may not equal MODE.  */
    if (code == EQ && GET_CODE (op0) == SUBREG
*************** cse_insn (insn, libcall_insn)
*** 7046,7054 ****
  	 equivalent constant, we want to add a REG_NOTE.   We don't want
  	 to write a REG_EQUAL note for a constant pseudo since verifying that
  	 that pseudo hasn't been eliminated is a pain.  Such a note also
! 	 won't help anything.  */
        if (n_sets == 1 && src_const && GET_CODE (dest) == REG
! 	  && GET_CODE (src_const) != REG)
  	{
  	  tem = find_reg_note (insn, REG_EQUAL, NULL_RTX);
  	  
--- 7050,7067 ----
  	 equivalent constant, we want to add a REG_NOTE.   We don't want
  	 to write a REG_EQUAL note for a constant pseudo since verifying that
  	 that pseudo hasn't been eliminated is a pain.  Such a note also
! 	 won't help anything. 
! 
! 	 Avoid a REG_EQUAL note for (CONST (MINUS (LABEL_REF) (LABEL_REF)))
! 	 which can be created for a reference to a compile time computable
! 	 entry in a jump table.  */
! 
        if (n_sets == 1 && src_const && GET_CODE (dest) == REG
! 	  && GET_CODE (src_const) != REG
! 	  && ! (GET_CODE (src_const) == CONST
! 		&& GET_CODE (XEXP (src_const, 0)) == MINUS
! 		&& GET_CODE (XEXP (XEXP (src_const, 0), 0)) == LABEL_REF
! 		&& GET_CODE (XEXP (XEXP (src_const, 0), 1)) == LABEL_REF))
  	{
  	  tem = find_reg_note (insn, REG_EQUAL, NULL_RTX);
  	  


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