On Fri, Nov 21, 2014 at 09:07:50PM +0100, Martin Jambor wrote: > Hi, > > the testcase of PR 63551 passes a union between a signed and an > unsigned integer between two functions as a parameter. The caller > initializes to an unsigned integer with the highest order bit set, the > callee loads the data through the signed field and compares with zero. > evaluate_conditions_for_known_args then wrongly evaluated the > condition in these circumstances, which later on lead to insertion of > builtin_unreachable and miscompilation. > > Fixed by fold_converting the known value first. I use the type of the > value in the condition which should do exactly the right thing because > the value is taken from the corresponding gimple_cond statement in > which types must match. > > Bootstrapped and tested on x86_64-linux. OK for trunk?
I forgot, this is also a 4.9 bug and I have bootstrapped and tested it on top of the 4.9 branch as well. So OK for trunk and the 4.9 branch? Thanks, Martin > > 2014-11-21 Martin Jambor <mjam...@suse.cz> > > PR ipa/63551 > * ipa-inline-analysis.c (evaluate_conditions_for_known_args): Convert > value of the argument to the type of the value in the condition. > > testsuite/ > * gcc.dg/ipa/pr63551.c: New test. > > > Index: src/gcc/ipa-inline-analysis.c > =================================================================== > --- src.orig/gcc/ipa-inline-analysis.c > +++ src/gcc/ipa-inline-analysis.c > @@ -880,6 +880,7 @@ evaluate_conditions_for_known_args (stru > } > if (c->code == IS_NOT_CONSTANT || c->code == CHANGED) > continue; > + val = fold_convert (TREE_TYPE (c->val), val); > res = fold_binary_to_constant (c->code, boolean_type_node, val, > c->val); > if (res && integer_zerop (res)) > continue; > Index: src/gcc/testsuite/gcc.dg/ipa/pr63551.c > =================================================================== > --- /dev/null > +++ src/gcc/testsuite/gcc.dg/ipa/pr63551.c > @@ -0,0 +1,33 @@ > +/* { dg-do run } */ > +/* { dg-options "-Os" } */ > + > +union U > +{ > + unsigned int f0; > + int f1; > +}; > + > +int a, d; > + > +void > +fn1 (union U p) > +{ > + if (p.f1 <= 0) > + if (a) > + d = 0; > +} > + > +void > +fn2 () > +{ > + d = 0; > + union U b = { 4294967286 }; > + fn1 (b); > +} > + > +int > +main () > +{ > + fn2 (); > + return 0; > +}