Fix for 19990502-0.f

Jeffrey A Law law@cygnus.com
Thu Jun 17 01:54:00 GMT 1999


Rather than repeat all the analysis, I'll just refer you to one of the
messages with the analysis.  You can use the thread pointers to go back
and forth in the discussion.

http://egcs.cygnus.com/ml/egcs-bugs/1999-04/msg00082.html


This patch fixes this specific problem and a couple closely related problems.

	* emit-rtl.c (operand_subword): Tighten checks for when it is safe
	to safe to extract a subword out of a REG.

Index: emit-rtl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/emit-rtl.c,v
retrieving revision 1.59
diff -c -3 -p -r1.59 emit-rtl.c
*** emit-rtl.c	1999/04/29 23:01:26	1.59
--- emit-rtl.c	1999/06/17 08:45:40
*************** operand_subword (op, i, validate_address
*** 1196,1205 ****
    /* If OP is a REG or SUBREG, we can handle it very simply.  */
    if (GET_CODE (op) == REG)
      {
!       /* If the register is not valid for MODE, return 0.  If we don't
! 	 do this, there is no way to fix up the resulting REG later.  */
        if (REGNO (op) < FIRST_PSEUDO_REGISTER
! 	  && ! HARD_REGNO_MODE_OK (REGNO (op) + i, word_mode))
  	return 0;
        else if (REGNO (op) >= FIRST_PSEUDO_REGISTER
  	       || (REG_FUNCTION_VALUE_P (op)
--- 1196,1228 ----
    /* If OP is a REG or SUBREG, we can handle it very simply.  */
    if (GET_CODE (op) == REG)
      {
!       /* ??? There is a potential problem with this code.  It does not
! 	 properly handle extractions of a subword from a hard register
! 	 that is larger than word_mode.  Presumably the check for
! 	 HARD_REGNO_MODE_OK catches these most of these cases.  */
! 
!       /* If OP is a hard register, but OP + I is not a hard register,
! 	 then extracting a subword is impossible.
! 
! 	 For example, consider if OP is the last hard register and it is
! 	 larger than word_mode.  If we wanted word N (for N > 0) because a
! 	 part of that hard register was known to contain a useful value,
! 	 then OP + I would refer to a pseudo, not the hard register we
! 	 actually wanted.  */
        if (REGNO (op) < FIRST_PSEUDO_REGISTER
! 	  && REGNO (op) + i >= FIRST_PSEUDO_REGISTER)
! 	return 0;
! 
!       /* If the register is not valid for MODE, return 0.  Note we
! 	 have to check both OP and OP + I since they may refer to
! 	 different parts of the register file.
! 
! 	 Consider if OP refers to the last 96bit FP register and we want
! 	 subword 3 because that subword is known to contain a value we
! 	 needed.  */
!       if (REGNO (op) < FIRST_PSEUDO_REGISTER
! 	  && (! HARD_REGNO_MODE_OK (REGNO (op), word_mode)
! 	      || ! HARD_REGNO_MODE_OK (REGNO (op) + i, word_mode)))
  	return 0;
        else if (REGNO (op) >= FIRST_PSEUDO_REGISTER
  	       || (REG_FUNCTION_VALUE_P (op)




More information about the Gcc-patches mailing list