On November 21, 2014 9:07:50 PM CET, Martin Jambor <mjam...@suse.cz> 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 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. Thanks, Richard. >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; >+}