https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81644

            Bug ID: 81644
           Summary: ICE in rtl_verify_bb_insn, BBRO pass duplicates BB
                    that ends with flow control insn
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ubizjak at gmail dot com
  Target Milestone: ---

BBRO pass duplicates BB that ends with flow control insn, causing ICE in
rtl_verify_bb_insns, at cfgrtl.c.

Testcase:

--cut here--
void b (void);

void
__attribute__ ((naked))
a (int z)
{
  if (z)
    return;
  b ();
}
--cut here--

gcc -O2:

bbro.c: In function ‘a’:
bbro.c:10:1: error: in basic block 3:
 }
 ^
bbro.c:10:1: error: flow control insn inside a basic block
(insn 17 16 27 3 (trap_if (const_int 1 [0x1])
        (const_int 6 [0x6])) "bbro.c":10 995 {trap}
     (nil))
during RTL pass: bbro
dump file: bbro.c.294r.bbro
bbro.c:10:1: internal compiler error: in rtl_verify_bb_insns, at cfgrtl.c:2669
0xe53d2b _fatal_insn(char const*, rtx_def const*, char const*, int, char
const*)
        /home/uros/gcc-svn/trunk/gcc/rtl-error.c:108
0x95a4e9 rtl_verify_bb_insns
        /home/uros/gcc-svn/trunk/gcc/cfgrtl.c:2669

(Happens on x86 that inserts trap insn where epilogue would be for naked
functions.)

The problem is in bbro pass that duplicates exit block in:

    1: NOTE_INSN_DELETED
    4: NOTE_INSN_BASIC_BLOCK 2
   15: NOTE_INSN_PROLOGUE_END
    3: NOTE_INSN_FUNCTION_BEG
    6: flags:CCZ=cmp(di:SI,0)
      REG_DEAD di:SI
    7: pc={(flags:CCZ!=0)?L12:pc}
      REG_DEAD flags:CCZ
      REG_BR_PROB 20448
    8: NOTE_INSN_BASIC_BLOCK 3
    9: call [`b'] argc:0
      REG_CALL_DECL `b'
   12: L12:
   13: NOTE_INSN_BASIC_BLOCK 4
   16: NOTE_INSN_EPILOGUE_BEG
   17: trap_if 0x1
   14: NOTE_INSN_DELETED

to:

    1: NOTE_INSN_DELETED
    4: NOTE_INSN_BASIC_BLOCK 2
   15: NOTE_INSN_PROLOGUE_END
    3: NOTE_INSN_FUNCTION_BEG
    6: flags:CCZ=cmp(di:SI,0)
      REG_DEAD di:SI
    7: pc={(flags:CCZ==0)?L25:pc}
      REG_DEAD flags:CCZ
      REG_BR_PROB 19552
   13: NOTE_INSN_BASIC_BLOCK 3
   16: NOTE_INSN_EPILOGUE_BEG
   17: trap_if 0x1                    <- here
   27: pc=L26
   28: barrier
   25: L25:
    8: NOTE_INSN_BASIC_BLOCK 4
    9: call [`b'] argc:0
      REG_CALL_DECL `b'
   23: NOTE_INSN_BASIC_BLOCK 5
   21: NOTE_INSN_EPILOGUE_BEG
   22: trap_if 0x1
   26: L26:
   24: NOTE_INSN_BASIC_BLOCK 6
   14: NOTE_INSN_DELETED

bbro pass should leave BBs that end with flow control insn alone.

Reply via email to