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]
Other format: [Raw text]

mips.h patch for -fprofile-generate code gen bug


This patch fixes bug 16325.  This is a problem with SPEC95 FP 146.wave5 failing
with a segfault when compiled with -O -fprofile-generate -mabi=32 for a
mips64-linux target.

The problem is that we emit profiling code that makes a libcall into a leaf
function.  We end up with contradictory assumptions about whether there is an
argument register save area, and we end up with local variables clobbering the
gp save area.  There are additional details about how exactly this happens in
the bug report.

The safest simplest solution seems to be to pre-allocate the argument register
save area when flag_profile_values is true, in order to avoid the confusion.

Presumably, at some point in the future, we will move the profiling code into
the trees/gimple, and then we will no longer have this problem.

This was tested on mips64-linux with a profiledbootstrap, and a C only make
check with and without the patch.  This has also been tested against SPEC95 FP
with FDO (feedback directed optimization), which was the original testcase.

I left the -mabi=32 option out of the testcase, because if I hardwire that
in, then the test will no longer work for all mips targets.  It will fail for
any target that doesn't support the old 32-bit ABI.  Instead, my assumption
here is that proper testing will involve testing the multilibs, so this will
get tested when the -mabi=32 multilib is tested.

I am planning to check this into both mainline and the gcc-3.4 branch.  I will
wait a few days in case one of the MIPS maintainers wants to comment.

gcc/ChangeLog
2004-07-13  James E Wilson  <wilson@specifixinc.com>

	PR target/16325
	* config/mips/mips.h (STARTING_FRAME_OFFSET): When flag_profile_value
	and ! TARGET_64BIT, include REG_PARM_STACK_SPACE.

gcc/testsuite/ChangeLog
2004-07-13  James E Wilson  <wilson@specifixinc.com>

	PR target/16325
	* gcc.dg/profile-generate-1.c: New.

*** orig-gcc-3.5-20040711/gcc/config/mips/mips.h	2004-07-07 12:17:05.000000000 -0700
--- gcc-3.5-20040711/gcc/config/mips/mips.h	2004-07-13 11:24:57.000000000 -0700
*************** extern enum reg_class mips_char_to_class
*** 2140,2148 ****
  #define STACK_GROWS_DOWNWARD
  
  /* The offset of the first local variable from the beginning of the frame.
!    See compute_frame_size for details about the frame layout.  */
  #define STARTING_FRAME_OFFSET						\
!   (current_function_outgoing_args_size					\
     + (TARGET_ABICALLS && !TARGET_NEWABI					\
        ? MIPS_STACK_ALIGN (UNITS_PER_WORD) : 0))
  
--- 2140,2160 ----
  #define STACK_GROWS_DOWNWARD
  
  /* The offset of the first local variable from the beginning of the frame.
!    See compute_frame_size for details about the frame layout.
! 
!    ??? If flag_profile_values is true, and we are generating 32-bit code, then
!    we assume that we will need 16 bytes of argument space.  This is because
!    the value profiling code may emit calls to cmpdi2 in leaf functions.
!    Without this hack, the local variables will start at sp+8 and the gp save
!    area will be at sp+16, and thus they will overlap.  compute_frame_size is
!    OK because it uses STARTING_FRAME_OFFSET to compute cprestore_size, which
!    will end up as 24 instead of 8.  This won't be needed if profiling code is
!    inserted before virtual register instantiation.  */
! 
  #define STARTING_FRAME_OFFSET						\
!   ((flag_profile_values && ! TARGET_64BIT				\
!     ? MAX (REG_PARM_STACK_SPACE(NULL), current_function_outgoing_args_size) \
!     : current_function_outgoing_args_size)				\
     + (TARGET_ABICALLS && !TARGET_NEWABI					\
        ? MIPS_STACK_ALIGN (UNITS_PER_WORD) : 0))
  
*** orig-gcc-3.5-20040711/gcc/testsuite/gcc.dg/profile-generate-1.c	2004-07-13 12:01:31.000000000 -0700
--- gcc-3.5-20040711/gcc/testsuite/gcc.dg/profile-generate-1.c	2004-07-13 11:20:46.000000000 -0700
***************
*** 0 ****
--- 1,34 ----
+ /* Bug 16325.  */
+ /* { dg-do run { target mips*-*-* } } */
+ /* { dg-options "-O -fprofile-generate" } */
+ 
+ int *p1;
+ int *p2;
+ int *p3;
+ 
+ int ga = 100;
+ 
+ int
+ sub (int i, int j)
+ {
+   int k;
+   int l;
+   int m;
+   int n;
+   p1 = &k;
+   p2 = &l;
+   p3 = &m;
+   k = 20;
+   l = 30;
+   m = 40;
+   n = i / j;
+   return n + ga;
+ }
+ 
+ int
+ main(void)
+ {
+   if (sub (99, 33) != 103)
+     abort ();
+   return 0;
+ }
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com


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