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]

[PATCH] S/390: Bug when predicting base register usage


Hi,

the attached patch fixes a bug in the s390 backend.  In s390_init_frame_layout
we have to predict whether we will need a literal pool base pointer or not.
Among other things we have to care about the frame size.  When the frame_size gets
to large it might be necessary to push the value into the literal pool.  The
s390_init_frame_layout function therefore checks whether the frame size is a
valid displacement (to be used in a load address instruction) or is a valid
16bit constant (to be used directly as an immediate value in an add instruction).
Unfortunately only the negated value was checked.  So a value of 32768 was
accepted.  But in the function epilogue this value has to be added to the stack 
pointer and the positive value isn't a 16bit constant.

With the patch s390_init_frame_layout makes sure that the positive value is
a valid constant.

Bootstraps for GCC 4.2 still running on s390 and s390x.

OK for GCC 4.1, 4.2 and mainline if testsuite shows no regressions?


Bye,

-Andreas-



2006-10-25  Andreas Krebbel  <krebbel1@de.ibm.com>

	* config/s390/s390.c (s390_init_frame_layout): Check positve frame_size.


2006-10-25  Andreas Krebbel  <krebbel1@de.ibm.com>

	* gcc.dg/20061025.c: New testcase.


Index: gcc/config/s390/s390.c
===================================================================
*** gcc/config/s390/s390.c.orig	2006-10-25 16:50:22.000000000 +0200
--- gcc/config/s390/s390.c	2006-10-25 16:50:59.000000000 +0200
*************** s390_init_frame_layout (void)
*** 6718,6725 ****
        /* Try to predict whether we'll need the base register.  */
        base_used = cfun->machine->split_branches_pending_p
  		  || current_function_uses_const_pool
! 		  || (!DISP_IN_RANGE (-frame_size)
! 		      && !CONST_OK_FOR_K (-frame_size));
  
        /* Decide which register to use as literal pool base.  In small
  	 leaf functions, try to use an unused call-clobbered register
--- 6718,6725 ----
        /* Try to predict whether we'll need the base register.  */
        base_used = cfun->machine->split_branches_pending_p
  		  || current_function_uses_const_pool
! 		  || (!DISP_IN_RANGE (frame_size)
! 		      && !CONST_OK_FOR_K (frame_size));
  
        /* Decide which register to use as literal pool base.  In small
  	 leaf functions, try to use an unused call-clobbered register
Index: gcc/testsuite/gcc.dg/20061025.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.dg/20061025.c	2006-10-25 16:50:59.000000000 +0200
***************
*** 0 ****
--- 1,13 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O1" } */
+ 
+ /* This testcase failed on s390.  The frame size for function f will be
+    exactly 32768 bytes.  The back end has to recognize that this is too
+    large for a 16bit constant and therefore should reserve the literal
+    pool base pointer.  */
+ 
+ int f () {
+   char a[32608];
+ 
+   g (a);
+ }


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