------- Comment #3 from kkojima at gcc dot gnu dot org  2006-08-23 04:35 -------
Here is a workaround.  Although it doesn't solve the issue
completely, it'd be better than nothing.  It prevents to
insert the mode switching code after the last insn of BB
when that insn has the REG_EH_REGION note.  It also checks
if the last insn needs a mode which doesn't match with
the mode given by the mode switching code in such case.

diff -uprN ORIG/trunk/gcc/mode-switching.c LOCAL/trunk/gcc/mode-switching.c
--- ORIG/trunk/gcc/mode-switching.c     2006-03-09 15:11:37.000000000 +0900
+++ LOCAL/trunk/gcc/mode-switching.c    2006-08-22 09:55:23.000000000 +0900
@@ -612,9 +612,11 @@ optimize_mode_switching (void)
                 of the previous block.  */
              if (eg->flags & EDGE_ABNORMAL)
                {
+                 rtx last = BB_END (src_bb);
+
                  emited = true;
-                 if (JUMP_P (BB_END (src_bb)))
-                   emit_insn_before (mode_set, BB_END (src_bb));
+                 if (JUMP_P (last))
+                   emit_insn_before (mode_set, last);
                  else
                    {
                      /* It doesn't make sense to switch to normal
@@ -629,8 +631,19 @@ optimize_mode_switching (void)
                         sense, anyway).  In the case of EH edges, EH
                         entry points also start in normal mode, so a
                         similar reasoning applies.  */
-                     gcc_assert (NONJUMP_INSN_P (BB_END (src_bb)));
-                     emit_insn_after (mode_set, BB_END (src_bb));
+                     gcc_assert (NONJUMP_INSN_P (last));
+                     /* We cannot insert instructions after the insn
+                        having a REG_EH_REGION note.  */
+                     if (find_reg_note (last, REG_EH_REGION, NULL_RTX))
+                       {
+                         gcc_assert ((MODE_NEEDED (entity_map[j], last)
+                                      == no_mode)
+                                     || (MODE_NEEDED (entity_map[j], last)
+                                         == mode));
+                         emit_insn_before (mode_set, last);
+                       }
+                     else
+                       emit_insn_after (mode_set, last);
                    }
                  bb_info[j][src_bb->index].computing = mode;
                  RESET_BIT (transp[src_bb->index], j);


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28764

Reply via email to