https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65735
--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #3) > Slightly cleaned up testcase (so it doesn't use ununinitialized vars). -O2 > is enough. > The ICE is on: > 2443 /* Make sure the successor is the next node in the path. */ > 2444 gcc_assert (i + 1 == n_region > 2445 || region_copy[i + 1] == single_succ_edge > (bb)->dest); > > i is 0, n_region is 5. > > int foo (void); > > void > bar (int a, int b, int c) > { > while (!a) > { > c = foo (); > if (c == 7) > c = b; > switch (c) > { > case 1: > a = b++; > if (b) > b = 1; > } > } > } Don't know anything about the FSM code, but in the second thread_through_all_blocks the first path looks like: (gdb) p *paths.m_vec->m_vecdata[0].m_vec->m_vecdata[0] $127 = {e = <edge 0x7ffff18669a0 (9 -> 4)>, type = EDGE_FSM_THREAD} (gdb) p *paths.m_vec->m_vecdata[0].m_vec->m_vecdata[1] $128 = {e = <edge 0x7ffff1866850 (4 -> 5)>, type = EDGE_FSM_THREAD} (gdb) p *paths.m_vec->m_vecdata[0].m_vec->m_vecdata[2] $129 = {e = <edge 0x7ffff1866498 (5 -> 12)>, type = EDGE_FSM_THREAD} (gdb) p *paths.m_vec->m_vecdata[0].m_vec->m_vecdata[3] $130 = {e = <edge 0x7ffff18665b0 (12 -> 14)>, type = EDGE_FSM_THREAD} (gdb) p *paths.m_vec->m_vecdata[0].m_vec->m_vecdata[4] $131 = {e = <edge 0x7ffff18663f0 (14 -> 5)>, type = EDGE_FSM_THREAD} (gdb) p *paths.m_vec->m_vecdata[0].m_vec->m_vecdata[5] $132 = {e = <edge 0x7ffff1866498 (5 -> 12)>, type = EDGE_NO_COPY_SRC_BLOCK} Having the same block (bb5) twice in the path sounds really suspicious to me. Guess a quick hack could be to check for bbs appearing more than once in valid_jump_thread_path. Dunno if bb->flags & BB_VISITED could be used for that.