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? 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