[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