re PR inline-asm/6806 (gcc 3.0.4 ignoring clobbered registers in inline asm with...
authorRichard Henderson <rth@redhat.com>
Mon, 13 Sep 2004 09:05:31 +0000 (02:05 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Mon, 13 Sep 2004 09:05:31 +0000 (02:05 -0700)
        PR inline-asm/6806
        * cselib.c (cselib_invalidate_rtx): Export.  Remove unused args.
        (cselib_invalidate_rtx_note_stores): New.
        (cselib_record_sets, cselib_process_insn): Update to match.
        * cselib.h (cselib_invalidate_rtx): Declare.
        * postreload.c (reload_cse_simplify): Invalidate asm clobbers.

From-SVN: r87432

gcc/ChangeLog
gcc/cselib.c
gcc/cselib.h
gcc/postreload.c
gcc/testsuite/gcc.dg/i386-asm-3.c [new file with mode: 0644]

index 5e2bbef..6f63d50 100644 (file)
@@ -1,4 +1,13 @@
 2004-09-13  Richard Henderson  <rth@redhat.com>
+        PR inline-asm/6806
+        * cselib.c (cselib_invalidate_rtx): Export.  Remove unused args.
+        (cselib_invalidate_rtx_note_stores): New.
+        (cselib_record_sets, cselib_process_insn): Update to match.
+        * cselib.h (cselib_invalidate_rtx): Declare.
+        * postreload.c (reload_cse_simplify): Invalidate asm clobbers.
+
+2004-09-13  Richard Henderson  <rth@redhat.com>
 
        PR tree-opt/10528
        * tree-inline.c (copy_body_r): Recompute bits for ADDR_EXPR,
index aa92248..e58f254 100644 (file)
@@ -61,7 +61,6 @@ static void add_mem_for_addr (cselib_val *, cselib_val *, rtx);
 static cselib_val *cselib_lookup_mem (rtx, int);
 static void cselib_invalidate_regno (unsigned int, enum machine_mode);
 static void cselib_invalidate_mem (rtx);
-static void cselib_invalidate_rtx (rtx, rtx, void *);
 static void cselib_record_set (rtx, cselib_val *, cselib_val *);
 static void cselib_record_sets (rtx);
 
@@ -1141,13 +1140,10 @@ cselib_invalidate_mem (rtx mem_rtx)
   *vp = &dummy_val;
 }
 
-/* Invalidate DEST, which is being assigned to or clobbered.  The second and
-   the third parameter exist so that this function can be passed to
-   note_stores; they are ignored.  */
+/* Invalidate DEST, which is being assigned to or clobbered.  */
 
-static void
-cselib_invalidate_rtx (rtx dest, rtx ignore ATTRIBUTE_UNUSED,
-                      void *data ATTRIBUTE_UNUSED)
+void
+cselib_invalidate_rtx (rtx dest)
 {
   while (GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == SIGN_EXTRACT
         || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SUBREG)
@@ -1163,7 +1159,16 @@ cselib_invalidate_rtx (rtx dest, rtx ignore ATTRIBUTE_UNUSED,
      invalidate the stack pointer correctly.  Note that invalidating
      the stack pointer is different from invalidating DEST.  */
   if (push_operand (dest, GET_MODE (dest)))
-    cselib_invalidate_rtx (stack_pointer_rtx, NULL_RTX, NULL);
+    cselib_invalidate_rtx (stack_pointer_rtx);
+}
+
+/* A wrapper for cselib_invalidate_rtx to be called via note_stores.  */
+
+static void
+cselib_invalidate_rtx_note_stores (rtx dest, rtx ignore ATTRIBUTE_UNUSED,
+                                  void *data ATTRIBUTE_UNUSED)
+{
+  cselib_invalidate_rtx (dest);
 }
 
 /* Record the result of a SET instruction.  DEST is being set; the source
@@ -1296,7 +1301,7 @@ cselib_record_sets (rtx insn)
   /* Invalidate all locations written by this insn.  Note that the elts we
      looked up in the previous loop aren't affected, just some of their
      locations may go away.  */
-  note_stores (body, cselib_invalidate_rtx, NULL);
+  note_stores (body, cselib_invalidate_rtx_note_stores, NULL);
 
   /* If this is an asm, look for duplicate sets.  This can happen when the
      user uses the same value as an output multiple times.  This is valid
@@ -1384,7 +1389,7 @@ cselib_process_insn (rtx insn)
      unlikely to help.  */
   for (x = REG_NOTES (insn); x; x = XEXP (x, 1))
     if (REG_NOTE_KIND (x) == REG_INC)
-      cselib_invalidate_rtx (XEXP (x, 0), NULL_RTX, NULL);
+      cselib_invalidate_rtx (XEXP (x, 0));
 #endif
 
   /* Look for any CLOBBERs in CALL_INSN_FUNCTION_USAGE, but only
@@ -1392,7 +1397,7 @@ cselib_process_insn (rtx insn)
   if (CALL_P (insn))
     for (x = CALL_INSN_FUNCTION_USAGE (insn); x; x = XEXP (x, 1))
       if (GET_CODE (XEXP (x, 0)) == CLOBBER)
-       cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0), NULL_RTX, NULL);
+       cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0));
 
   cselib_current_insn = 0;
 
index b529060..1aff251 100644 (file)
@@ -70,3 +70,4 @@ extern enum machine_mode cselib_reg_set_mode (rtx);
 extern int rtx_equal_for_cselib_p (rtx, rtx);
 extern int references_value_p (rtx, int);
 extern rtx cselib_subst_to_values (rtx);
+extern void cselib_invalidate_rtx (rtx);
index 20d4a4f..2ff95b1 100644 (file)
@@ -118,6 +118,19 @@ reload_cse_simplify (rtx insn, rtx testreg)
       int count = 0;
       rtx value = NULL_RTX;
 
+      /* Registers mentioned in the clobber list for an asm cannot be reused
+        within the body of the asm.  Invalidate those registers now so that
+        we don't try to substitute values for them.  */
+      if (asm_noperands (body) >= 0)
+       {
+         for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
+           {
+             rtx part = XVECEXP (body, 0, i);
+             if (GET_CODE (part) == CLOBBER && REG_P (XEXP (part, 0)))
+               cselib_invalidate_rtx (XEXP (part, 0));
+           }
+       }
+
       /* If every action in a PARALLEL is a noop, we can delete
         the entire PARALLEL.  */
       for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
diff --git a/gcc/testsuite/gcc.dg/i386-asm-3.c b/gcc/testsuite/gcc.dg/i386-asm-3.c
new file mode 100644 (file)
index 0000000..f60f7d6
--- /dev/null
@@ -0,0 +1,34 @@
+/* PR inline-asm/6806 */
+/* { dg-do run { target i?86-*-* } } */
+/* { dg-options "-O2" } */
+
+extern void abort (void);
+
+volatile int out = 1;
+volatile int a = 2;
+volatile int b = 4;
+volatile int c = 8;
+volatile int d = 16;
+volatile int e = 32;
+volatile int f = 64;
+
+int
+main ()
+{
+  asm volatile ("xorl %%eax, %%eax     \n\t"
+               "xorl %%esi, %%esi      \n\t"
+               "addl %1, %0            \n\t"
+               "addl %2, %0            \n\t"
+               "addl %3, %0            \n\t"
+               "addl %4, %0            \n\t"
+               "addl %5, %0            \n\t"
+               "addl %6, %0"
+               : "+r" (out)
+               : "r" (a), "r" (b), "r" (c), "g" (d), "g" (e), "g" (f)
+               : "%eax", "%esi");
+
+  if (out != 127)
+    abort ();
+
+  return 0;
+}