diff options
author | Jeff Law <law@redhat.com> | 2005-04-20 12:02:40 -0600 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2005-04-20 12:02:40 -0600 |
commit | ad1032fd92e96960ecf2efd0ca26f7c1899a2bd9 (patch) | |
tree | c23d3cf2e1d3a9964cbe98f26ed40c908b4fafc9 /gcc/reload1.c | |
parent | 187230a795716fc0d98cb066402fe9d71639996c (diff) | |
download | gcc-ad1032fd92e96960ecf2efd0ca26f7c1899a2bd9.tar.gz |
reload1.c (reload): Ignore equivalences between pseudos and read only memory.
* reload1.c (reload): Ignore equivalences between pseudos and
read only memory.
From-SVN: r98466
Diffstat (limited to 'gcc/reload1.c')
-rw-r--r-- | gcc/reload1.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/gcc/reload1.c b/gcc/reload1.c index 5e1ab1a27cc..b2200a8d3b3 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -740,8 +740,20 @@ reload (rtx first, int global) that is not a legitimate memory operand. As later stages of reload assume that all addresses found in the reg_equiv_* arrays were originally legitimate, - we ignore such REG_EQUIV notes. */ - if (memory_operand (x, VOIDmode)) + + It can also happen that a REG_EQUIV note contains a + readonly memory location. If the destination pseudo + is set from some other value (typically a different + pseudo), and the destination pseudo does not get a + hard reg, then reload will replace the destination + pseudo with its equivalent memory location. This + is horribly bad as it creates a store to a readonly + memory location and a runtime segfault. To avoid + this problem we reject readonly memory locations + for equivalences. This is overly conservative as + we could find all sets of the destination pseudo + and remove them as they should be redundant. */ + if (memory_operand (x, VOIDmode) && ! MEM_READONLY_P (x)) { /* Always unshare the equivalence, so we can substitute into this insn without touching the |