This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Fix a bunch of ia64 compile-time crashes
- From: Jan Hubicka <jh at suse dot cz>
- To: Zack Weinberg <zack at codesourcery dot com>
- Cc: gcc-patches at gcc dot gnu dot org, Jan Hubicka <jh at suse dot cz>,Jim Wilson <wilson at specifixinc dot com>
- Date: Wed, 28 Jan 2004 22:08:02 +0100
- Subject: Re: Fix a bunch of ia64 compile-time crashes
- References: <874quf94ya.fsf@egil.codesourcery.com>
>
> 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);