Commit 0d87c765 by Richard Henderson Committed by Richard Henderson

re PR inline-asm/6806 (gcc 3.0.4 ignoring clobbered registers in inline asm with…

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
parent ddef210a
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,
......
......@@ -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;
......
......@@ -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);
......@@ -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)
......
/* 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment