Hi! The following testcase distilled from Linux kernel on ppc64le ICEs, because fixup_reorder_chain sees a bb with a single fallthru edge falling into a bb with simple return and decides to redirect that fallthru edge to EXIT. That is possible if the bb ending in the fallthru edge doesn't end with a jump or ends with a normal unconditional jump, but not when the bb ends with asm goto which can despite a single fallthru have multiple labels to the fallthrough basic block.
The following patch makes sure we never try to redirect such cases to EXIT. Bootstrapped/regtested on x86_64-linux, i686-linux and s390x-linux, ok for trunk? 2023-01-03 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/108263 * cfgrtl.cc (fixup_reorder_chain): Avoid trying to redirect asm goto to EXIT. * gcc.dg/pr108263.c: New test. --- gcc/cfgrtl.cc.jj 2023-01-02 09:32:32.000000000 +0100 +++ gcc/cfgrtl.cc 2023-01-02 14:13:40.658338194 +0100 @@ -3910,6 +3910,7 @@ fixup_reorder_chain (void) rtx ret_label = NULL_RTX; basic_block nb; edge_iterator ei; + bool asm_goto = false; if (EDGE_COUNT (bb->succs) == 0) continue; @@ -4016,7 +4017,9 @@ fixup_reorder_chain (void) || e_fall->dest == EXIT_BLOCK_PTR_FOR_FN (cfun)) continue; - /* Otherwise we'll have to use the fallthru fixup below. */ + /* Otherwise we'll have to use the fallthru fixup below. + But avoid redirecting asm goto to EXIT. */ + asm_goto = true; } else { @@ -4048,7 +4051,8 @@ fixup_reorder_chain (void) return rather than a jump to the return block. */ rtx_insn *ret, *use; basic_block dest; - if (bb_is_just_return (e_fall->dest, &ret, &use) + if (!asm_goto + && bb_is_just_return (e_fall->dest, &ret, &use) && ((PATTERN (ret) == simple_return_rtx && targetm.have_simple_return ()) || (PATTERN (ret) == ret_rtx && targetm.have_return ()))) { --- gcc/testsuite/gcc.dg/pr108263.c.jj 2023-01-02 14:09:49.381614027 +0100 +++ gcc/testsuite/gcc.dg/pr108263.c 2023-01-02 14:07:16.899772608 +0100 @@ -0,0 +1,25 @@ +/* PR rtl-optimization/108263 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +int v, *p; + +void +foo (void) +{ + int i; + for (i = 0; ; i++) + { + if (v) + { + __label__ l1; + asm goto ("" : : : : l1); + l1: + return; + } + if (p[i]) + break; + } + asm goto ("" : : "r" (i) : : l2); +l2:; +} Jakub