diff mbox

[PR,46734,4.5,4.6] No TREE_ADDRESSIBLE types conversion in IPA-SRA

Message ID 20101209102315.GA10989@virgil.arch.suse.de
State New
Headers show

Commit Message

Martin Jambor Dec. 9, 2010, 10:23 a.m. UTC
Hi,

doing type conversion of TREE_ADDRESSIBLE basically requires keeping
the old aggregate around which beats the purpose of IPA-SRA.  The fix
is therefore to disallow such conversions when aggregating accesses.

The patch below has been generated from trunk but the same patch
applies to the 4.5 branch too and fixes the problem there as well.  I
have bootstrapped and tested it on both the trunk and the branch on
x86_64-linux.  OK for trunk now and for the 4.5 branch once it is
unfrozen?

Thanks,

Martin



2010-12-08  Martin Jambor  <mjambor@suse.cz>

	PR middle-end/46734
	* tree-sra.c (splice_param_accesses): Check that there are not
	multiple ADDRESSABLE types.

	* testsuite/g++.dg/tree-ssa/pr46734.C: New test.

Comments

Richard Biener Dec. 9, 2010, 12:06 p.m. UTC | #1
On Thu, 9 Dec 2010, Martin Jambor wrote:

> Hi,
> 
> doing type conversion of TREE_ADDRESSIBLE basically requires keeping
> the old aggregate around which beats the purpose of IPA-SRA.  The fix
> is therefore to disallow such conversions when aggregating accesses.
> 
> The patch below has been generated from trunk but the same patch
> applies to the 4.5 branch too and fixes the problem there as well.  I
> have bootstrapped and tested it on both the trunk and the branch on
> x86_64-linux.  OK for trunk now and for the 4.5 branch once it is
> unfrozen?

Ok.

Thanks,
Richard.

> Thanks,
> 
> Martin
> 
> 
> 
> 2010-12-08  Martin Jambor  <mjambor@suse.cz>
> 
> 	PR middle-end/46734
> 	* tree-sra.c (splice_param_accesses): Check that there are not
> 	multiple ADDRESSABLE types.
> 
> 	* testsuite/g++.dg/tree-ssa/pr46734.C: New test.
> 
> Index: mine/gcc/testsuite/g++.dg/tree-ssa/pr46734.C
> ===================================================================
> --- /dev/null
> +++ mine/gcc/testsuite/g++.dg/tree-ssa/pr46734.C
> @@ -0,0 +1,34 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O -fipa-sra" } */
> +
> +struct A
> +{
> +  int *p;
> +  A() {p = (int *) -1;}
> +  ~A() {if (p && p != (int *) -1) *p = 0;}
> +};
> +
> +struct B
> +{
> +  A a;
> +  char data[23];
> +  B() : a() {data[0] = 0;}
> +};
> +
> +extern A ga;
> +extern int *gi;
> +extern void *gz;
> +extern B *gb;
> +
> +static int * __attribute__ ((noinline)) foo (B *b, void *z)
> +{
> +  __builtin_memcpy (gz, z, 28);
> +  ga = b->a;
> +  return b->a.p;
> +}
> +
> +int *bar (B *b, void *z)
> +{
> +  gb = b;
> +  return foo (b, z);
> +}
> Index: mine/gcc/tree-sra.c
> ===================================================================
> --- mine.orig/gcc/tree-sra.c
> +++ mine/gcc/tree-sra.c
> @@ -3587,7 +3587,10 @@ splice_param_accesses (tree parm, bool *
>  	  else if (ac2->size != access->size)
>  	    return NULL;
>  
> -	  if (access_precludes_ipa_sra_p (ac2))
> +	  if (access_precludes_ipa_sra_p (ac2)
> +	      || (ac2->type != access->type
> +		  && (TREE_ADDRESSABLE (ac2->type)
> +		      || TREE_ADDRESSABLE (access->type))))
>  	    return NULL;
>  
>  	  modification |= ac2->write;
> 
>
diff mbox

Patch

Index: mine/gcc/testsuite/g++.dg/tree-ssa/pr46734.C
===================================================================
--- /dev/null
+++ mine/gcc/testsuite/g++.dg/tree-ssa/pr46734.C
@@ -0,0 +1,34 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O -fipa-sra" } */
+
+struct A
+{
+  int *p;
+  A() {p = (int *) -1;}
+  ~A() {if (p && p != (int *) -1) *p = 0;}
+};
+
+struct B
+{
+  A a;
+  char data[23];
+  B() : a() {data[0] = 0;}
+};
+
+extern A ga;
+extern int *gi;
+extern void *gz;
+extern B *gb;
+
+static int * __attribute__ ((noinline)) foo (B *b, void *z)
+{
+  __builtin_memcpy (gz, z, 28);
+  ga = b->a;
+  return b->a.p;
+}
+
+int *bar (B *b, void *z)
+{
+  gb = b;
+  return foo (b, z);
+}
Index: mine/gcc/tree-sra.c
===================================================================
--- mine.orig/gcc/tree-sra.c
+++ mine/gcc/tree-sra.c
@@ -3587,7 +3587,10 @@  splice_param_accesses (tree parm, bool *
 	  else if (ac2->size != access->size)
 	    return NULL;
 
-	  if (access_precludes_ipa_sra_p (ac2))
+	  if (access_precludes_ipa_sra_p (ac2)
+	      || (ac2->type != access->type
+		  && (TREE_ADDRESSABLE (ac2->type)
+		      || TREE_ADDRESSABLE (access->type))))
 	    return NULL;
 
 	  modification |= ac2->write;