aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2004-09-13 02:05:31 -0700
committerRichard Henderson <rth@gcc.gnu.org>2004-09-13 02:05:31 -0700
commit0d87c765251e8619f4eb86894bdcf109367d0274 (patch)
treec07f98b7d57da963ba6c6d9edd7cb156910bc1e4 /gcc
parentddef210a8919486d2d9f9b65c914435a39b21060 (diff)
downloadgcc-0d87c765251e8619f4eb86894bdcf109367d0274.zip
gcc-0d87c765251e8619f4eb86894bdcf109367d0274.tar.gz
gcc-0d87c765251e8619f4eb86894bdcf109367d0274.tar.bz2
re PR inline-asm/6806 (gcc 3.0.4 ignoring clobbered registers in inline asm with -O1 or higher on i386)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/cselib.c27
-rw-r--r--gcc/cselib.h1
-rw-r--r--gcc/postreload.c13
-rw-r--r--gcc/testsuite/gcc.dg/i386-asm-3.c34
5 files changed, 73 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5e2bbef..6f63d50 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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,
diff --git a/gcc/cselib.c b/gcc/cselib.c
index aa92248..e58f2541 100644
--- a/gcc/cselib.c
+++ b/gcc/cselib.c
@@ -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;
diff --git a/gcc/cselib.h b/gcc/cselib.h
index b529060..1aff251 100644
--- a/gcc/cselib.h
+++ b/gcc/cselib.h
@@ -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);
diff --git a/gcc/postreload.c b/gcc/postreload.c
index 20d4a4f..2ff95b1 100644
--- a/gcc/postreload.c
+++ b/gcc/postreload.c
@@ -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
index 0000000..f60f7d6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/i386-asm-3.c
@@ -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;
+}