diff options
author | Martin Jambor <mjambor@suse.cz> | 2020-02-14 15:02:35 +0100 |
---|---|---|
committer | Martin Jambor <mjambor@suse.cz> | 2020-02-14 15:02:35 +0100 |
commit | 515dd04260c6049110d7624eaf1b276929dcd9af (patch) | |
tree | e62aa998fdbd5b7def31b1bcabc6970603962821 /gcc/tree-sra.c | |
parent | 5a8754323d67011f7dceb5c8b82c4a5b48f0de4d (diff) | |
download | gcc-515dd04260c6049110d7624eaf1b276929dcd9af.zip gcc-515dd04260c6049110d7624eaf1b276929dcd9af.tar.gz gcc-515dd04260c6049110d7624eaf1b276929dcd9af.tar.bz2 |
sra: Avoid verification failure (PR 93516)
get_ref_base_and_extent can return different sizes for COMPONENT_REFs
and DECLs of the same type, with the latter including (more?) padding.
When in the IL there is an assignment between such a COMPONENT_REF and a
DECL, SRA will try to propagate the access from the former as a child of
the latter, creating an artificial reference that does not match the
access's declared size, which triggers a verifier assert.
Fixed by teaching the propagation functions about this special situation
so that they don't do it. The condition is the same that
build_user_friendly_ref_for_offset uses so the artificial reference
causing the verifier is guaranteed not to be created.
2020-02-14 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/93516
* tree-sra.c (propagate_subaccesses_from_rhs): Do not create
access of the same type as the parent.
(propagate_subaccesses_from_lhs): Likewise.
gcc/testsuite/
* g++.dg/tree-ssa/pr93516.C: New test.
Diffstat (limited to 'gcc/tree-sra.c')
-rw-r--r-- | gcc/tree-sra.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index f03ad3a..0cfac0a 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -2785,9 +2785,17 @@ propagate_subaccesses_from_rhs (struct access *lacc, struct access *racc) } rchild->grp_hint = 1; - new_acc = create_artificial_child_access (lacc, rchild, norm_offset, - false, (lacc->grp_write - || rchild->grp_write)); + /* Because get_ref_base_and_extent always includes padding in size for + accesses to DECLs but not necessarily for COMPONENT_REFs of the same + type, we might be actually attempting to here to create a child of the + same type as the parent. */ + if (!types_compatible_p (lacc->type, rchild->type)) + new_acc = create_artificial_child_access (lacc, rchild, norm_offset, + false, + (lacc->grp_write + || rchild->grp_write)); + else + new_acc = lacc; gcc_checking_assert (new_acc); if (racc->first_child) propagate_subaccesses_from_rhs (new_acc, rchild); @@ -2834,10 +2842,19 @@ propagate_subaccesses_from_lhs (struct access *lacc, struct access *racc) continue; } - struct access *new_acc - = create_artificial_child_access (racc, lchild, norm_offset, - true, false); - propagate_subaccesses_from_lhs (lchild, new_acc); + /* Because get_ref_base_and_extent always includes padding in size for + accesses to DECLs but not necessarily for COMPONENT_REFs of the same + type, we might be actually attempting to here to create a child of the + same type as the parent. */ + if (!types_compatible_p (racc->type, lchild->type)) + { + struct access *new_acc + = create_artificial_child_access (racc, lchild, norm_offset, + true, false); + propagate_subaccesses_from_lhs (lchild, new_acc); + } + else + propagate_subaccesses_from_lhs (lchild, racc); ret = true; } return ret; |