Message ID | 20140903084705.GD18073@virgil.suse |
---|---|
State | New |
Headers | show |
On Wed, Sep 3, 2014 at 10:47 AM, Martin Jambor <mjambor@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 <mjambor@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; > +}
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; +}