From mboxrd@z Thu Jan 1 00:00:00 1970 From: Philip Blundell To: nobody@gcc.gnu.org Cc: gcc-prs@gcc.gnu.org Subject: Re: c/2404: arm-linux-gcc ice Date: Tue, 27 Mar 2001 13:26:00 -0000 Message-id: <20010327212600.21383.qmail@sourceware.cygnus.com> X-SW-Source: 2001-03/msg00305.html List-Id: The following reply was made to PR c/2404; it has been noted by GNATS. From: Philip Blundell To: bkohlen@intrinsyc.com Cc: gcc-gnats@gcc.gnu.org Subject: Re: c/2404: arm-linux-gcc ice Date: Tue, 27 Mar 2001 22:24:04 +0100 >shadow.c: In function `shadowImageGlyphBlt': >shadow.c:1173: Internal compiler error in `purge_addressof_1', at function.c:3 >183 >Please submit a full bug report. >See for instructions. Does this patch help at all? p. --- gcc/function.c 1999/05/20 22:26:35 1.90.4.1 +++ gcc/function.c 1999/07/16 09:30:04 @@ -3042,6 +3042,105 @@ extracted by usage MEM with narrower mode. */ static rtx purge_addressof_replacements; +/* Return 1 if X and Y are identical-looking rtx's. + This is the Lisp function EQUAL for rtx arguments. */ + +int +rtx_equal_for_addressof_p (x, y) + rtx x, y; +{ + register int i; + register int j; + register enum rtx_code code; + register char *fmt; + + if (x == y) + return 1; + if (x == 0 || y == 0) + return 0; + + code = GET_CODE (x); + /* Rtx's of different codes cannot be equal. */ + if (code != GET_CODE (y)) + return 0; + + /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. + (REG:SI x) and (REG:HI x) are NOT equivalent. + But (MEM:SI x) and (MEM:HI x) are equivalent for our purposes. */ + + if (code != MEM && (GET_MODE (x) != GET_MODE (y))) + return 0; + + /* REG, LABEL_REF, and SYMBOL_REF can be compared nonrecursively. */ + + if (code == REG) + return REGNO (x) == REGNO (y); + else if (code == LABEL_REF) + return XEXP (x, 0) == XEXP (y, 0); + else if (code == SYMBOL_REF) + return XSTR (x, 0) == XSTR (y, 0); + else if (code == SCRATCH || code == CONST_DOUBLE) + return 0; + + /* Compare the elements. If any pair of corresponding elements + fail to match, return 0 for the whole things. */ + + fmt = GET_RTX_FORMAT (code); + for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) + { + switch (fmt[i]) + { + case 'w': + if (XWINT (x, i) != XWINT (y, i)) + return 0; + break; + + case 'n': + case 'i': + if (XINT (x, i) != XINT (y, i)) + return 0; + break; + + case 'V': + case 'E': + /* Two vectors must have the same length. */ + if (XVECLEN (x, i) != XVECLEN (y, i)) + return 0; + + /* And the corresponding elements must match. */ + for (j = 0; j < XVECLEN (x, i); j++) + if (rtx_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0) + return 0; + break; + + case 'e': + if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0) + return 0; + break; + + case 'S': + case 's': + if (strcmp (XSTR (x, i), XSTR (y, i))) + return 0; + break; + + case 'u': + /* These are just backpointers, so they don't matter. */ + break; + + case '0': + break; + + /* It is believed that rtx's at this level will never + contain anything but integers and other rtx's, + except for within LABEL_REFs and SYMBOL_REFs. */ + default: + abort (); + } + } + return 1; +} + /* Helper function for purge_addressof. See if the rtx expression at *LOC in INSN needs to be changed. If FORCE, always put any ADDRESSOFs into the stack. */ @@ -3122,7 +3221,7 @@ for (tem = purge_bitfield_addressof_replacements; tem != NULL_RTX; tem = XEXP (XEXP (tem, 1), 1)) - if (rtx_equal_p (x, XEXP (tem, 0))) + if (rtx_equal_for_addressof_p (x, XEXP (tem, 0))) { *loc = XEXP (XEXP (tem, 1), 0); return; @@ -3132,7 +3231,7 @@ for (tem = purge_addressof_replacements; tem != NULL_RTX; tem = XEXP (XEXP (tem, 1), 1)) - if (rtx_equal_p (XEXP (x, 0), XEXP (tem, 0))) + if (rtx_equal_for_addressof_p (XEXP (x, 0), XEXP (tem, 0))) { rtx z = XEXP (XEXP (tem, 1), 0);