aboutsummaryrefslogtreecommitdiff
path: root/gcc/function.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2008-02-12 19:31:53 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2008-02-12 19:31:53 +0100
commitd7b8033f3e4f59d5ff54ab68fe5667467a52a273 (patch)
treecc86a9d5f9cae1c352e371479313945266e39ca9 /gcc/function.c
parent2e250fa218c90851d585ee46240201fcdec857f9 (diff)
downloadgcc-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.c18
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 ();