On May 4, 2017 5:09:15 PM GMT+02:00, Martin Jambor <mjam...@suse.cz> wrote: >Hi, > >PR 80622 happens because when setting grp_write lazily, the code does >not acknowledge that constant pool bases come initialized and so >contain data even when not written to. The patch below fixes that but >it also puts a test for pre-initialization into a special function, >uses it at all appropriate places and moves the test in question to an >earlier time, which is a tiny bit cheaper because it may avoid >unnecessary re-invocation of propagate_subaccesses_across_link. > >Bootstrapped and tested on x86_64-linux, OK for trunk?
OK. Richard. >Thanks, > >Martin > > > >2017-05-04 Martin Jambor <mjam...@suse.cz> > > PR tree-optimization/80622 > * tree-sra.c (comes_initialized_p): New function. > (build_accesses_from_assign): Only set write lazily when > comes_initialized_p is false. > (analyze_access_subtree): Use comes_initialized_p. > (propagate_subaccesses_across_link): Assert !comes_initialized_p > instead of testing for PARM_DECL. > >testsuite/ > * gcc.dg/tree-ssa/pr80622.c: New test. >--- > gcc/testsuite/gcc.dg/tree-ssa/pr80622.c | 19 +++++++++++++++++++ >gcc/tree-sra.c | 29 >+++++++++++++++++++++-------- > 2 files changed, 40 insertions(+), 8 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr80622.c > >diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr80622.c >b/gcc/testsuite/gcc.dg/tree-ssa/pr80622.c >new file mode 100644 >index 00000000000..96dcb8fcdc0 >--- /dev/null >+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr80622.c >@@ -0,0 +1,19 @@ >+/* { dg-do run } */ >+/* { dg-options "-O" } */ >+ >+struct S { int d; char e; int f; char g; } a; >+char c; >+ >+int >+main () >+{ >+ struct S b[][1] = {3, 0, 3, 4, 3, 0, 3, 4, 3, 0, 3, 4, 3, 0, 3, 4, >3, >+ 0, 3, 4, 3, 0, 3, 4, 3, 0, 3, 4, 3, 0, 3, 4, 3, >0, >+ 3, 4, 3, 4, 7, 7, 3, 5, 0, 3, 4, 7, 7, 3, 5, 0, >3, >+ 4, 3, 4, 7, 7, 3, 5, 0, 3, 4, 7, 7, 3, 5, 0, 3, >4}; >+ a = b[4][0]; >+ c = b[4][0].e; >+ if (a.g != 4) >+ __builtin_abort (); >+ return 0; >+} >diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c >index 1606573aead..8ac9c0783ff 100644 >--- a/gcc/tree-sra.c >+++ b/gcc/tree-sra.c >@@ -1305,6 +1305,15 @@ disqualify_if_bad_bb_terminating_stmt (gimple >*stmt, tree lhs, tree rhs) > return false; > } > >+/* Return true if the nature of BASE is such that it contains data >even if >+ there is no write to it in the function. */ >+ >+static bool >+comes_initialized_p (tree base) >+{ >+ return TREE_CODE (base) == PARM_DECL || constant_decl_p (base); >+} >+ >/* Scan expressions occurring in STMT, create access structures for all >accesses >to candidates for scalarization and remove those candidates which occur >in >statements or expressions that prevent them from being split apart. >Return >@@ -1364,8 +1373,10 @@ build_accesses_from_assign (gimple *stmt) > link->racc = racc; > add_link_to_rhs (racc, link); >/* Let's delay marking the areas as written until propagation of >accesses >- across link. */ >- lacc->write = false; >+ across link, unless the nature of rhs tells us that its data comes >+ from elsewhere. */ >+ if (!comes_initialized_p (racc->base)) >+ lacc->write = false; > } > > return lacc || racc; >@@ -2472,8 +2483,7 @@ analyze_access_subtree (struct access *root, >struct access *parent, > > if (!hole || root->grp_total_scalarization) > root->grp_covered = 1; >- else if (root->grp_write || TREE_CODE (root->base) == PARM_DECL >- || constant_decl_p (root->base)) >+ else if (root->grp_write || comes_initialized_p (root->base)) > root->grp_unscalarized_data = 1; /* not covered and written to */ > return sth_created; > } >@@ -2581,11 +2591,14 @@ propagate_subaccesses_across_link (struct >access *lacc, struct access *racc) > >/* IF the LHS is still not marked as being written to, we only need to >do so > if the RHS at this level actually was. */ >- if (!lacc->grp_write && >- (racc->grp_write || TREE_CODE (racc->base) == PARM_DECL)) >+ if (!lacc->grp_write) > { >- lacc->grp_write = true; >- ret = true; >+ gcc_checking_assert (!comes_initialized_p (racc->base)); >+ if (racc->grp_write) >+ { >+ lacc->grp_write = true; >+ ret = true; >+ } > } > > if (is_gimple_reg_type (lacc->type)