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
This commit is contained in:
parent
ddef210a89
commit
0d87c76525
@ -1,3 +1,12 @@
|
||||
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
|
||||
|
27
gcc/cselib.c
27
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;
|
||||
|
||||
|
@ -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)
|
||||
|
34
gcc/testsuite/gcc.dg/i386-asm-3.c
Normal file
34
gcc/testsuite/gcc.dg/i386-asm-3.c
Normal file
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user