Message ID | ri6mst3ddmq.fsf@ |
---|---|
State | New |
Headers | show |
Series | sra: Disqualify bases of operands of asm gotos | expand |
On Wed, 17 Jan 2024, Martin Jambor wrote: > Hi, > > 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. > > Bootstrapped and tested on x86_64-linux, OK for master? It will need > some tweaking for release branches, is it in principle OK for them too > (after testing)? OK. > Thanks, > > Martin > > > 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. > --- > gcc/testsuite/gcc.dg/torture/pr110422.c | 10 +++++++++ > gcc/tree-sra.cc | 29 ++++++++++++++++++++----- > 2 files changed, 33 insertions(+), 6 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/torture/pr110422.c > > diff --git a/gcc/testsuite/gcc.dg/torture/pr110422.c b/gcc/testsuite/gcc.dg/torture/pr110422.c > new file mode 100644 > index 00000000000..2e171a7a19e > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/torture/pr110422.c > @@ -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; > +} > diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc > index 6a1141b7377..f8e71ec48b9 100644 > --- a/gcc/tree-sra.cc > +++ b/gcc/tree-sra.cc > @@ -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; >
diff --git a/gcc/testsuite/gcc.dg/torture/pr110422.c b/gcc/testsuite/gcc.dg/torture/pr110422.c new file mode 100644 index 00000000000..2e171a7a19e --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr110422.c @@ -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; +} diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc index 6a1141b7377..f8e71ec48b9 100644 --- a/gcc/tree-sra.cc +++ b/gcc/tree-sra.cc @@ -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;