sra: Disqualify bases of operands of asm gotos

PR 110422 shows that SRA can ICE assuming there is a single edge
outgoing from a block terminated with an asm goto.  We need that for
BB-terminating statements so that any adjustments they make to the
aggregates can be copied over to their replacements.  Because we can't
have that after ASM gotos, we need to punt.

gcc/ChangeLog:

2024-01-17  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/110422
	* tree-sra.cc (scan_function): Disqualify bases of operands of asm
	gotos.

gcc/testsuite/ChangeLog:

2024-01-17  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/110422
	* gcc.dg/torture/pr110422.c: New test.
This commit is contained in:
Martin Jambor 2024-01-18 14:24:15 +01:00
parent 895a213826
commit 6764043e88
No known key found for this signature in database
GPG key ID: BF63C1BC3FA43540
2 changed files with 33 additions and 6 deletions

View file

@ -0,0 +1,10 @@
/* { dg-do compile } */
struct T { int x; };
int foo(void) {
struct T v;
asm goto("" : "+r"(v.x) : : : lab);
return 0;
lab:
return -5;
}

View file

@ -1559,15 +1559,32 @@ scan_function (void)
case GIMPLE_ASM:
{
gasm *asm_stmt = as_a <gasm *> (stmt);
for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
if (stmt_ends_bb_p (asm_stmt)
&& !single_succ_p (gimple_bb (asm_stmt)))
{
t = TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
ret |= build_access_from_expr (t, asm_stmt, false);
for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
{
t = TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
disqualify_base_of_expr (t, "OP of asm goto.");
}
for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
{
t = TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
disqualify_base_of_expr (t, "OP of asm goto.");
}
}
for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
else
{
t = TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
ret |= build_access_from_expr (t, asm_stmt, true);
for (i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
{
t = TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
ret |= build_access_from_expr (t, asm_stmt, false);
}
for (i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
{
t = TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
ret |= build_access_from_expr (t, asm_stmt, true);
}
}
}
break;