This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: cc1 SEGV (2.94.17 19990411 - current cvs)
- To: Matti Aarnio <matti dot aarnio at sonera dot fi>, egcs-bugs at egcs dot cygnus dot com
- Subject: Re: cc1 SEGV (2.94.17 19990411 - current cvs)
- From: Richard Henderson <rth at cygnus dot com>
- Date: Mon, 12 Apr 1999 03:21:01 -0700
- Cc: egcs-patches at egcs dot cygnus dot com
- References: <19990411202632Z92324-10747+11@mea.tmt.tele.fi>
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])),