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]

fix inline-asm/6806


As diagnosed by me -- and apparently forgotten -- in 2002 against
gcc 3.1, reload inheritence was failing to take into account the
asm clobbers.  They would be processed by cselib_process_insn for
subsequent instructions, but would not be honored wrt overlap with
the asm inputs.

Test case in gcc.dg/i386-asm-3.c.

Bootstrapped and tested on i686-linux.  Applied to 3.3 and beyond.


r~


        * 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.

Index: cselib.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cselib.c,v
retrieving revision 1.51
diff -u -p -r1.51 cselib.c
--- cselib.c	7 Sep 2004 15:46:53 -0000	1.51
+++ cselib.c	13 Sep 2004 04:34:55 -0000
@@ -61,7 +61,6 @@ static void add_mem_for_addr (cselib_val
 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 ign
      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: cselib.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cselib.h,v
retrieving revision 1.15
diff -u -p -r1.15 cselib.h
--- cselib.h	22 Apr 2004 17:47:47 -0000	1.15
+++ cselib.h	13 Sep 2004 04:34:55 -0000
@@ -70,3 +70,4 @@ extern enum machine_mode cselib_reg_set_
 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: postreload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/postreload.c,v
retrieving revision 2.22
diff -u -p -r2.22 postreload.c
--- postreload.c	10 Sep 2004 11:02:25 -0000	2.22
+++ postreload.c	13 Sep 2004 04:34:55 -0000
@@ -118,6 +118,19 @@ reload_cse_simplify (rtx insn, rtx testr
       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)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]