Fix a bunch of ia64 compile-time crashes

Jan Hubicka jh@suse.cz
Wed Jan 28 21:11:00 GMT 2004


> 
> Jan's performance patches exposed a latent bug in the ia64 back end
> which manifested as crashes in the test suite:
> 
> FAIL: gcc.c-torture/compile/20001205-1.c (test for excess errors)
> FAIL: gcc.c-torture/compile/20010605-3.c (test for excess errors)
> FAIL: gcc.c-torture/compile/20010605-3.c (test for excess errors)
> FAIL: gcc.c-torture/compile/20010605-3.c (test for excess errors)
> FAIL: gcc.c-torture/compile/20010605-3.c (test for excess errors)
> FAIL: gcc.dg/20030405-1.c (test for excess errors)
> 
> In short - match_dup expressions must appear lexically after their
> corresponding match_operand expressions in all machine description
> patterns.  Before the performance patches, these would simply fail
> to match, as the operands array was cleared to zero before calling

Actually things are nastier - the arrays got clearled only on some calls
of recog, while not on the others.  I can imagine scenario where
instruction happen to match by accident just becuase operand array
already contains "right" value.

> recog; but now recog calls rtx_equal_p on garbage data.
> 
> Fixed by swapping all the offending match_operand and match_dup
> expressions.  Jan has a patch which makes genrecog detect these
> and error out, which I encourage him to clean up and submit. 
> For right now I'm just going to fix the ia64 machine description.
> I consider this patch pretty obvious, but I'm going to hold off
> applying it (to both 3.4 and mainline) for a little while in case
> someone knows different.
> 
> Bootstrapped ia64-hpux; I could only run the C testsuite, due to
> dwarf2 crashes while compiling libstdc++.
> 
> zw
> 
>         * config/ia64/ia64.md (fetchadd_acq_si, fetchadd_acq_di)
>         (cmpxchg_acq_si, cmpxchg_acq_di): Exchange match_dup and
>         match_operand expressions so that all match_dups appear
>         lexically after their corresponding match_operands.

Thanks for sending this.
I am attaching the genrecog patch for sanity checking

2004-01-28  Jan Hubicka  <jh@suse.cz>
	* genrecog.c (find_operand): add extra argument stop.
	(validate_pattern): Verify that mach_dup is duplicating operand
	defined lexically earlier.
Index: genrecog.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/genrecog.c,v
retrieving revision 1.135
diff -c -3 -p -r1.135 genrecog.c
*** genrecog.c	21 Jan 2004 20:40:02 -0000	1.135
--- genrecog.c	27 Jan 2004 23:04:42 -0000
*************** static struct decision *new_decision
*** 231,237 ****
  static struct decision_test *new_decision_test
    (enum decision_type, struct decision_test ***);
  static rtx find_operand
!   (rtx, int);
  static rtx find_matching_operand
    (rtx, int);
  static void validate_pattern
--- 231,237 ----
  static struct decision_test *new_decision_test
    (enum decision_type, struct decision_test ***);
  static rtx find_operand
!   (rtx, int, rtx);
  static rtx find_matching_operand
    (rtx, int);
  static void validate_pattern
*************** new_decision_test (enum decision_type ty
*** 345,360 ****
    return test;
  }
  
! /* Search for and return operand N.  */
  
  static rtx
! find_operand (rtx pattern, int n)
  {
    const char *fmt;
    RTX_CODE code;
    int i, j, len;
    rtx r;
  
    code = GET_CODE (pattern);
    if ((code == MATCH_SCRATCH
         || code == MATCH_INSN
--- 345,363 ----
    return test;
  }
  
! /* Search for and return operand N, stop when reaching node STOP.  */
  
  static rtx
! find_operand (rtx pattern, int n, rtx stop)
  {
    const char *fmt;
    RTX_CODE code;
    int i, j, len;
    rtx r;
  
+   if (pattern == stop)
+     return stop;
+ 
    code = GET_CODE (pattern);
    if ((code == MATCH_SCRATCH
         || code == MATCH_INSN
*************** find_operand (rtx pattern, int n)
*** 371,377 ****
        switch (fmt[i])
  	{
  	case 'e': case 'u':
! 	  if ((r = find_operand (XEXP (pattern, i), n)) != NULL_RTX)
  	    return r;
  	  break;
  
--- 374,380 ----
        switch (fmt[i])
  	{
  	case 'e': case 'u':
! 	  if ((r = find_operand (XEXP (pattern, i), n, stop)) != NULL_RTX)
  	    return r;
  	  break;
  
*************** find_operand (rtx pattern, int n)
*** 382,388 ****
  
  	case 'E':
  	  for (j = 0; j < XVECLEN (pattern, i); j++)
! 	    if ((r = find_operand (XVECEXP (pattern, i, j), n)) != NULL_RTX)
  	      return r;
  	  break;
  
--- 385,392 ----
  
  	case 'E':
  	  for (j = 0; j < XVECLEN (pattern, i); j++)
! 	    if ((r = find_operand (XVECEXP (pattern, i, j), n, stop))
! 		!= NULL_RTX)
  	      return r;
  	  break;
  
*************** validate_pattern (rtx pattern, rtx insn,
*** 466,472 ****
      {
      case MATCH_SCRATCH:
        return;
! 
      case MATCH_INSN:
      case MATCH_OPERAND:
      case MATCH_OPERATOR:
--- 470,486 ----
      {
      case MATCH_SCRATCH:
        return;
!     case MATCH_DUP:
!     case MATCH_OP_DUP:
!     case MATCH_PAR_DUP:
!       if (find_operand (insn, XINT (pattern, 0), pattern) == pattern)
! 	{
! 	  message_with_line (pattern_lineno,
! 			     "operand %i duplicated before defined",
! 			     XINT (pattern, 0));
!           error_count++;
! 	}
!       break;
      case MATCH_INSN:
      case MATCH_OPERAND:
      case MATCH_OPERATOR:
*************** validate_pattern (rtx pattern, rtx insn,
*** 638,649 ****
  	if (GET_CODE (dest) == MATCH_DUP
  	    || GET_CODE (dest) == MATCH_OP_DUP
  	    || GET_CODE (dest) == MATCH_PAR_DUP)
! 	  dest = find_operand (insn, XINT (dest, 0));
  
  	if (GET_CODE (src) == MATCH_DUP
  	    || GET_CODE (src) == MATCH_OP_DUP
  	    || GET_CODE (src) == MATCH_PAR_DUP)
! 	  src = find_operand (insn, XINT (src, 0));
  
  	dmode = GET_MODE (dest);
  	smode = GET_MODE (src);
--- 652,663 ----
  	if (GET_CODE (dest) == MATCH_DUP
  	    || GET_CODE (dest) == MATCH_OP_DUP
  	    || GET_CODE (dest) == MATCH_PAR_DUP)
! 	  dest = find_operand (insn, XINT (dest, 0), NULL);
  
  	if (GET_CODE (src) == MATCH_DUP
  	    || GET_CODE (src) == MATCH_OP_DUP
  	    || GET_CODE (src) == MATCH_PAR_DUP)
! 	  src = find_operand (insn, XINT (src, 0), NULL);
  
  	dmode = GET_MODE (dest);
  	smode = GET_MODE (src);



More information about the Gcc-patches mailing list