From: Richard Henderson Date: Mon, 13 Sep 2004 08:54:35 +0000 (-0700) Subject: re PR inline-asm/6806 (gcc 3.0.4 ignoring clobbered registers in inline asm with... X-Git-Tag: releases/gcc-3.3.5~24 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=95e28cde5d619def465e86076d3fe1e3e8cec308;p=thirdparty%2Fgcc.git re PR inline-asm/6806 (gcc 3.0.4 ignoring clobbered registers in inline asm with -O1 or higher on i386) PR inline-asm/6806 * cselib.c (cselib_invalidate_rtx): Export. Remove unused args. (cselib_invalidate_rtx_note_stores): New. (cselib_record_sets, cselib_process_insn): Update to match. * cselib.h (cselib_invalidate_rtx): Declare. * reload1.c (reload_cse_simplify): Invalidate asm clobbers. From-SVN: r87431 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0c6e38905821..05cb309f57cf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,13 @@ -2003-08-29 Jonathan Wakely +2004-09-13 Richard Henderson + + PR inline-asm/6806 + * cselib.c (cselib_invalidate_rtx): Export. Remove unused args. + (cselib_invalidate_rtx_note_stores): New. + (cselib_record_sets, cselib_process_insn): Update to match. + * cselib.h (cselib_invalidate_rtx): Declare. + * reload1.c (reload_cse_simplify): Invalidate asm clobbers. + +2004-08-29 Jonathan Wakely * doc/trouble.texi (C++ misunderstandings): Fix example code. diff --git a/gcc/cselib.c b/gcc/cselib.c index e3b228cc27d4..d88c6386bf73 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -63,7 +63,7 @@ static void cselib_invalidate_regno PARAMS ((unsigned int, static int cselib_mem_conflict_p PARAMS ((rtx, rtx)); static int cselib_invalidate_mem_1 PARAMS ((void **, void *)); static void cselib_invalidate_mem PARAMS ((rtx)); -static void cselib_invalidate_rtx PARAMS ((rtx, rtx, void *)); +static void cselib_invalidate_rtx_note_stores PARAMS ((rtx, rtx, void *)); static void cselib_record_set PARAMS ((rtx, cselib_val *, cselib_val *)); static void cselib_record_sets PARAMS ((rtx)); @@ -1143,15 +1143,11 @@ cselib_invalidate_mem (mem_rtx) htab_traverse (hash_table, cselib_invalidate_mem_1, mem_rtx); } -/* Invalidate DEST, which is being assigned to or clobbered. The second and - the third parameter exist so that this function can be passed to - note_stores; they are ignored. */ +/* Invalidate DEST, which is being assigned to or clobbered. */ -static void -cselib_invalidate_rtx (dest, ignore, data) +void +cselib_invalidate_rtx (dest) rtx dest; - rtx ignore ATTRIBUTE_UNUSED; - void *data ATTRIBUTE_UNUSED; { while (GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == SIGN_EXTRACT || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SUBREG) @@ -1167,7 +1163,18 @@ cselib_invalidate_rtx (dest, ignore, data) invalidate the stack pointer correctly. Note that invalidating the stack pointer is different from invalidating DEST. */ if (push_operand (dest, GET_MODE (dest))) - cselib_invalidate_rtx (stack_pointer_rtx, NULL_RTX, NULL); + cselib_invalidate_rtx (stack_pointer_rtx); +} + +/* A wrapper for cselib_invalidate_rtx to be called via note_stores. */ + +static void +cselib_invalidate_rtx_note_stores (dest, ignore, data) + rtx dest; + rtx ignore ATTRIBUTE_UNUSED; + void *data ATTRIBUTE_UNUSED; +{ + cselib_invalidate_rtx (dest); } /* Record the result of a SET instruction. DEST is being set; the source @@ -1293,7 +1300,7 @@ cselib_record_sets (insn) /* Invalidate all locations written by this insn. Note that the elts we looked up in the previous loop aren't affected, just some of their locations may go away. */ - note_stores (body, cselib_invalidate_rtx, NULL); + note_stores (body, cselib_invalidate_rtx_note_stores, NULL); /* Now enter the equivalences in our tables. */ for (i = 0; i < n_sets; i++) @@ -1358,7 +1365,7 @@ cselib_process_insn (insn) unlikely to help. */ for (x = REG_NOTES (insn); x; x = XEXP (x, 1)) if (REG_NOTE_KIND (x) == REG_INC) - cselib_invalidate_rtx (XEXP (x, 0), NULL_RTX, NULL); + cselib_invalidate_rtx (XEXP (x, 0)); #endif /* Look for any CLOBBERs in CALL_INSN_FUNCTION_USAGE, but only @@ -1366,7 +1373,7 @@ cselib_process_insn (insn) if (GET_CODE (insn) == CALL_INSN) for (x = CALL_INSN_FUNCTION_USAGE (insn); x; x = XEXP (x, 1)) if (GET_CODE (XEXP (x, 0)) == CLOBBER) - cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0), NULL_RTX, NULL); + cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0)); cselib_current_insn = 0; diff --git a/gcc/cselib.h b/gcc/cselib.h index f29ee8de04e8..877d80401dc8 100644 --- a/gcc/cselib.h +++ b/gcc/cselib.h @@ -68,3 +68,4 @@ extern void cselib_process_insn PARAMS ((rtx)); extern int rtx_equal_for_cselib_p PARAMS ((rtx, rtx)); extern int references_value_p PARAMS ((rtx, int)); extern rtx cselib_subst_to_values PARAMS ((rtx)); +extern void cselib_invalidate_rtx PARAMS ((rtx)); diff --git a/gcc/reload1.c b/gcc/reload1.c index c747ddf7297d..81c3fb6a8ced 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -8085,6 +8085,19 @@ reload_cse_simplify (insn, testreg) int count = 0; rtx value = NULL_RTX; + /* Registers mentioned in the clobber list for an asm cannot be reused + within the body of the asm. Invalidate those registers now so that + we don't try to substitute values for them. */ + if (asm_noperands (body) >= 0) + { + for (i = XVECLEN (body, 0) - 1; i >= 0; --i) + { + rtx part = XVECEXP (body, 0, i); + if (GET_CODE (part) == CLOBBER && REG_P (XEXP (part, 0))) + cselib_invalidate_rtx (XEXP (part, 0)); + } + } + /* If every action in a PARALLEL is a noop, we can delete the entire PARALLEL. */ for (i = XVECLEN (body, 0) - 1; i >= 0; --i)