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

H.J. Lu hjl.tools@gmail.com
Mon Mar 9 13:55:00 GMT 2009


On Mon, Mar 9, 2009 at 4:32 AM, Andreas Krebbel
<krebbel@linux.vnet.ibm.com> wrote:
> Hi,
>
> could anyone please have a look at that one.

It has been approved by Ian:

http://gcc.gnu.org/ml/gcc-patches/2009-03/msg00113.html

H.J.
----
> 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;
>> +}
>



-- 
H.J.



More information about the Gcc-patches mailing list