On Wed, Sep 3, 2014 at 10:47 AM, Martin Jambor <mjam...@suse.cz> wrote: > Hi, > > this PR revealed that the aggregate value intersection code in IPA-CP > has one more problem in it, namely when jump function flags show that > a PASS_THROUGH jump function cannot be used at all, it must also clear > the intersection when punting. Fixed thusly. > > Bootstrapped and tested on x86_64-linux (so far only on trunk, testing > on branches in progress). OK for trunk and all the problematic > branches (IIRC both 4.9 and 4.8)?
Ok. Thanks, Richard. > Thanks, > > Martin > > > 2014-09-02 Martin Jambor <mjam...@suse.cz> > > PR ipa/62015 > * ipa-cp.c (intersect_aggregates_with_edge): Handle impermissible > pass-trough jump functions correctly. > > testsuite/ > * g++.dg/ipa/pr62015.C: New test. > > diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c > index 44d4c9a..afbec25 100644 > --- a/gcc/ipa-cp.c > +++ b/gcc/ipa-cp.c > @@ -3048,6 +3048,11 @@ intersect_aggregates_with_edge (struct cgraph_edge > *cs, int index, > intersect_with_agg_replacements (cs->caller, src_idx, > &inter, 0); > } > + else > + { > + inter.release (); > + return vNULL; > + } > } > else > { > @@ -3063,6 +3068,11 @@ intersect_aggregates_with_edge (struct cgraph_edge > *cs, int index, > else > intersect_with_plats (src_plats, &inter, 0); > } > + else > + { > + inter.release (); > + return vNULL; > + } > } > } > else if (jfunc->type == IPA_JF_ANCESTOR > diff --git a/gcc/testsuite/g++.dg/ipa/pr62015.C > b/gcc/testsuite/g++.dg/ipa/pr62015.C > new file mode 100644 > index 0000000..950b46e > --- /dev/null > +++ b/gcc/testsuite/g++.dg/ipa/pr62015.C > @@ -0,0 +1,55 @@ > +/* { dg-do run } */ > +/* { dg-options "-O3 -std=c++11" } */ > + > + > +extern "C" int printf(const char *fmt, ...); > +extern "C" void abort(void); > + > +struct Side { > + enum _Value { Left, Right, Invalid }; > + > + constexpr Side() : _value(Invalid) {} > + constexpr Side(_Value value) : _value(value) {} > + operator _Value() const { return (_Value)_value; } > + > + private: > + char _value; > +}; > + > +struct A { > + void init(); > + void adjust(Side side, bool final); > + void move(Side side); > +}; > + > +void A::init() > +{ > + adjust(Side::Invalid, false); > +} > + > +static void __attribute__((noinline)) > +check (int v, int final) > +{ > + if (v != 0) > + abort(); > +} > + > + > +__attribute__((noinline)) > +void A::adjust(Side side, bool final) > +{ > + check ((int)side, final); > +} > + > +void A::move(Side side) > +{ > + adjust(side, false); > + adjust(side, true); > +} > + > +int main() > +{ > + A t; > + t.move(Side::Left); > + return 0; > +}