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]

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


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]