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]

PATCH: fix emit_move_insn_1



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


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