This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: fix emit_move_insn_1
- To: gcc-patches at gcc dot gnu dot org
- Subject: PATCH: fix emit_move_insn_1
- From: Toshi Morita <tm2 at best dot com>
- Date: Sat, 14 Apr 2001 03:45:23 -0700 (PDT)
- Cc: jh at suse dot cz, kazu at hxi dot com
There seems to be a bug in emit_move_insn_1 which affects the
h8300-hms target. Here is my analysis and patch:
When attempting to build for --target=h8300-hms, this error occurs:
...
/home/tm/gcc-build-h8300/gcc/xgcc -B/home/tm/gcc-build-h8300/gcc/ -B/usr/local/h8300-hms/bin/ -B/usr/local/h8300-hms/lib/ -isystem /usr/local/h8300-hms/include -O2 -DCROSS_COMPILE -DIN_GCC -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -isystem ./include -DDF=SF -DDI=SI -g1 -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED -Dinhibit_libc -I. -I. -I../../gcc/gcc -I../../gcc/gcc/. -I../../gcc/gcc/config -I../../gcc/gcc/../include -fexceptions -c ../../gcc/gcc/unwind-sjlj.c -o libgcc/./unwind-sjlj.o
../../gcc/gcc/unwind-sjlj.c: In function `_Unwind_GetRegionStart':
../../gcc/gcc/unwind-sjlj.c:200: warning: unused parameter `context'
In file included from ../../gcc/gcc/unwind-sjlj.c:257:
../../gcc/gcc/unwind.inc: In function `_Unwind_RaiseException_Phase2':
../../gcc/gcc/unwind.inc:67: warning: implicit declaration of function `abort'
../../gcc/gcc/unwind.inc:57: Internal compiler error in expand_call, at calls.c:3081
This abort occurs because this line is triggered in expand_call:
/* Verify that we've deallocated all the stack we used. */
if (pass
&& old_stack_allocated != stack_pointer_delta - pending_stack_adjust)
abort ();
This abort is triggered because gcc loses track of the stack displacement.
This problem occurs when GCC pushes a DImode parameter onto the stack:
(gdb)
2963 if (args[i].reg == 0 || args[i].pass_on_stack)
(gdb)
2965 rtx before_arg = get_last_insn ();
(gdb) print cfun->expr->x_stack_pointer_delta
$13 = 4
(gdb) print args[2].mode
$14 = DImode
(gdb) next
2967 if (store_one_arg (&args[i], argblock, flags,
(gdb) next
2974 }
(gdb) print cfun->expr->x_stack_pointer_delta
$15 = 20
Basically, the stack pointer is adjusted TWICE and winds up with a displacement
of 16 instead of 8.
This problem occurs because cfun->expr->x_stack_pointer_delta is
adjusted in two different places for this testcase:
expr.c:3153: emit_single_push_insn():
#define stack_pointer_delta (cfun->expr->x_stack_pointer_delta)
stack_pointer_delta += PUSH_ROUNDING (GET_MODE_SIZE (mode));
expr.c:2965: emit_move_insn_1();
anti_adjust_stack (GEN_INT (GET_MODE_SIZE (GET_MODE (x))));
I believe the code at expr.c:2965 is incorrect because there are
multiple code paths through emit_move_insn_1, and only one of them
(the bug case) updates cfun->expr->x_stack_pointer_delta, and
only when PUSH_ROUNDING is defined.
So, here is the patch:
Sat Apr 14 02:47:56 PDT 2001 Toshiyasu Morita (toshiyasu.morita@hsa.hitachi.com)
expr.c (emit_move_insn_1): Avoid modifying cfun->expr->x_stack_pointer
when PUSH_ROUNDING is defined.
*** expr.c Fri Apr 13 20:39:22 2001
--- expr.c.fix Sat Apr 14 01:49:55 2001
***************
*** 2776,2781 ****
--- 2776,2782 ----
enum machine_mode submode;
enum mode_class class = GET_MODE_CLASS (mode);
unsigned int i;
+ rtx temp;
if ((unsigned int) mode >= (unsigned int) MAX_MACHINE_MODE)
abort ();
***************
*** 2962,2968 ****
X with a reference to the stack pointer. */
if (push_operand (x, GET_MODE (x)))
{
! anti_adjust_stack (GEN_INT (GET_MODE_SIZE (GET_MODE (x))));
x = change_address (x, VOIDmode, stack_pointer_rtx);
}
#endif
--- 2963,2985 ----
X with a reference to the stack pointer. */
if (push_operand (x, GET_MODE (x)))
{
! /* Do not use anti_adjust_stack, since we don't want to update
! stack_pointer_delta. */
! temp = expand_binop (Pmode,
! #ifdef STACK_GROWS_DOWNWARD
! sub_optab,
! #else
! add_optab,
! #endif
! stack_pointer_rtx,
! GEN_INT
! (PUSH_ROUNDING (GET_MODE_SIZE (GET_MODE (x)))),
! stack_pointer_rtx,
! 0,
! OPTAB_LIB_WIDEN);
! if (temp != stack_pointer_rtx)
! emit_move_insn (stack_pointer_rtx, temp);
!
x = change_address (x, VOIDmode, stack_pointer_rtx);
}
#endif
With this patch, the h8300-hms target is buildable again, and the source still
passes "make bootstrap" on i686-linux.
Also, if someone could review/approve my previous patches, it'd be greatly appreciated:
4/11/01: http://gcc.gnu.org/ml/gcc-patches/2001-04/msg00665.html (remove redundant test)
3/28/01: http://gcc.gnu.org/ml/gcc-patches/2001-03/msg01957.html (H8/300 release info fix)
3/10/01: http://gcc.gnu.org/ml/gcc-patches/2001-03/msg00624.html (v850 GC bug)
3/07/01: http://gcc.gnu.org/ml/gcc-patches/2001-03/msg00374.html (combiner bugfix)
Toshi