Message ID | 20141121200750.GD7784@virgil.suse |
---|---|
State | New |
Headers | show |
On November 21, 2014 9:07:50 PM CET, Martin Jambor <mjambor@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 <mjambor@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; >+}
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 <mjambor@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; > +}
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; +}