aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernd Schmidt <bernds@codesourcery.com>2010-08-02 20:17:59 +0000
committerBernd Schmidt <bernds@gcc.gnu.org>2010-08-02 20:17:59 +0000
commit14292418cbbeec96857d8920e66e43038f0f3194 (patch)
tree0ffc9ab78ee641e805a69ce10d99a3c7d5a26661
parentfea8c257250f4535a05716673597577fe3a7a605 (diff)
downloadgcc-14292418cbbeec96857d8920e66e43038f0f3194.zip
gcc-14292418cbbeec96857d8920e66e43038f0f3194.tar.gz
gcc-14292418cbbeec96857d8920e66e43038f0f3194.tar.bz2
re PR target/45063 (ICE: Segmentation fault (cc1) compiling matmul_i1.c)
PR target/45063 * caller-save.c (save_call_clobbered_regs): Remove regs from hard_regs_saved when they are set. From-SVN: r162828
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/caller-save.c13
2 files changed, 18 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c37e93d..5bdb9de 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2010-08-02 Bernd Schmidt <bernds@codesourcery.com>
+
+ PR target/45063
+ * caller-save.c (save_call_clobbered_regs): Remove regs from
+ hard_regs_saved when they are set.
+
2010-08-02 Uros Bizjak <ubizjak@gmail.com>
PR target/41089
diff --git a/gcc/caller-save.c b/gcc/caller-save.c
index af9b2da..60c4747 100644
--- a/gcc/caller-save.c
+++ b/gcc/caller-save.c
@@ -763,6 +763,7 @@ save_call_clobbered_regs (void)
if (n_regs_saved)
{
int regno;
+ HARD_REG_SET this_insn_sets;
if (code == JUMP_INSN)
/* Restore all registers if this is a JUMP_INSN. */
@@ -777,7 +778,17 @@ save_call_clobbered_regs (void)
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (TEST_HARD_REG_BIT (referenced_regs, regno))
- regno += insert_restore (chain, 1, regno, MOVE_MAX_WORDS, save_mode);
+ regno += insert_restore (chain, 1, regno, MOVE_MAX_WORDS,
+ save_mode);
+ /* If a saved register is set after the call, this means we no
+ longer should restore it. This can happen when parts of a
+ multi-word pseudo do not conflict with other pseudos, so
+ IRA may allocate the same hard register for both. One may
+ be live across the call, while the other is set
+ afterwards. */
+ CLEAR_HARD_REG_SET (this_insn_sets);
+ note_stores (PATTERN (insn), mark_set_regs, &this_insn_sets);
+ AND_COMPL_HARD_REG_SET (hard_regs_saved, this_insn_sets);
}
if (code == CALL_INSN