re PR middle-end/60175 (ICE on gcc.dg/asan/nosanitize-and-inline.c)
authorJakub Jelinek <jakub@redhat.com>
Mon, 3 Mar 2014 07:25:50 +0000 (08:25 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 3 Mar 2014 07:25:50 +0000 (08:25 +0100)
PR middle-end/60175
* function.c (expand_function_end): Don't emit
clobber_return_register sequence if clobber_after is a BARRIER.
* cfgexpand.c (construct_exit_block): Append instructions before
return_label to prev_bb.

From-SVN: r208267

gcc/ChangeLog
gcc/cfgexpand.c
gcc/function.c

index 9acf6ec667983c6eda83ce92d46a4e3dad9d27e3..93effc9fae23846dc128b540138c8bff7fc1da6c 100644 (file)
@@ -1,3 +1,11 @@
+2014-03-03  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/60175
+       * function.c (expand_function_end): Don't emit
+       clobber_return_register sequence if clobber_after is a BARRIER.
+       * cfgexpand.c (construct_exit_block): Append instructions before
+       return_label to prev_bb.
+
 2014-03-02  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
 
        * config/rs6000/constraints.md: Document reserved use of "wc".
index 06d494c3d9211e23ad7f0e11a24838ee32a6de81..5c23b72ee7dbb15f5aa6ad6921ee6f8bd063d943 100644 (file)
@@ -5273,7 +5273,8 @@ construct_exit_block (void)
   edge e, e2;
   unsigned ix;
   edge_iterator ei;
-  rtx orig_end = BB_END (EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb);
+  basic_block prev_bb = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb;
+  rtx orig_end = BB_END (prev_bb);
 
   rtl_profile_for_bb (EXIT_BLOCK_PTR_FOR_FN (cfun));
 
@@ -5288,13 +5289,25 @@ construct_exit_block (void)
   end = get_last_insn ();
   if (head == end)
     return;
-  /* While emitting the function end we could move end of the last basic block.
-   */
-  BB_END (EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb) = orig_end;
+  /* While emitting the function end we could move end of the last basic
+     block.  */
+  BB_END (prev_bb) = orig_end;
   while (NEXT_INSN (head) && NOTE_P (NEXT_INSN (head)))
     head = NEXT_INSN (head);
-  exit_block = create_basic_block (NEXT_INSN (head), end,
-                                  EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb);
+  /* But make sure exit_block starts with RETURN_LABEL, otherwise the
+     bb frequency counting will be confused.  Any instructions before that
+     label are emitted for the case where PREV_BB falls through into the
+     exit block, so append those instructions to prev_bb in that case.  */
+  if (NEXT_INSN (head) != return_label)
+    {
+      while (NEXT_INSN (head) != return_label)
+       {
+         if (!NOTE_P (NEXT_INSN (head)))
+           BB_END (prev_bb) = NEXT_INSN (head);
+         head = NEXT_INSN (head);
+       }
+    }
+  exit_block = create_basic_block (NEXT_INSN (head), end, prev_bb);
   exit_block->frequency = EXIT_BLOCK_PTR_FOR_FN (cfun)->frequency;
   exit_block->count = EXIT_BLOCK_PTR_FOR_FN (cfun)->count;
   if (current_loops && EXIT_BLOCK_PTR_FOR_FN (cfun)->loop_father)
index b43e67f65ef6d19b38dad4ce72a4aba4a2e640fa..e67d3c1553f8802545ed6797fa16bf47c0f4da67 100644 (file)
@@ -5156,17 +5156,20 @@ expand_function_end (void)
       crtl->return_rtx = outgoing;
     }
 
-  /* Emit the actual code to clobber return register.  */
-  {
-    rtx seq;
+  /* Emit the actual code to clobber return register.  Don't emit
+     it if clobber_after is a barrier, then the previous basic block
+     certainly doesn't fall thru into the exit block.  */
+  if (!BARRIER_P (clobber_after))
+    {
+      rtx seq;
 
-    start_sequence ();
-    clobber_return_register ();
-    seq = get_insns ();
-    end_sequence ();
+      start_sequence ();
+      clobber_return_register ();
+      seq = get_insns ();
+      end_sequence ();
 
-    emit_insn_after (seq, clobber_after);
-  }
+      emit_insn_after (seq, clobber_after);
+    }
 
   /* Output the label for the naked return from the function.  */
   if (naked_return_label)