We'd like to have PR ipa/63551 fixed even on the 4.8 branch, so this patch backports the fix and its related follow-ups along with a new C++ testcase. Martin J. said he was fine with it and the patches applied cleanly. I've installed the new test onto 4.9/5/trunk a while ago to make sure we don't regress in the future.
Bootstrapped/regtested on x86_64-linux, applying to 4.8. 2015-04-30 Marek Polacek <pola...@redhat.com> * g++.dg/ipa/pr63551.C: New test. Backported from mainline 2014-12-15 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/63551 * gcc.dg/ipa/pr63551.c (fn2): Use 4294967286U instead of 4294967286 to avoid warnings. 2014-12-03 Martin Jambor <mjam...@suse.cz> PR ipa/64153 * ipa-inline-analysis.c (evaluate_conditions_for_known_args): Check type sizes before view_converting. 2014-12-01 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. * gcc.dg/ipa/pr63551.c: New test. * gcc.dg/ipa/pr64041.c: Likewise. diff --git gcc/ipa-inline-analysis.c gcc/ipa-inline-analysis.c index 5343933..1a27df2 100644 --- gcc/ipa-inline-analysis.c +++ gcc/ipa-inline-analysis.c @@ -831,9 +831,19 @@ evaluate_conditions_for_known_args (struct cgraph_node *node, } if (c->code == IS_NOT_CONSTANT || c->code == CHANGED) continue; - res = fold_binary_to_constant (c->code, boolean_type_node, val, c->val); - if (res && integer_zerop (res)) - continue; + + if (operand_equal_p (TYPE_SIZE (TREE_TYPE (c->val)), + TYPE_SIZE (TREE_TYPE (val)), 0)) + { + 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); } return clause; diff --git gcc/testsuite/g++.dg/ipa/pr63551.C gcc/testsuite/g++.dg/ipa/pr63551.C index e69de29..03e0339 100644 --- gcc/testsuite/g++.dg/ipa/pr63551.C +++ gcc/testsuite/g++.dg/ipa/pr63551.C @@ -0,0 +1,23 @@ +// { dg-options "-O -Wno-psabi" } +// { dg-do compile } + +struct A { int a; }; +template <typename T, typename V> struct B { V operator[] (T); }; +union U { long double ld; void *v; }; +A a; + +void +bar (U &x) +{ + if (x.v) *reinterpret_cast <A *>(x.v) = a; +} + +struct C { C (A) { c.ld = 0; bar (c); } U c; }; +struct D { A d, e; void foo () { f[0][d] = e; } B <int, B <A, C> > f; }; + +void +baz () +{ + D d; + d.foo (); +} diff --git gcc/testsuite/gcc.dg/ipa/pr63551.c gcc/testsuite/gcc.dg/ipa/pr63551.c index e69de29..48b020a 100644 --- gcc/testsuite/gcc.dg/ipa/pr63551.c +++ 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 = { 4294967286U }; + fn1 (b); +} + +int +main () +{ + fn2 (); + return 0; +} diff --git gcc/testsuite/gcc.dg/ipa/pr64041.c gcc/testsuite/gcc.dg/ipa/pr64041.c index e69de29..4877b4b 100644 --- gcc/testsuite/gcc.dg/ipa/pr64041.c +++ gcc/testsuite/gcc.dg/ipa/pr64041.c @@ -0,0 +1,64 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +int printf (const char *, ...); + +int a, b = 1, d; + +union U1 +{ + unsigned int f0; + int f1; +}; + +union U2 +{ + int f2; + int f3; +} c; + +int +fn1 (int p) +{ + int t = p && a || p && a && p; + return t ? t : a; +} + +unsigned +fn2 (union U1 p1, union U2 p2) +{ + if (p1.f1 <= 0) + { + for (; p2.f2;) + c.f2 = 0; + p2.f2 = fn1 (d); + } + return p2.f3; +} + +int g = 0; + +int +foo () +{ + if (b) + { + union U1 f = { 0xFFFFFFFFU }; + + fn2 (f, c); + } + g = 1; + return 0; +} + + +int +main () +{ + foo (); + + if (g == 0) + __builtin_abort (); + + return 0; +} Marek