From 929b7fc3c0afc5d5154ce9e40371a42a0610fd7f Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Mon, 9 Mar 2009 13:30:19 +0000 Subject: [PATCH] recog.c (verfiy_changes): Disallow renaming of hard regs in inline asms for register asm ("") declarations. 2009-03-09 Andreas Krebbel * recog.c (verfiy_changes): Disallow renaming of hard regs in inline asms for register asm ("") declarations. 2009-03-09 Andreas Krebbel * gcc.target/s390/20090223-1.c: New testcase. From-SVN: r144726 --- gcc/ChangeLog | 5 ++ gcc/recog.c | 10 ++++ gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.target/s390/20090223-1.c | 60 ++++++++++++++++++++++ 4 files changed, 79 insertions(+) create mode 100644 gcc/testsuite/gcc.target/s390/20090223-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9ab8b72ee35..300507d9c05 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2009-03-09 Andreas Krebbel + + * recog.c (verfiy_changes): Disallow renaming of hard regs in + inline asms for register asm ("") declarations. + 2009-03-09 Eric Botcazou * fold-const.c (fold_unary): Fix comment. diff --git a/gcc/recog.c b/gcc/recog.c index 7c22faec6de..70370e3ad81 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -379,6 +379,16 @@ verify_changes (int num) if (! memory_address_p (GET_MODE (object), XEXP (object, 0))) break; } + else if (REG_P (changes[i].old) + && asm_noperands (PATTERN (object)) > 0 + && REG_EXPR (changes[i].old) != NULL_TREE + && DECL_ASSEMBLER_NAME_SET_P (REG_EXPR (changes[i].old)) + && DECL_REGISTER (REG_EXPR (changes[i].old))) + { + /* Don't allow changes of hard register operands to inline + assemblies if they have been defined as register asm ("x"). */ + break; + } else if (insn_invalid_p (object)) { rtx pat = PATTERN (object); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 135a0b4a1cb..0651163fb8c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2009-03-09 Andreas Krebbel + + * gcc.target/s390/20090223-1.c: New testcase. + 2009-03-08 Jerry DeLisle PR libfortran/39402 diff --git a/gcc/testsuite/gcc.target/s390/20090223-1.c b/gcc/testsuite/gcc.target/s390/20090223-1.c new file mode 100644 index 00000000000..443ccb9aa69 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/20090223-1.c @@ -0,0 +1,60 @@ +/* The RTL loop optimizer used to replace the output register of the + inline assembly with a pseudo although the variable is declared as + register asm ("0"). */ + +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +extern void abort (void); + +static unsigned char __attribute__ ((always_inline)) +mytoupper (unsigned char c) +{ + if (c >= 'a' && c <= 'z') + c -= 'a' - 'A'; + return c; +} + +static unsigned long __attribute__ ((always_inline)) +strlen (const char *s) +{ + register unsigned long r0 asm ("0"); + const char *tmp = s; + + asm ( +#ifdef __s390x__ + " lghi %0, 0\n" +#else + " lhi %0, 0\n" +#endif + "0:srst %0,%1\n" + " jo 0b" + : "=d" (r0), "+a" (tmp) + : + :"cc"); + return r0 - (unsigned long) s; +} + +char boot_command_line[] = "this is a test"; + +void __attribute__ ((noinline)) +foo (char *str) +{ + if (strcmp (str, "THIS IS A TEST") != 0) + abort (); +} + +int +main () +{ + char upper_command_line[1024]; + int i; + + for (i = 0; i < strlen (boot_command_line); i++) + upper_command_line[i] = mytoupper (boot_command_line[i]); + + upper_command_line[strlen (boot_command_line)] = 0; + foo (upper_command_line); + + return 0; +} -- 2.30.2