diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2012-12-01 22:54:03 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2012-12-01 22:54:03 +0000 |
commit | b02dfe0ab7aae6700f0c15419373891118eab134 (patch) | |
tree | 535b6d29222cbe7e3bb3fe3d6f9637f31e93face /gnu | |
parent | a06516e47e752c824b8c4c1a049b5e408d3ba696 (diff) |
reload_cse_noop_set_p(): invoking rtx_equal_for_cselib_p() is not enough; if
it reports the dest and source parts of the set insn are identical, we need
to check whether they are volatile memory references, and return 0 (not a
noop) in that case.
This allows `*volatile_ptr = *volatile_ptr;' constructs to no longer be
incorrectly optimized away on platforms which can perform memory to memory
transfers in a single instruction (i.e. m68k and vax).
Found the hard way on vax, where some systems need to frob the interrupt
stack early, before being able to handle faults, and a gcc3-built kernel
would have this operation optimized away, leading to a quick system reset.
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/usr.bin/gcc/gcc/reload1.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/gnu/usr.bin/gcc/gcc/reload1.c b/gnu/usr.bin/gcc/gcc/reload1.c index 5f8102c8821..2cc4c3f7150 100644 --- a/gnu/usr.bin/gcc/gcc/reload1.c +++ b/gnu/usr.bin/gcc/gcc/reload1.c @@ -8059,7 +8059,19 @@ static int reload_cse_noop_set_p (set) rtx set; { - return rtx_equal_for_cselib_p (SET_DEST (set), SET_SRC (set)); + rtx dest, src; + + dest = SET_DEST (set); + src = SET_SRC (set); + + if (! rtx_equal_for_cselib_p (dest, src)) + return 0; + + if ((GET_CODE (dest) == MEM && MEM_VOLATILE_P (dest)) + || (GET_CODE (src) == MEM && MEM_VOLATILE_P (src))) + return 0; + + return 1; } /* Try to simplify INSN. */ |