On Fri, Nov 11, 2011 at 4:21 PM, Martin Jambor <mjam...@suse.cz> wrote: > Hi, > > the problem in PR 50605 is that is_gimple_ip_invariant returns false > for > > &MEM[(struct tRecorderImp *)&recorder + 8B] > > where &reorder is an IP gimple invariant. This patch fixes that by > copying the code that handles MEM_REFs from > is_gimple_invariant_address (and only changing > decl_address_invariant_p to decl_address_ip_invariant_p). > > Bootstrapped and tested on x86_64-linux. OK for trunk?
Ok. Thanks, Richard. > Thanks, > > Martin > > > > 2011-11-11 Martin Jambor <mjam...@suse.cz> > > PR tree-optimization/50605 > * gimple.c (is_gimple_ip_invariant_address): Also handle MEM_REFs > of IPA invariant decls. > > * testsuite/g++.dg/ipa/pr50605.C: New test. > > > Index: src/gcc/testsuite/g++.dg/ipa/pr50605.C > =================================================================== > --- /dev/null > +++ src/gcc/testsuite/g++.dg/ipa/pr50605.C > @@ -0,0 +1,40 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O3 -fno-early-inlining" } */ > + > +class A > +{ > +public: > + int a; > + void *stuff; > +}; > + > +class B > +{ > +public: > + int b; > + void *other_stuff; > + A array[50]; > +}; > + > +extern B gb; > + > +int process_A (A *a) > +{ > + return a->a; > +} > + > +int process_A_complex (A *a) > +{ > + return process_A (a+3); > +} > + > +int process_B (B *b) > +{ > + return process_A_complex (&b->array[0]); > +} > + > +int foo (void) > +{ > + return process_B (&gb); > +} > + > Index: src/gcc/gimple.c > =================================================================== > --- src.orig/gcc/gimple.c > +++ src/gcc/gimple.c > @@ -2850,8 +2850,18 @@ is_gimple_ip_invariant_address (const_tr > return false; > > op = strip_invariant_refs (TREE_OPERAND (t, 0)); > + if (!op) > + return false; > + > + if (TREE_CODE (op) == MEM_REF) > + { > + const_tree op0 = TREE_OPERAND (op, 0); > + return (TREE_CODE (op0) == ADDR_EXPR > + && (CONSTANT_CLASS_P (TREE_OPERAND (op0, 0)) > + || decl_address_ip_invariant_p (TREE_OPERAND (op0, 0)))); > + } > > - return op && (CONSTANT_CLASS_P (op) || decl_address_ip_invariant_p (op)); > + return CONSTANT_CLASS_P (op) || decl_address_ip_invariant_p (op); > } > > /* Return true if T is a GIMPLE minimal invariant. It's a restricted > >