This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
fix inline-asm/6806
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 13 Sep 2004 02:10:19 -0700
- Subject: 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)