From 3f982e5a854b6cc6206628fc914ad3fa1a236b9d Mon Sep 17 00:00:00 2001 From: jakub Date: Tue, 12 Feb 2008 18:31:53 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@132263 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 ++++++ gcc/function.c | 18 +++++++++++++++++- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/gcc.target/i386/pr35160.c | 31 +++++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr35160.c 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 + + PR inline-asm/35160 + * function.c (match_asm_constraints_1): Don't replace the same input + multiple times. + 2008-02-12 Anatoly Sokolov * 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 + 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; +} -- 2.7.4