aboutsummaryrefslogtreecommitdiff
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
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/function.c18
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.target/i386/pr35160.c31
4 files changed, 57 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e7eca81..553f349 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2008-02-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR inline-asm/35160
+ * function.c (match_asm_constraints_1): Don't replace the same input
+ multiple times.
+
2008-02-12 Anatoly Sokolov <aesok@post.ru>
* config/avr/avr.h (AVR_HAVE_RAMPZ): Define.
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 ();
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 091bb28..40c0ba2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2008-02-12 Jakub Jelinek <jakub@redhat.com>
+ PR inline-asm/35160
+ * gcc.target/i386/pr35160.c: New test.
+
PR c++/34862
* g++.dg/init/new27.C: New test.
diff --git a/gcc/testsuite/gcc.target/i386/pr35160.c b/gcc/testsuite/gcc.target/i386/pr35160.c
new file mode 100644
index 0000000..587b846
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr35160.c
@@ -0,0 +1,31 @@
+/* PR inline-asm/35160 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+extern void abort (void);
+
+void
+__attribute__((noinline))
+foo (unsigned int *y)
+{
+ unsigned int c0, c1, c2, d0, d1, d2;
+ d0 = 0; d1 = 0; d2 = 0; c0 = c1 = c2 = 0;
+
+ __asm__ ("movl $7, %k0; movl $8, %k1; movl $9, %k2"
+ : "+r" (d0), "+r" (d1), "+r" (d2));
+ __asm__ ("movl %3, %0; movl %4, %1; movl %5, %2"
+ : "+r" (c0), "+r" (c1), "+r" (c2), "+r" (d0), "+r" (d1), "+r" (d2));
+ y[0] = c0;
+ y[1] = c1;
+ y[2] = c2;
+}
+
+int
+main (void)
+{
+ unsigned int y[3];
+ foo (y);
+ if (y[0] != 7 || y[1] != 8 || y[2] != 9)
+ abort ();
+ return 0;
+}