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> 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 PR tree-opt/10528
* tree-inline.c (copy_body_r): Recompute bits for ADDR_EXPR, * 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); ...@@ -61,7 +61,6 @@ static void add_mem_for_addr (cselib_val *, cselib_val *, rtx);
static cselib_val *cselib_lookup_mem (rtx, int); static cselib_val *cselib_lookup_mem (rtx, int);
static void cselib_invalidate_regno (unsigned int, enum machine_mode); static void cselib_invalidate_regno (unsigned int, enum machine_mode);
static void cselib_invalidate_mem (rtx); 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_set (rtx, cselib_val *, cselib_val *);
static void cselib_record_sets (rtx); static void cselib_record_sets (rtx);
...@@ -1141,13 +1140,10 @@ cselib_invalidate_mem (rtx mem_rtx) ...@@ -1141,13 +1140,10 @@ cselib_invalidate_mem (rtx mem_rtx)
*vp = &dummy_val; *vp = &dummy_val;
} }
/* Invalidate DEST, which is being assigned to or clobbered. The second and /* Invalidate DEST, which is being assigned to or clobbered. */
the third parameter exist so that this function can be passed to
note_stores; they are ignored. */
static void void
cselib_invalidate_rtx (rtx dest, rtx ignore ATTRIBUTE_UNUSED, cselib_invalidate_rtx (rtx dest)
void *data ATTRIBUTE_UNUSED)
{ {
while (GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == SIGN_EXTRACT while (GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == SIGN_EXTRACT
|| GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SUBREG) || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SUBREG)
...@@ -1163,7 +1159,16 @@ cselib_invalidate_rtx (rtx dest, rtx ignore ATTRIBUTE_UNUSED, ...@@ -1163,7 +1159,16 @@ cselib_invalidate_rtx (rtx dest, rtx ignore ATTRIBUTE_UNUSED,
invalidate the stack pointer correctly. Note that invalidating invalidate the stack pointer correctly. Note that invalidating
the stack pointer is different from invalidating DEST. */ the stack pointer is different from invalidating DEST. */
if (push_operand (dest, GET_MODE (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 /* Record the result of a SET instruction. DEST is being set; the source
...@@ -1296,7 +1301,7 @@ cselib_record_sets (rtx insn) ...@@ -1296,7 +1301,7 @@ cselib_record_sets (rtx insn)
/* Invalidate all locations written by this insn. Note that the elts we /* 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 looked up in the previous loop aren't affected, just some of their
locations may go away. */ 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 /* 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 user uses the same value as an output multiple times. This is valid
...@@ -1384,7 +1389,7 @@ cselib_process_insn (rtx insn) ...@@ -1384,7 +1389,7 @@ cselib_process_insn (rtx insn)
unlikely to help. */ unlikely to help. */
for (x = REG_NOTES (insn); x; x = XEXP (x, 1)) for (x = REG_NOTES (insn); x; x = XEXP (x, 1))
if (REG_NOTE_KIND (x) == REG_INC) if (REG_NOTE_KIND (x) == REG_INC)
cselib_invalidate_rtx (XEXP (x, 0), NULL_RTX, NULL); cselib_invalidate_rtx (XEXP (x, 0));
#endif #endif
/* Look for any CLOBBERs in CALL_INSN_FUNCTION_USAGE, but only /* Look for any CLOBBERs in CALL_INSN_FUNCTION_USAGE, but only
...@@ -1392,7 +1397,7 @@ cselib_process_insn (rtx insn) ...@@ -1392,7 +1397,7 @@ cselib_process_insn (rtx insn)
if (CALL_P (insn)) if (CALL_P (insn))
for (x = CALL_INSN_FUNCTION_USAGE (insn); x; x = XEXP (x, 1)) for (x = CALL_INSN_FUNCTION_USAGE (insn); x; x = XEXP (x, 1))
if (GET_CODE (XEXP (x, 0)) == CLOBBER) 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; cselib_current_insn = 0;
......
...@@ -70,3 +70,4 @@ extern enum machine_mode cselib_reg_set_mode (rtx); ...@@ -70,3 +70,4 @@ extern enum machine_mode cselib_reg_set_mode (rtx);
extern int rtx_equal_for_cselib_p (rtx, rtx); extern int rtx_equal_for_cselib_p (rtx, rtx);
extern int references_value_p (rtx, int); extern int references_value_p (rtx, int);
extern rtx cselib_subst_to_values (rtx); extern rtx cselib_subst_to_values (rtx);
extern void cselib_invalidate_rtx (rtx);
...@@ -118,6 +118,19 @@ reload_cse_simplify (rtx insn, rtx testreg) ...@@ -118,6 +118,19 @@ reload_cse_simplify (rtx insn, rtx testreg)
int count = 0; int count = 0;
rtx value = NULL_RTX; 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 /* If every action in a PARALLEL is a noop, we can delete
the entire PARALLEL. */ the entire PARALLEL. */
for (i = XVECLEN (body, 0) - 1; i >= 0; --i) 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