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]

Re: cc1 SEGV (2.94.17 19990411 - current cvs)


On Sun, Apr 11, 1999 at 11:26:17PM +0300, Matti Aarnio wrote:
> Program received signal SIGSEGV, Segmentation fault.
> find_replacement (loc=0x8) at ../../gcc/reload.c:5853
> 5853      if (GET_CODE (*loc) == PLUS || GET_CODE (*loc) == MINUS
> (gdb) where
> #0  find_replacement (loc=0x8) at ../../gcc/reload.c:5853
> #1  0x1201b00e4 in get_unaligned_address (ref=0x8, extra_offset=0) at ...

Out of range stack slots suck.  Dynamically allocate

  u_char answer[32*1024];

and you'll get much better code.  Not that you really care for
something like dig...

Anyway, this should fix the segv. 


r~

PS: Thanks, Kenner, for the little "this is rare so we won't handle it"
comment.  That makes me feel all warm and fuzzy.


        * alpha.c (aligned_memory_operand): Handle out of range stack slots.
        Take a new SCRATCH argument for the occasion.  Update all callers.
        (get_unaligned_address): Abort on out of range stack slots.
        * alpha.md (adddi3 splitter): Check s_p_rtx not REGNO.
        (reload_inqi): Check for aligned mems before unaligned.
        (reload_inhi): Likewise.

Index: alpha.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/alpha/alpha.c,v
retrieving revision 1.76
diff -c -p -d -r1.76 alpha.c
*** alpha.c	1999/04/07 03:19:35	1.76
--- alpha.c	1999/04/12 10:06:40
*************** divmod_operator (op, mode)
*** 728,738 ****
     a constant.  It must be a valid address.  This means that we can do
     this as an aligned reference plus some offset.
  
!    Take into account what reload will do.
! 
!    We could say that out-of-range stack slots are alignable, but that would
!    complicate get_aligned_mem and it isn't worth the trouble since few
!    functions have large stack space.  */
  
  int
  aligned_memory_operand (op, mode)
--- 728,734 ----
     a constant.  It must be a valid address.  This means that we can do
     this as an aligned reference plus some offset.
  
!    Take into account what reload will do.  */
  
  int
  aligned_memory_operand (op, mode)
*************** aligned_memory_operand (op, mode)
*** 747,757 ****
        mode = GET_MODE (op);
      }
  
!   if (reload_in_progress && GET_CODE (op) == REG
!       && REGNO (op) >= FIRST_PSEUDO_REGISTER)
!     op = reg_equiv_mem[REGNO (op)];
  
!   if (GET_CODE (op) != MEM || GET_MODE (op) != mode
        || ! memory_address_p (mode, XEXP (op, 0)))
      return 0;
  
--- 743,760 ----
        mode = GET_MODE (op);
      }
  
!   if (reload_in_progress)
!     {
!       /* This is a stack slot.  The stack pointer is always aligned.
! 	 We may have to jump through hoops to get a valid address,
! 	 but we can do it.  */
!       if (GET_CODE (op) == REG
!           && REGNO (op) >= FIRST_PSEUDO_REGISTER)
! 	return 1;
!     }
  
!   if (GET_CODE (op) != MEM
!       || GET_MODE (op) != mode
        || ! memory_address_p (mode, XEXP (op, 0)))
      return 0;
  
*************** direct_return ()
*** 899,909 ****
  
  /* REF is an alignable memory location.  Place an aligned SImode
     reference into *PALIGNED_MEM and the number of bits to shift into
!    *PBITNUM.  */
  
  void
! get_aligned_mem (ref, paligned_mem, pbitnum)
!      rtx ref;
       rtx *paligned_mem, *pbitnum;
  {
    rtx base;
--- 902,913 ----
  
  /* REF is an alignable memory location.  Place an aligned SImode
     reference into *PALIGNED_MEM and the number of bits to shift into
!    *PBITNUM.  SCRATCH is a free register for use in reloading out
!    of range stack slots.  */
  
  void
! get_aligned_mem (ref, scratch, paligned_mem, pbitnum)
!      rtx ref, scratch;
       rtx *paligned_mem, *pbitnum;
  {
    rtx base;
*************** get_aligned_mem (ref, paligned_mem, pbit
*** 919,931 ****
        ref = SUBREG_REG (ref);
      }
  
-   if (GET_CODE (ref) == REG)
-     ref = reg_equiv_mem[REGNO (ref)];
- 
    if (reload_in_progress)
!     base = find_replacement (&XEXP (ref, 0));
    else
!     base = XEXP (ref, 0);
  
    if (GET_CODE (base) == PLUS)
      offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
--- 923,970 ----
        ref = SUBREG_REG (ref);
      }
  
    if (reload_in_progress)
!     {
!       if (GET_CODE (ref) == REG)
! 	{
! 	  /* The "simple" case is where the stack slot is in range.  */
! 	  if (reg_equiv_mem[REGNO (ref)])
! 	    {
! 	      ref = reg_equiv_mem[REGNO (ref)];
! 	      base = find_replacement (&XEXP (ref, 0));
! 	    }
! 	  else
! 	    {
! 	      /* The stack slot isn't in range.  Fix it up as needed.  */
! 	      HOST_WIDE_INT hi, lo;
! 
! 	      base = reg_equiv_address[REGNO (ref)];
! 	      if (GET_CODE (base) != PLUS)
! 		abort ();
! 	      offset += INTVAL (XEXP (base, 1));
! 	      base = XEXP (base, 0);
! 
! 	      lo = ((offset & 0xFFFF) ^ 0x8000) - 0x8000;
! 	      hi = (((offset - lo) & 0xFFFFFFFF) ^ 0x80000000) - 0x80000000;
! 	      if (hi + lo != offset)
! 		abort ();
! 	      if (scratch == NULL)
! 		abort ();
! 
! 	      emit_insn (gen_adddi3 (scratch, base, GEN_INT (hi)));
! 	      base = scratch;
! 	      offset = lo;
! 	    }
! 	}
!       else
! 	base = find_replacement (&XEXP (ref, 0));
!     }
    else
!     {
!       if (GET_CODE (ref) != MEM)
! 	abort ();
!       base = XEXP (ref, 0);
!     }
  
    if (GET_CODE (base) == PLUS)
      offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
*************** get_unaligned_address (ref, extra_offset
*** 962,974 ****
        ref = SUBREG_REG (ref);
      }
  
-   if (GET_CODE (ref) == REG)
-     ref = reg_equiv_mem[REGNO (ref)];
- 
    if (reload_in_progress)
!     base = find_replacement (&XEXP (ref, 0));
    else
!     base = XEXP (ref, 0);
  
    if (GET_CODE (base) == PLUS)
      offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
--- 1001,1027 ----
        ref = SUBREG_REG (ref);
      }
  
    if (reload_in_progress)
!     {
!       if (GET_CODE (ref) == REG)
! 	{
! 	  if (reg_equiv_mem[REGNO (ref)])
!             ref = reg_equiv_mem[REGNO (ref)];
! 	  else
! 	    {
! 	      /* The stack slot is out of range.  We should have handled
! 		 this as an aligned access -- I wonder why we didn't? */
! 	      abort ();
! 	    }
! 	}
!       base = find_replacement (&XEXP (ref, 0));
!     }
    else
!     {
!       if (GET_CODE (ref) != MEM)
! 	abort ();
!       base = XEXP (ref, 0);
!     }
  
    if (GET_CODE (base) == PLUS)
      offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
Index: alpha.md
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/alpha/alpha.md,v
retrieving revision 1.71
diff -c -p -d -r1.71 alpha.md
*** alpha.md	1999/04/07 03:18:52	1.71
--- alpha.md	1999/04/12 10:06:40
***************
*** 547,553 ****
  	(plus:DI (match_operand:DI 1 "register_operand" "")
  		 (match_operand:DI 2 "const_int_operand" "")))]
    "! add_operand (operands[2], DImode)
!    && REGNO (operands[0]) != STACK_POINTER_REGNUM"
    [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
     (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
    "
--- 547,553 ----
  	(plus:DI (match_operand:DI 1 "register_operand" "")
  		 (match_operand:DI 2 "const_int_operand" "")))]
    "! add_operand (operands[2], DImode)
!    && operands[0] != stack_pointer_rtx"
    [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
     (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
    "
***************
*** 4521,4527 ****
  			 ? gen_rtx_REG (SImode, REGNO (operands[0]))
  			 : gen_reg_rtx (SImode));
  
! 	  get_aligned_mem (operands[1], &aligned_mem, &bitnum);
  
  	  emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
  					 scratch));
--- 4521,4527 ----
  			 ? gen_rtx_REG (SImode, REGNO (operands[0]))
  			 : gen_reg_rtx (SImode));
  
! 	  get_aligned_mem (operands[1], scratch, &aligned_mem, &bitnum);
  
  	  emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
  					 scratch));
***************
*** 4561,4567 ****
  	  rtx temp1 = gen_reg_rtx (SImode);
  	  rtx temp2 = gen_reg_rtx (SImode);
  
! 	  get_aligned_mem (operands[0], &aligned_mem, &bitnum);
  
  	  emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
  					temp1, temp2));
--- 4561,4567 ----
  	  rtx temp1 = gen_reg_rtx (SImode);
  	  rtx temp2 = gen_reg_rtx (SImode);
  
! 	  get_aligned_mem (operands[0], NULL_RTX, &aligned_mem, &bitnum);
  
  	  emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
  					temp1, temp2));
***************
*** 4632,4638 ****
  			 ? gen_rtx_REG (SImode, REGNO (operands[0]))
  			 : gen_reg_rtx (SImode));
  
! 	  get_aligned_mem (operands[1], &aligned_mem, &bitnum);
  
  	  emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
  					 scratch));
--- 4632,4638 ----
  			 ? gen_rtx_REG (SImode, REGNO (operands[0]))
  			 : gen_reg_rtx (SImode));
  
! 	  get_aligned_mem (operands[1], scratch, &aligned_mem, &bitnum);
  
  	  emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
  					 scratch));
***************
*** 4672,4678 ****
  	  rtx temp1 = gen_reg_rtx (SImode);
  	  rtx temp2 = gen_reg_rtx (SImode);
  
! 	  get_aligned_mem (operands[0], &aligned_mem, &bitnum);
  
  	  emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
  					temp1, temp2));
--- 4672,4678 ----
  	  rtx temp1 = gen_reg_rtx (SImode);
  	  rtx temp2 = gen_reg_rtx (SImode);
  
! 	  get_aligned_mem (operands[0], NULL_RTX, &aligned_mem, &bitnum);
  
  	  emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
  					temp1, temp2));
***************
*** 4706,4723 ****
    "! TARGET_BWX"
    "
  {
!   rtx addr = get_unaligned_address (operands[1], 0);
  
!   /* It is possible that one of the registers we got for operands[2]
!      might coincide with that of operands[0] (which is why we made
!      it TImode).  Pick the other one to use as our scratch.  */
!   rtx scratch = gen_rtx_REG (DImode,
! 			     REGNO (operands[0]) == REGNO (operands[2]) 
! 			     ? REGNO (operands[2]) + 1 : REGNO (operands[2]));
  
!   rtx seq = gen_unaligned_loadqi (operands[0], addr, scratch,
! 				  gen_rtx_REG (DImode, REGNO (operands[0])));
  
    alpha_set_memflags (seq, operands[1]);
    emit_insn (seq);
    DONE;
--- 4706,4739 ----
    "! TARGET_BWX"
    "
  {
!   rtx scratch, seq;
  
!   if (aligned_memory_operand (operands[1], QImode))
!     {
!       rtx aligned_mem, bitnum;
  
!       get_aligned_mem (operands[1],
! 		       gen_rtx_REG (DImode, REGNO (operands[2]) + 1),
! 		       &aligned_mem, &bitnum);
!       seq = gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
! 				gen_rtx_REG (SImode, REGNO (operands[2])));
!     }
!   else
!     {
!       rtx addr;
  
+       /* It is possible that one of the registers we got for operands[2]
+          might coincide with that of operands[0] (which is why we made
+          it TImode).  Pick the other one to use as our scratch.  */
+       if (REGNO (operands[0]) == REGNO (operands[2]))
+ 	scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
+       else
+ 	scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
+ 
+       addr = get_unaligned_address (operands[1], 0);
+       seq = gen_unaligned_loadqi (operands[0], addr, scratch,
+ 				  gen_rtx_REG (DImode, REGNO (operands[0])));
+     }
    alpha_set_memflags (seq, operands[1]);
    emit_insn (seq);
    DONE;
***************
*** 4725,4747 ****
  
  (define_expand "reload_inhi"
    [(parallel [(match_operand:HI 0 "register_operand" "=r")
! 	      (match_operand:HI 1 "unaligned_memory_operand" "m")
  	      (match_operand:TI 2 "register_operand" "=&r")])]
    "! TARGET_BWX"
    "
  {
!   rtx addr = get_unaligned_address (operands[1], 0);
  
!   /* It is possible that one of the registers we got for operands[2]
!      might coincide with that of operands[0] (which is why we made
!      it TImode).  Pick the other one to use as our scratch.  */
!   rtx scratch = gen_rtx_REG (DImode,
! 			     REGNO (operands[0]) == REGNO (operands[2]) 
! 			     ? REGNO (operands[2]) + 1 : REGNO (operands[2]));
  
!   rtx seq = gen_unaligned_loadhi (operands[0], addr, scratch,
! 				  gen_rtx_REG (DImode, REGNO (operands[0])));
  
    alpha_set_memflags (seq, operands[1]);
    emit_insn (seq);
    DONE;
--- 4741,4779 ----
  
  (define_expand "reload_inhi"
    [(parallel [(match_operand:HI 0 "register_operand" "=r")
! 	      (match_operand:HI 1 "any_memory_operand" "m")
  	      (match_operand:TI 2 "register_operand" "=&r")])]
    "! TARGET_BWX"
    "
  {
!   rtx scratch, seq;
  
!   if (aligned_memory_operand (operands[1], HImode))
!     {
!       rtx aligned_mem, bitnum;
  
!       get_aligned_mem (operands[1],
! 		       gen_rtx_REG (DImode, REGNO (operands[2]) + 1),
! 		       &aligned_mem, &bitnum);
!       seq = gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
! 				gen_rtx_REG (SImode, REGNO (operands[2])));
!     }
!   else
!     {
!       rtx addr;
  
+       /* It is possible that one of the registers we got for operands[2]
+          might coincide with that of operands[0] (which is why we made
+          it TImode).  Pick the other one to use as our scratch.  */
+       if (REGNO (operands[0]) == REGNO (operands[2]))
+ 	scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
+       else
+ 	scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
+ 
+       addr = get_unaligned_address (operands[1], 0);
+       seq = gen_unaligned_loadhi (operands[0], addr, scratch,
+ 				  gen_rtx_REG (DImode, REGNO (operands[0])));
+     }
    alpha_set_memflags (seq, operands[1]);
    emit_insn (seq);
    DONE;
***************
*** 4758,4764 ****
      {
        rtx aligned_mem, bitnum;
  
!       get_aligned_mem (operands[0], &aligned_mem, &bitnum);
  
        emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
  				    gen_rtx_REG (SImode, REGNO (operands[2])),
--- 4790,4796 ----
      {
        rtx aligned_mem, bitnum;
  
!       get_aligned_mem (operands[0], NULL_RTX, &aligned_mem, &bitnum);
  
        emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
  				    gen_rtx_REG (SImode, REGNO (operands[2])),
***************
*** 4796,4802 ****
      {
        rtx aligned_mem, bitnum;
  
!       get_aligned_mem (operands[0], &aligned_mem, &bitnum);
  
        emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
  				    gen_rtx_REG (SImode, REGNO (operands[2])),
--- 4828,4834 ----
      {
        rtx aligned_mem, bitnum;
  
!       get_aligned_mem (operands[0], NULL_RTX, &aligned_mem, &bitnum);
  
        emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
  				    gen_rtx_REG (SImode, REGNO (operands[2])),


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