Message ID | 20101209102315.GA10989@virgil.arch.suse.de |
---|---|
State | New |
Headers | show |
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; > >
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;