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]

S/390: Disable load/store_multiple before reload


Hello,

unfortunately reload doesn't appear to be able to handle the s390
load_multiple/store_multiple patterns correctly; all but the first
element of the PARALLEL will not get substitutions applied to.

I see that other ports have circumvented this problem by rephrasing
their pattern without using match_parallel; this appears difficult
to do in our case though (because our LOAD MULTIPLE instruction
allows base + displacement addressing) ...

As we have actual bug reports of this problem causing ICEs on valid
code, and also these pattern aren't really all that frequently used
before reload, I've decided to allow them only after reload for now.

Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux on 
3.3, 3.4, and mainline.  Applied to all three branches.

Bye,
Ulrich


ChangeLog:

	* config/s390/s390.md ("load_multiple", "*load_multiple_di",
	"*load_multiple_si"): Allow only if reload_completed.
	("store_multiple", "*store_multiple_di", "*store_multiple_si"):
	Likewise.

testsuite/ChangeLog:

	* gcc.dg/20040306-1.c: New test.


Index: gcc/config/s390/s390.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.md,v
retrieving revision 1.102
diff -c -p -r1.102 s390.md
*** gcc/config/s390/s390.md	19 Feb 2004 17:36:45 -0000	1.102
--- gcc/config/s390/s390.md	6 Mar 2004 19:45:17 -0000
***************
*** 1696,1707 ****
  ;
  ; load_multiple pattern(s).
  ;
  
  (define_expand "load_multiple"
    [(match_par_dup 3 [(set (match_operand 0 "" "")
  			  (match_operand 1 "" ""))
  		     (use (match_operand 2 "" ""))])]
!   ""
  {
    enum machine_mode mode;
    int regno;
--- 1696,1710 ----
  ;
  ; load_multiple pattern(s).
  ;
+ ; ??? Due to reload problems with replacing registers inside match_parallel
+ ; we currently support load_multiple/store_multiple only after reload.
+ ;
  
  (define_expand "load_multiple"
    [(match_par_dup 3 [(set (match_operand 0 "" "")
  			  (match_operand 1 "" ""))
  		     (use (match_operand 2 "" ""))])]
!   "reload_completed"
  {
    enum machine_mode mode;
    int regno;
***************
*** 1763,1769 ****
    [(match_parallel 0 "load_multiple_operation"
  		   [(set (match_operand:DI 1 "register_operand" "=r")
  			 (match_operand:DI 2 "s_operand" "QS"))])]
!   "word_mode == DImode"
  {
    int words = XVECLEN (operands[0], 0);
    operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
--- 1766,1772 ----
    [(match_parallel 0 "load_multiple_operation"
  		   [(set (match_operand:DI 1 "register_operand" "=r")
  			 (match_operand:DI 2 "s_operand" "QS"))])]
!   "reload_completed && word_mode == DImode"
  {
    int words = XVECLEN (operands[0], 0);
    operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
***************
*** 1776,1782 ****
    [(match_parallel 0 "load_multiple_operation"
  		   [(set (match_operand:SI 1 "register_operand" "=r,r")
  			 (match_operand:SI 2 "s_operand" "Q,S"))])]
!   ""
  {
    int words = XVECLEN (operands[0], 0);
    operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
--- 1779,1785 ----
    [(match_parallel 0 "load_multiple_operation"
  		   [(set (match_operand:SI 1 "register_operand" "=r,r")
  			 (match_operand:SI 2 "s_operand" "Q,S"))])]
!   "reload_completed"
  {
    int words = XVECLEN (operands[0], 0);
    operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
***************
*** 1793,1799 ****
    [(match_par_dup 3 [(set (match_operand 0 "" "")
  			  (match_operand 1 "" ""))
  		     (use (match_operand 2 "" ""))])]
!   ""
  {
    enum machine_mode mode;
    int regno;
--- 1796,1802 ----
    [(match_par_dup 3 [(set (match_operand 0 "" "")
  			  (match_operand 1 "" ""))
  		     (use (match_operand 2 "" ""))])]
!   "reload_completed"
  {
    enum machine_mode mode;
    int regno;
***************
*** 1857,1863 ****
    [(match_parallel 0 "store_multiple_operation"
  		   [(set (match_operand:DI 1 "s_operand" "=QS")
  			 (match_operand:DI 2 "register_operand" "r"))])]
!   "word_mode == DImode"
  {
    int words = XVECLEN (operands[0], 0);
    operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
--- 1860,1866 ----
    [(match_parallel 0 "store_multiple_operation"
  		   [(set (match_operand:DI 1 "s_operand" "=QS")
  			 (match_operand:DI 2 "register_operand" "r"))])]
!   "reload_completed && word_mode == DImode"
  {
    int words = XVECLEN (operands[0], 0);
    operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
***************
*** 1871,1877 ****
    [(match_parallel 0 "store_multiple_operation"
  		   [(set (match_operand:SI 1 "s_operand" "=Q,S")
  			 (match_operand:SI 2 "register_operand" "r,r"))])]
!   ""
  {
    int words = XVECLEN (operands[0], 0);
    operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
--- 1874,1880 ----
    [(match_parallel 0 "store_multiple_operation"
  		   [(set (match_operand:SI 1 "s_operand" "=Q,S")
  			 (match_operand:SI 2 "register_operand" "r,r"))])]
!   "reload_completed"
  {
    int words = XVECLEN (operands[0], 0);
    operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
*** /dev/null	Mon Aug 11 14:39:14 2003
--- gcc/testsuite/gcc.dg/20040306-1.c	Sat Mar  6 20:52:44 2004
***************
*** 0 ****
--- 1,22 ----
+ /* This used to ICE due to a reload bug on s390*.  */
+ 
+ /* { dg-do compile } */
+ /* { dg-options "-O2" } */
+ 
+ 
+ typedef struct test
+ {
+   unsigned short pad;
+   unsigned char type[6];
+ } t;
+ 
+ extern void set (t *a, t *b, t *c, t *d, t *e, t *f, t *g, t *h, 
+ 		 t *i, t *j, t *k, t *l, t *m, t *n, t *o, t *p);
+ extern void use (t a, t b, t c, t d, t e, t f, t g, t h,
+ 		 t i, t j, t k, t l, t m, t n, t o, t p);
+ void test (void)
+ {
+     t a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p;
+     set (&a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m, &n, &o, &p);
+     use (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p);
+ }
-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de


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