This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PING] recog: Disallow changes in asms for reg asm ("x") operands
- From: "Andreas Krebbel" <krebbel at linux dot vnet dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 9 Mar 2009 12:32:25 +0100
- Subject: [PING] recog: Disallow changes in asms for reg asm ("x") operands
- References: <20090223154342.GA10350@bart>
Hi,
could anyone please have a look at that one.
Bye,
-Andreas-
On Mon, Feb 23, 2009 at 04:43:42PM +0100, Andreas Krebbel wrote:
> Hi,
>
> in the attached testcase RTL loop invariant motion replaces the output
> register of the inline assembly with a pseudo. I don't think this is a
> valid change since the register asm("0") definition of r0 should be
> binding for the inline assembly.
>
> The attached patch adds a check to verify_changes which prevents such
> changes from being done when the respective declaration requires a
> specific hard reg.
>
> This fixes the testcase which is currently failing on s390 and s390x.
>
> Bootstrapped on s390 and s390x - x86_64 still running.
>
> Ok for mainline - given the x86_64 is clean?
>
> Bye,
>
> -Andreas-
>
>
> 2009-02-23 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
>
> * recog.c (verfiy_changes): Disallow renaming of hard regs in
> inline asms for register asm ("") declarations.
>
>
> 2009-02-23 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
>
> * gcc.target/s390/20090223-1.c: New testcase.
>
>
> Index: gcc/gcc/recog.c
> ===================================================================
> --- gcc.orig/gcc/recog.c
> +++ gcc/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);
> Index: gcc/gcc/testsuite/gcc.target/s390/20090223-1.c
> ===================================================================
> --- /dev/null
> +++ gcc/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;
> +}