Message ID | 1457691258-25010-1-git-send-email-alan.lawrence@arm.com |
---|---|
State | New |
Headers | show |
On Fri, Mar 11, 2016 at 11:14 AM, Alan Lawrence <alan.lawrence@arm.com> wrote: > In this PR, a packed structure containing bitfields, loses part of its constant-pool initialization in SRA. > > A fuller explanation is on the PR: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70013#c11. In short we need to > treat constant-pool entries, like function parameters, as both come > 'pre-initialized' before the function starts. > > Bootstrapped + regtest (gcc, g++) on AArch64; same with addition of Ada, on ARM > and x86. > > OK for trunk? Ok. Richard. > gcc/ChangeLog: > > PR tree-optimization/70013 > * tree-sra.c (analyze_access_subtree): Also set grp_unscalarized_data > for constant-pool entries. > > gcc/testsuite/ChangeLog: > > * gcc.dg/tree-ssa/sra-20.c: New. > --- > gcc/testsuite/gcc.dg/tree-ssa/sra-20.c | 20 ++++++++++++++++++++ > gcc/tree-sra.c | 3 ++- > 2 files changed, 22 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/sra-20.c > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sra-20.c b/gcc/testsuite/gcc.dg/tree-ssa/sra-20.c > new file mode 100644 > index 0000000..5002c24 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/sra-20.c > @@ -0,0 +1,20 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O1 -Wall" } */ > +/* PR/70013, SRA of constant-pool loads removes initialization of part of d. */ > +#pragma pack (1) > +struct S0 { > + unsigned f0 : 17; > +}; > + > +int c; > + > +int > +main (int argc, char **argv) > +{ > + struct S0 d[] = { { 1 }, { 2 } }; > + struct S0 e = d[1]; > + > + c = d[0].f0; > + __builtin_printf ("%x\n", e.f0); > + return 0; > +} > diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c > index 72157ed..24eac6a 100644 > --- a/gcc/tree-sra.c > +++ b/gcc/tree-sra.c > @@ -2427,7 +2427,8 @@ 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) > + else if (root->grp_write || TREE_CODE (root->base) == PARM_DECL > + || constant_decl_p (root->base)) > root->grp_unscalarized_data = 1; /* not covered and written to */ > return sth_created; > } > -- > 1.9.1 >
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sra-20.c b/gcc/testsuite/gcc.dg/tree-ssa/sra-20.c new file mode 100644 index 0000000..5002c24 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/sra-20.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -Wall" } */ +/* PR/70013, SRA of constant-pool loads removes initialization of part of d. */ +#pragma pack (1) +struct S0 { + unsigned f0 : 17; +}; + +int c; + +int +main (int argc, char **argv) +{ + struct S0 d[] = { { 1 }, { 2 } }; + struct S0 e = d[1]; + + c = d[0].f0; + __builtin_printf ("%x\n", e.f0); + return 0; +} diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 72157ed..24eac6a 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -2427,7 +2427,8 @@ 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) + else if (root->grp_write || TREE_CODE (root->base) == PARM_DECL + || constant_decl_p (root->base)) root->grp_unscalarized_data = 1; /* not covered and written to */ return sth_created; }