diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ffe1af3e996b5df81e812f8d975ce6a527d151c8..44e77f9986b8815f74a2a1a01b9fb94f107e7f09 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2013-02-06  Tom de Vries  <tom@codesourcery.com>
+
+	PR rtl-optimization/56131
+	* cfgrtl.c (delete_insn): Use NOTE_BASIC_BLOCK instead of BLOCK_FOR_INSN
+	to get the bb of a NOTE_INSN_BASIC_BLOCK.  Handle the case that the bb
+	of the label is NULL.  Add comment.
+
 2013-02-05  Jakub Jelinek  <jakub@redhat.com>
 
 	* tree.h (struct tree_decl_with_vis): Remove thread_local field.
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index ba07f89bd5c370e69e1014391784a8a1595e73eb..c6ed44f8a7e7041bd8c3100f9095c42b394c121f 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -135,7 +135,7 @@ delete_insn (rtx insn)
       if (! can_delete_label_p (insn))
 	{
 	  const char *name = LABEL_NAME (insn);
-	  basic_block bb = BLOCK_FOR_INSN (insn);
+	  basic_block bb, label_bb = BLOCK_FOR_INSN (insn);
 	  rtx bb_note = NEXT_INSN (insn);
 
 	  really_delete = false;
@@ -143,10 +143,16 @@ delete_insn (rtx insn)
 	  NOTE_KIND (insn) = NOTE_INSN_DELETED_LABEL;
 	  NOTE_DELETED_LABEL_NAME (insn) = name;
 
-	  if (bb_note != NULL_RTX && NOTE_INSN_BASIC_BLOCK_P (bb_note)
-	      && BLOCK_FOR_INSN (bb_note) == bb)
+	  /* If the note following the label starts a basic block, and the
+	     label is a member of the same basic block, interchange the two.
+	     If the label is not marked with a bb, assume it's the same bb.  */
+	  if (bb_note != NULL_RTX
+	      && NOTE_INSN_BASIC_BLOCK_P (bb_note)
+	      && (label_bb == NOTE_BASIC_BLOCK (bb_note)
+		  || label_bb == NULL))
 	    {
 	      reorder_insns_nobb (insn, insn, bb_note);
+	      bb = NOTE_BASIC_BLOCK (bb_note);
 	      BB_HEAD (bb) = bb_note;
 	      if (BB_END (bb) == bb_note)
 		BB_END (bb) = insn;