diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr97009.c b/gcc/testsuite/gcc.dg/tree-ssa/pr97009.c new file mode 100644 index 00000000000..741dbc270c3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr97009.c @@ -0,0 +1,66 @@ +/* { dg-do run } */ +/* { dg-options "-O1" } */ + +static int __attribute__((noipa)) +get_5 (void) +{ + return 5; +} + +static int __attribute__((noipa)) +verify_5 (int v) +{ + if (v != 5) + __builtin_abort (); +} + +struct T +{ + int w; + int a[4]; +}; + +struct S +{ + int v; + int x; + struct T t[2]; + char alotofstuff[128]; +}; + +volatile int vol; + +void __attribute__((noipa)) +consume_t (struct T t) +{ + vol = t.a[0]; +} + +int __attribute__((noipa)) +foo (int l1, int l2) +{ + struct S s1, s2, s3; + int i, j; + + s1.v = get_5 (); + for (i = 0; i < l1; i++) + { + for (j = 0; j < l2; j++) + s1.t[i].a[j] = get_5 (); + consume_t(s1.t[i]); + } + + s2 = s1; + + s3 = s2; + for (i = 0; i < l1; i++) + for (j = 0; j < l2; j++) + verify_5 (s3.t[i].a[j]); +} + +int +main (int argc, char *argv[]) +{ + foo (2, 4); + return 0; +} diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index d177f1ba11c..8dfc923ed7e 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -2723,6 +2723,19 @@ budget_for_propagation_access (tree decl) return true; } +/* Return true if ACC or any of its subaccesses has grp_child set. */ + +static bool +access_or_its_child_written (struct access *acc) +{ + if (acc->grp_write) + return true; + for (struct access *sub = acc->first_child; sub; sub = sub->next_sibling) + if (access_or_its_child_written (sub)) + return true; + return false; +} + /* Propagate subaccesses and grp_write flags of RACC across an assignment link to LACC. Enqueue sub-accesses as necessary so that the write flag is propagated transitively. Return true if anything changed. Additionally, if @@ -2836,7 +2849,7 @@ propagate_subaccesses_from_rhs (struct access *lacc, struct access *racc) if (rchild->grp_unscalarizable_region || !budget_for_propagation_access (lacc->base)) { - if (rchild->grp_write && !lacc->grp_write) + if (!lacc->grp_write && access_or_its_child_written (rchild)) { ret = true; subtree_mark_written_and_rhs_enqueue (lacc);