Your Jan 15 change broke the x86

Richard Henderson rth@cygnus.com
Sat Jan 30 16:13:00 GMT 1999


On Sat, Jan 30, 1999 at 11:08:50AM -0700, Jeffrey A Law wrote:
> 
> Fri Jan 15 18:42:12 1999  Richard Henderson  <rth@cygnus.com>
> 
>         * expr.c (queued_subexp_p): Make public.
>         * expr.h (queued_subexp_p): Declare it.
>         * recog.c (asm_operand_ok): New function.
>         (check_asm_operands): Use it.  After reload, use constrain_operands 
>         instead.
>         * recog.h (asm_operand_ok): Declare it.
>         * stmt.c (expand_asm_operands): Use it to try harder to make
>         asms initially satisfy their constraints.
> 
> Is breaking the x86.  Specifically it will not bootstrap with -O0.
> 
> Here's a testcase.  Compile it with -O0 on an x86.  The compiler will abort
> during instantiate_virtual_regs_1.

Got it.  The immediate problem was that we weren't finding the matching
constraint on "%0" and so failing to OK anything.  The underlying problem
is to aggressive checking with too little information -- if a matching
constraint is buried in alternatives ("r,0") we have scarce hope of
doing the right thing before reload.

The attached patch modifies asm_operand_ok to recognize when results are
inconclusive.  Its two uses then take the conservative approach. 

In addition, "%" handling is improved so that we don't have to throw up
our hands quite so often.  I don't really check swapping of operands,
but it makes sure at least one of the two operands will be close.

> It also appears that they're causing the PA to blow up with a similar
> problem, except in divdi3, which also uses asms...

Would you check to see that this solves the PA problem as well?


r~


	* recog.c (check_asm_operands): Ignore "%".
	(asm_operand_ok): Return inconclusive if the string contains
	a matching constraint.
	* stmt.c (expand_asm_operands): Skip "%" when resolving a matching
	constraint.  Regard operand ok inconclusive as failure and fix up.

Index: recog.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/recog.c,v
retrieving revision 1.27
diff -c -p -d -r1.27 recog.c
*** recog.c	1999/01/23 19:45:40	1.27
--- recog.c	1999/01/30 22:25:48
*************** check_asm_operands (x)
*** 188,194 ****
    for (i = 0; i < noperands; i++)
      {
        const char *c = constraints[i];
!       if (ISDIGIT ((unsigned char)c[0]))
  	c = constraints[c[0] - '0'];
  
        if (! asm_operand_ok (operands[i], c))
--- 188,196 ----
    for (i = 0; i < noperands; i++)
      {
        const char *c = constraints[i];
!       if (c[0] == '%')
! 	c++;
!       if (ISDIGIT ((unsigned char)c[0]) && c[1] == '\0')
  	c = constraints[c[0] - '0'];
  
        if (! asm_operand_ok (operands[i], c))
*************** decode_asm_operands (body, operands, ope
*** 1550,1562 ****
    return template;
  }
  
! /* Check if an asm_operand matches it's constraints.  */
  
  int
  asm_operand_ok (op, constraint)
       rtx op;
       const char *constraint;
  {
    /* Use constrain_operands after reload.  */
    if (reload_completed)
      abort ();
--- 1552,1567 ----
    return template;
  }
  
! /* Check if an asm_operand matches it's constraints. 
!    Return > 0 if ok, = 0 if bad, < 0 if inconclusive.  */
  
  int
  asm_operand_ok (op, constraint)
       rtx op;
       const char *constraint;
  {
+   int result = 0;
+ 
    /* Use constrain_operands after reload.  */
    if (reload_completed)
      abort ();
*************** asm_operand_ok (op, constraint)
*** 1578,1586 ****
  
  	case '0': case '1': case '2': case '3': case '4':
  	case '5': case '6': case '7': case '8': case '9':
! 	  /* Our caller is supposed to have given us the proper
! 	     matching constraint.  */
! 	  /* abort (); */
  	  break;
  
  	case 'p':
--- 1583,1593 ----
  
  	case '0': case '1': case '2': case '3': case '4':
  	case '5': case '6': case '7': case '8': case '9':
! 	  /* For best results, our caller should have given us the
! 	     proper matching constraint, but we can't actually fail
! 	     the check if they didn't.  Indicate that results are
! 	     inconclusive.  */
! 	  result = -1;
  	  break;
  
  	case 'p':
*************** asm_operand_ok (op, constraint)
*** 1745,1751 ****
  	}
      }
  
!   return 0;
  }
  
  /* Given an rtx *P, if it is a sum containing an integer constant term,
--- 1752,1758 ----
  	}
      }
  
!   return result;
  }
  
  /* Given an rtx *P, if it is a sum containing an integer constant term,
Index: stmt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/stmt.c,v
retrieving revision 1.59
diff -c -p -d -r1.59 stmt.c
*** stmt.c	1999/01/24 07:23:59	1.59
--- stmt.c	1999/01/30 22:25:48
*************** expand_asm_operands (string, outputs, in
*** 1472,1478 ****
  	      }
  
  	    /* Try and find the real constraint for this dup.  */
! 	    if (j == 0 && c_len == 1)
  	      {
  		tree o = outputs;
  		for (j = constraint[j] - '0'; j > 0; --j)
--- 1472,1479 ----
  	      }
  
  	    /* Try and find the real constraint for this dup.  */
! 	    if ((j == 0 && c_len == 1)
! 		|| (j == 1 && c_len == 2 && constraint[0] == '%'))
  	      {
  		tree o = outputs;
  		for (j = constraint[j] - '0'; j > 0; --j)
*************** expand_asm_operands (string, outputs, in
*** 1502,1508 ****
  
        op = expand_expr (TREE_VALUE (tail), NULL_RTX, VOIDmode, 0);
  
!       if (! asm_operand_ok (op, constraint))
  	{
  	  if (allows_reg)
  	    op = force_reg (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))), op);
--- 1503,1509 ----
  
        op = expand_expr (TREE_VALUE (tail), NULL_RTX, VOIDmode, 0);
  
!       if (asm_operand_ok (op, constraint) <= 0)
  	{
  	  if (allows_reg)
  	    op = force_reg (TYPE_MODE (TREE_TYPE (TREE_VALUE (tail))), op);



More information about the Gcc-patches mailing list