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] Fix PR rtl-optimization/27661 (reload problem)


Hello,

this fixes PR 27661.  The problem here is how to handle address
reloads when the address was reduced to a simple const_int --
since the mode of the address thus is VOIDmode, what mode should
be used for the reload register?

When this situation occurs in find_reloads_address when encountering
an *invalid* address, the code there simply defaults to using Pmode.
That would appear reasonable, even on architectures that simultaneously
support more that one mode for addresses, because Pmode is always at
least one valid address mode.

However, when an address is valid as such, but needs to be reloaded
later on anyway due to it not fulfilling an EXTRA_MEMORY_CONSTRAINT
(or 'o' constraint), the code there does *not* cope with VOIDmode
as the mode of the address, and will ICE.

The patch below fixes the problem by defaulting to Pmode there
as well.

Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux,
fixes the test case from the PR.

OK for mainline / 4.1 / 4.0 ?

Bye,
Ulrich

:ADDPATCH reload:

ChangeLog:

	PR rtl-optimization/27661
	* reload.c (find_reloads): When reloading a VOIDmode constant
	as address due to an EXTRA_MEMORY_CONSTRAINT or 'o' constraint,
	use Pmode as mode of the reload register.

testsuite/ChangeLog:

	PR rtl-optimization/27661
	* gcc.dg/pr27661.c: New test case.


Index: gcc/reload.c
===================================================================
*** gcc/reload.c	(revision 113828)
--- gcc/reload.c	(working copy)
*************** find_reloads (rtx insn, int replace, int
*** 3854,3864 ****
  		 && goal_alternative_offmemok[i]
  		 && MEM_P (recog_data.operand[i]))
  	  {
  	    operand_reloadnum[i]
  	      = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
  			     &XEXP (recog_data.operand[i], 0), (rtx*) 0,
  			     base_reg_class (VOIDmode, MEM, SCRATCH),
! 			     GET_MODE (XEXP (recog_data.operand[i], 0)),
  			     VOIDmode, 0, 0, i, RELOAD_FOR_INPUT);
  	    rld[operand_reloadnum[i]].inc
  	      = GET_MODE_SIZE (GET_MODE (recog_data.operand[i]));
--- 3854,3872 ----
  		 && goal_alternative_offmemok[i]
  		 && MEM_P (recog_data.operand[i]))
  	  {
+ 	    /* If the address to be reloaded is a VOIDmode constant,
+ 	       use Pmode as mode of the reload register, as would have
+ 	       been done by find_reloads_address.  */
+ 	    enum machine_mode address_mode;
+ 	    address_mode = GET_MODE (XEXP (recog_data.operand[i], 0));
+ 	    if (address_mode == VOIDmode)
+ 	      address_mode = Pmode;
+ 
  	    operand_reloadnum[i]
  	      = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
  			     &XEXP (recog_data.operand[i], 0), (rtx*) 0,
  			     base_reg_class (VOIDmode, MEM, SCRATCH),
! 			     address_mode,
  			     VOIDmode, 0, 0, i, RELOAD_FOR_INPUT);
  	    rld[operand_reloadnum[i]].inc
  	      = GET_MODE_SIZE (GET_MODE (recog_data.operand[i]));
*** /dev/null	Tue Oct 26 21:09:21 2004
--- gcc/testsuite/gcc.dg/pr27661.c	Mon May 22 20:50:46 2006
***************
*** 0 ****
--- 1,25 ----
+ /* This used to ICE on s390 due to a reload bug.  */
+ 
+ /* { dg-do compile { target s390*-*-* } } */
+ /* { dg-options "-O2 -march=z990 -ftracer" } */
+ 
+ extern int memcmp (const void *s1, const void *s2, unsigned long n);
+ extern int printf (__const char *__restrict __format, ...);
+ 
+ struct test
+ {
+   char tmp[4096];
+   char msgtype[2];
+ };
+ 
+ void test (struct test *testtb)
+ {
+   if (testtb)
+     printf ("a");
+ 
+   if (memcmp(testtb->msgtype, "a", 2))
+     printf ("a");
+ 
+   printf ("b");
+ }
+ 
-- 
  Dr. Ulrich Weigand
  Linux on zSeries Development
  Ulrich.Weigand@de.ibm.com


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