Bug 59605 - [4.9 Regression] error: wrong number of branch edges after unconditional jump in bb 11
Summary: [4.9 Regression] error: wrong number of branch edges after unconditional jump...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: 4.9.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-12-26 20:25 UTC by H.J. Lu
Modified: 2014-01-02 13:20 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-12-26 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2013-12-26 20:25:53 UTC
On Linux/x86, r206213  gave

[hjl@gnu-18 gcc]$ cat bad.c
#define BUFFER_SIZE (16*1024*1024 + AVG_SIZE*2)
/*#define MEMORY_COPIES (1024*1024*64*(long long)10)*/
char t[BUFFER_SIZE];
main()
{
  unsigned int i;
  for (i=0;i<((long long)MEMORY_COPIES + AVG_SIZE * 2 - 1)/AVG_SIZE*2;i++)
#ifdef test_memset
    __builtin_memset (t+(i*1024*1024+i*1)%(BUFFER_SIZE - AVG_SIZE*2), i, (AVG_SIZE + i) % (AVG_SIZE * 2 + 0));
#else
    __builtin_memcpy (t+(i*1024*1024+i*1)%(BUFFER_SIZE - AVG_SIZE*2), t+((i+1)*1024*1024*4+i*1)%(BUFFER_SIZE - AVG_SIZE *2), (AVG_SIZE + i) % (AVG_SIZE * 2 + 0));
#endif
  return 0;
}
[hjl@gnu-18 gcc]$ ./xgcc -B ./  -x c -O3 -minline-stringops-dynamically -DAVG_SIZE=8192000 -DMEMORY_COPIES=640000000 bad.c        
bad.c: In function ‘main’:
bad.c:14:1: error: wrong number of branch edges after unconditional jump in bb 11
 }
 ^
bad.c:14:1: error: wrong number of branch edges after unconditional jump in bb 7
bad.c:14:1: internal compiler error: verify_flow_info failed
0x666c23 verify_flow_info()
	/export/gnu/import/git/gcc/gcc/cfghooks.c:260
0xe25a53 try_optimize_cfg
	/export/gnu/import/git/gcc/gcc/cfgcleanup.c:2857
0xe25a53 cleanup_cfg(int)
	/export/gnu/import/git/gcc/gcc/cfgcleanup.c:3022
0x665412 gimple_expand_cfg
	/export/gnu/import/git/gcc/gcc/cfgexpand.c:5837
0x665412 execute
	/export/gnu/import/git/gcc/gcc/cfgexpand.c:5932
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
[hjl@gnu-18 gcc]$
Comment 1 H.J. Lu 2013-12-26 20:30:20 UTC
It is caused by r203937.
Comment 2 H.J. Lu 2013-12-26 23:10:53 UTC
ix86_expand_set_or_movmem has

  rtx jump_around_label = NULL;

 /* Misaligned move sequences handles both prologues and epilogues at once.
     Default code generation results in smaller code for large alignments and
     also avoids redundant job when sizes are known precisely.  */
  if (misaligned_prologue_used)
    {
      /* Misaligned move prologue handled small blocks by itself.  */
      expand_set_or_movmem_prologue_epilogue_by_misaligned_moves
           (dst, src, &destreg, &srcreg,
            move_mode, promoted_val, vec_promoted_val,
            &count_exp,
            &jump_around_label,
            desired_align < align
            ? MAX (desired_align, epilogue_size_needed) : epilogue_size_needed,
            desired_align, align, &min_size, dynamic_check, issetmem);
      if (!issetmem)
        src = change_address (src, BLKmode, srcreg);
...
      else
        {   
          rtx hot_label = gen_label_rtx ();
          jump_around_label = gen_label_rtx ();
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
When jump_around_label != NULL, the previous jump_around_label
is lost.
          emit_cmp_and_jump_insns (count_exp, GEN_INT (dynamic_check - 1),
                                   LEU, 0, GET_MODE (count_exp), 1, hot_label);
          predict_jump (REG_BR_PROB_BASE * 90 / 100);
          if (issetmem)
            set_storage_via_libcall (dst, count_exp, val_exp, false);
          else
            emit_block_move_via_libcall (dst, src, count_exp, false);
          emit_jump (jump_around_label);
          emit_label (hot_label);
        }
Comment 3 H.J. Lu 2013-12-26 23:15:00 UTC
Does this

---
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 0cf0a9d..07f9a86 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -24015,7 +24015,8 @@ ix86_expand_set_or_movmem (rtx dst, rtx src, rtx count_exp, rtx val_exp,
       else
 	{
 	  rtx hot_label = gen_label_rtx ();
-	  jump_around_label = gen_label_rtx ();
+	  if (jump_around_label == NULL_RTX)
+	    jump_around_label = gen_label_rtx ();
 	  emit_cmp_and_jump_insns (count_exp, GEN_INT (dynamic_check - 1),
 				   LEU, 0, GET_MODE (count_exp), 1, hot_label);
 	  predict_jump (REG_BR_PROB_BASE * 90 / 100);
---

make any senses?
Comment 4 H.J. Lu 2013-12-27 02:32:09 UTC
A patch is posted at

http://gcc.gnu.org/ml/gcc-patches/2013-12/msg01907.html
Comment 5 Jakub Jelinek 2013-12-30 08:48:28 UTC
Author: jakub
Date: Mon Dec 30 08:48:25 2013
New Revision: 206242

URL: http://gcc.gnu.org/viewcvs?rev=206242&root=gcc&view=rev
Log:
	PR target/59605
	* config/i386/i386.c (ix86_expand_set_or_movmem): Create
	jump_around_label only if it doesn't exist.

	* gcc.dg/pr59605.c: New test.

Added:
    trunk/gcc/testsuite/gcc.dg/pr59605.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/i386/i386.c
    trunk/gcc/testsuite/ChangeLog
Comment 6 Jakub Jelinek 2014-01-02 13:20:56 UTC
Fixed.