From 515dd04260c6049110d7624eaf1b276929dcd9af Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Fri, 14 Feb 2020 15:02:35 +0100 Subject: [PATCH] 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 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. --- gcc/ChangeLog | 7 ++++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/g++.dg/tree-ssa/pr93516.C | 24 +++++++++++++++++++ gcc/tree-sra.c | 31 +++++++++++++++++++------ 4 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr93516.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 797d9716d4e..1cdec0b4071 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2020-02-14 Martin Jambor + + 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. + 2020-02-14 Hongtao Liu PR target/93724 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e1df2c67633..a69fa2c2947 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-02-14 Martin Jambor + + PR tree-optimization/93516 + * g++.dg/tree-ssa/pr93516.C: New test. + 2020-02-14 Hongtao Liu * gcc.target/i386/avx512vbmi2-vpshld-1.c: New test. diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr93516.C b/gcc/testsuite/g++.dg/tree-ssa/pr93516.C new file mode 100644 index 00000000000..2bba37c1386 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr93516.C @@ -0,0 +1,24 @@ +// { dg-do compile } +// { dg-options "-O2" } */ + +struct b; +struct c { + b *operator->(); +}; +class e { + void *f; + int d; + +public: + template a g() { return *static_cast(this); } +}; +struct h : e {}; +struct b { + void i(e); + e j(); +}; +void m() { + c k; + h l = k->j().g(); + k->i(l); +} diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index f03ad3a586f..0cfac0a8192 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; -- 2.30.2