cfgrtl: Don't try to redirect asm goto to EXIT [PR108263]

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.

2023-01-03  Jakub Jelinek  <jakub@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.
This commit is contained in:
Jakub Jelinek
2023-01-03 12:12:35 +01:00
parent 201c21b0e8
commit 4fb639a7fe
2 changed files with 31 additions and 2 deletions

View File

@@ -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 ())))
{

View File

@@ -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:;
}