This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PING] recog: Disallow changes in asms for reg asm ("x") operands


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;
> +}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]