Hi! The recent r244993 change where bypass_conditional_jumps is called only after splitting blocks for unconditional traps can result in ICEs during bypass_conditional_jumps, because on the (unreachable, to be removed later) new basic blocks created by that splitting we don't have cprop per-bb data structures like cprop_avout computed (nor space for them allocated). bypass_conditional_jumps already uses bypass_last_basic_block variable to avoid touching basic blocks created during that function, so this patch just extends that to also the basic blocks created for splitting after unconditional traps.
Bootstrapped/regtested on {x86_64,i686,powerpc64{,le}}-linux, ok for trunk? 2017-02-06 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/79386 * cprop.c (bypass_conditional_jumps): Initialize bypass_last_basic_block already before splitting bbs after unconditional traps... (bypass_conditional_jumps): ... rather than here. * gcc.c-torture/compile/pr79386.c: New test. --- gcc/cprop.c.jj 2017-01-30 09:31:48.000000000 +0100 +++ gcc/cprop.c 2017-02-06 14:37:07.157093577 +0100 @@ -1697,7 +1697,6 @@ bypass_conditional_jumps (void) if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)) return 0; - bypass_last_basic_block = last_basic_block_for_fn (cfun); mark_dfs_back_edges (); changed = 0; @@ -1863,6 +1862,11 @@ one_cprop_pass (void) } } + /* Make sure bypass_conditional_jumps will ignore not just its new + basic blocks, but also the ones after unconditional traps (those are + unreachable and will be eventually removed as such). */ + bypass_last_basic_block = last_basic_block_for_fn (cfun); + while (!uncond_traps.is_empty ()) { rtx_insn *insn = uncond_traps.pop (); --- gcc/testsuite/gcc.c-torture/compile/pr79386.c.jj 2017-02-06 14:43:31.932063697 +0100 +++ gcc/testsuite/gcc.c-torture/compile/pr79386.c 2017-02-06 14:43:19.000000000 +0100 @@ -0,0 +1,46 @@ +/* PR rtl-optimization/79386 */ + +int a, b; + +int +foo (int x) +{ + int c; + int *d, *e; + + if (b == 0) + { + c = 0; + e = &b; + d = &b; + } + else + { + int f; + + c = 1; + for (f = 0; f < 9; ++f) + c *= 3; + e = (int *) (__UINTPTR_TYPE__) c; + d = &x; + } + *e = c < 3; + if (*e != 0) + { + int g; + + b += (a != 0) ? a : 1; + if (g != 0 || x != 0) + *d = 0; + if (b >= 0) + { + if (g != 0) + g = x; + if (*d / g != 0) + for (;;) + ; + } + } + + return b * (a != 0 && *d != 0); +} Jakub