recog.c (verfiy_changes): Disallow renaming of hard regs in inline asms for register...
authorAndreas Krebbel <Andreas.Krebbel@de.ibm.com>
Mon, 9 Mar 2009 13:30:19 +0000 (13:30 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Mon, 9 Mar 2009 13:30:19 +0000 (13:30 +0000)
2009-03-09  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

* recog.c (verfiy_changes): Disallow renaming of hard regs in
inline asms for register asm ("") declarations.

2009-03-09  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

* gcc.target/s390/20090223-1.c: New testcase.

From-SVN: r144726

gcc/ChangeLog
gcc/recog.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/s390/20090223-1.c [new file with mode: 0644]

index 9ab8b72ee35c0206271267d10265e3c764103a1c..300507d9c05f7b1d1242b403a56bab9cd895b361 100644 (file)
@@ -1,3 +1,8 @@
+2009-03-09  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
+
+       * recog.c (verfiy_changes): Disallow renaming of hard regs in
+       inline asms for register asm ("") declarations.
+
 2009-03-09  Eric Botcazou  <ebotcazou@adacore.com>
 
        * fold-const.c (fold_unary): Fix comment.
index 7c22faec6ded8528f8f3d97f0d46a1e080253600..70370e3ad81619d4cc67c64fc4e1f70f5d80aff3 100644 (file)
@@ -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 135a0b4a1cbd66f6af4e74bfba1438eb67e8e771..0651163fb8cf51a6db4c79d64d8b7a5a494112a9 100644 (file)
@@ -1,3 +1,7 @@
+2009-03-09  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
+
+       * gcc.target/s390/20090223-1.c: New testcase.
+
 2009-03-08  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR libfortran/39402
diff --git a/gcc/testsuite/gcc.target/s390/20090223-1.c b/gcc/testsuite/gcc.target/s390/20090223-1.c
new file mode 100644 (file)
index 0000000..443ccb9
--- /dev/null
@@ -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;
+}