]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/45063 (ICE: Segmentation fault (cc1) compiling matmul_i1.c)
authorBernd Schmidt <bernds@codesourcery.com>
Mon, 2 Aug 2010 20:17:59 +0000 (20:17 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Mon, 2 Aug 2010 20:17:59 +0000 (20:17 +0000)
PR target/45063
* caller-save.c (save_call_clobbered_regs): Remove regs from
hard_regs_saved when they are set.

From-SVN: r162828

gcc/ChangeLog
gcc/caller-save.c

index c37e93d3e13d56f9f84a29d9409a880e6464e35e..5bdb9deb1ebbc8eb60fda875695e36836c58665d 100644 (file)
@@ -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
index af9b2da8975bd2f4f15c5c20ee116421d0ecdf3f..60c47477e89e2df0bfdd8cfdf0bd9dd8dc92c2a8 100644 (file)
@@ -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