Re: [PATCH] sra: Avoid verification failure (PR 93516)

2020-02-14 Thread Richard Biener
On Fri, 14 Feb 2020, Martin Jambor wrote:

> Hi,
> 
> 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.

"both" use DECL_SIZE, but those can differ dependent on alignment
for example.

> 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.
> 
> Bootstrapped and tested on x86_64-linux.  OK for trunk?

OK.

Thanks,
Richard.

> Thanks,
> 
> Martin
> 
> 
> 2020-02-10  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 fa3cbb895e9..daba335cf79 100644
> --- a/gcc/ChangeLog
> +++ b/gcc/ChangeLog
> @@ -1,3 +1,10 @@
> +2020-02-10  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-10  Feng Xue  
>  
>   PR ipa/93203
> diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
> index 0ede9604611..eada2ebed63 100644
> --- a/gcc/testsuite/ChangeLog
> +++ b/gcc/testsuite/ChangeLog
> @@ -1,3 +1,8 @@
> +2020-02-10  Martin Jambor  
> +
> + PR tree-optimization/93516
> + * g++.dg/tree-ssa/pr93516.C: New test.
> +
>  2020-02-10  Feng Xue  
>  
>   PR ipa/93203
> 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 000..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 ea8594db193..a3bcd5f3e03 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))
> + 

[PATCH] sra: Avoid verification failure (PR 93516)

2020-02-14 Thread Martin Jambor
Hi,

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.

Bootstrapped and tested on x86_64-linux.  OK for trunk?

Thanks,

Martin


2020-02-10  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 fa3cbb895e9..daba335cf79 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2020-02-10  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-10  Feng Xue  
 
PR ipa/93203
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0ede9604611..eada2ebed63 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2020-02-10  Martin Jambor  
+
+   PR tree-optimization/93516
+   * g++.dg/tree-ssa/pr93516.C: New test.
+
 2020-02-10  Feng Xue  
 
PR ipa/93203
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 000..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 ea8594db193..a3bcd5f3e03 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