diff options
author | 2012-12-01 22:54:02 +0000 | |
---|---|---|
committer | 2012-12-01 22:54:02 +0000 | |
commit | e37ff515a253919717bf5f41c0f640bfef960c50 (patch) | |
tree | 45b4df36f6b1dfa8204ce39bfae03f9591640729 | |
parent | Crank boot blocks version because of the compiler change. (diff) | |
download | wireguard-openbsd-e37ff515a253919717bf5f41c0f640bfef960c50.tar.xz wireguard-openbsd-e37ff515a253919717bf5f41c0f640bfef960c50.zip |
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.
-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. */ |