Hi, On Fri, Nov 21, 2014 at 09:18:03PM +0100, Richard Biener wrote: > On November 21, 2014 9:07:50 PM CET, Martin Jambor <mjam...@suse.cz> wrote: > >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 think you want to use fold_unary (VIEW_CONVERT,...) Here if you consider > the case with > Int and float. And "fail" if that returns NULL or not a constant. >
You are of course right. The following does exactly that. Bootstrapped and tested on x86_64-linux on trunk and the 4.9 branch. OK for both? 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,7 +880,10 @@ evaluate_conditions_for_known_args (stru } if (c->code == IS_NOT_CONSTANT || c->code == CHANGED) continue; - res = fold_binary_to_constant (c->code, boolean_type_node, val, c->val); + val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (c->val), val); + res = val + ? fold_binary_to_constant (c->code, boolean_type_node, val, c->val) + : NULL; if (res && integer_zerop (res)) continue; clause |= 1 << (i + predicate_first_dynamic_condition); 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; +}