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

Reply via email to