diff options
author | Jakub Jelinek <jakub@redhat.com> | 2008-02-12 19:31:53 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2008-02-12 19:31:53 +0100 |
commit | d7b8033f3e4f59d5ff54ab68fe5667467a52a273 (patch) | |
tree | cc86a9d5f9cae1c352e371479313945266e39ca9 /gcc/function.c | |
parent | 2e250fa218c90851d585ee46240201fcdec857f9 (diff) | |
download | gcc-d7b8033f3e4f59d5ff54ab68fe5667467a52a273.zip gcc-d7b8033f3e4f59d5ff54ab68fe5667467a52a273.tar.gz gcc-d7b8033f3e4f59d5ff54ab68fe5667467a52a273.tar.bz2 |
re PR inline-asm/35160 (local-alloc introduces sharing of the same pseudo/hard reg between different output regs in inline asm)
PR inline-asm/35160
* function.c (match_asm_constraints_1): Don't replace the same input
multiple times.
* gcc.target/i386/pr35160.c: New test.
From-SVN: r132263
Diffstat (limited to 'gcc/function.c')
-rw-r--r-- | gcc/function.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/gcc/function.c b/gcc/function.c index 401bb21..514d1a6 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -1,6 +1,6 @@ /* Expands front end tree to back end RTL for GCC. Copyright (C) 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, - 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 + 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of GCC. @@ -5683,7 +5683,9 @@ match_asm_constraints_1 (rtx insn, rtx *p_sets, int noutputs) rtx op = SET_SRC (p_sets[0]); int ninputs = ASM_OPERANDS_INPUT_LENGTH (op); rtvec inputs = ASM_OPERANDS_INPUT_VEC (op); + bool *output_matched = alloca (noutputs * sizeof (bool)); + memset (output_matched, 0, noutputs * sizeof (bool)); for (i = 0; i < ninputs; i++) { rtx input, output, insns; @@ -5713,6 +5715,20 @@ match_asm_constraints_1 (rtx insn, rtx *p_sets, int noutputs) if (j != ninputs) continue; + /* Avoid changing the same input several times. For + asm ("" : "=mr" (out1), "=mr" (out2) : "0" (in), "1" (in)); + only change in once (to out1), rather than changing it + first to out1 and afterwards to out2. */ + if (i > 0) + { + for (j = 0; j < noutputs; j++) + if (output_matched[j] && input == SET_DEST (p_sets[j])) + break; + if (j != noutputs) + continue; + } + output_matched[match] = true; + start_sequence (); emit_move_insn (output, input); insns = get_insns (); |