aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2024-01-18 14:24:15 +0100
committerMartin Jambor <mjambor@suse.cz>2024-01-18 14:25:30 +0100
commit6764043e88a4208f7c69bf0ccd19ddc7a6016fb1 (patch)
tree2ead8c77a846d0861feb95f088c82b4381a1e0b2
parent895a2138265fd9cace3588404523122f73626d2a (diff)
downloadgcc-6764043e88a4208f7c69bf0ccd19ddc7a6016fb1.zip
gcc-6764043e88a4208f7c69bf0ccd19ddc7a6016fb1.tar.gz
gcc-6764043e88a4208f7c69bf0ccd19ddc7a6016fb1.tar.bz2
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.
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr110422.c10
-rw-r--r--gcc/tree-sra.cc29
2 files changed, 33 insertions, 6 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr110422.c b/gcc/testsuite/gcc.dg/torture/pr110422.c
new file mode 100644
index 0000000..2e171a7
--- /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 6a1141b..f8e71ec 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;