Hi!

This transformation turns it into a false or true if TREE_OVERFLOW
and TYPE_OVERFLOW_UNDEFINED, but if TREE_OVERFLOW is set, but not
TYPE_OVERFLOW_UNDEFINED, we leak the overflow bit into the IL, which then
confuses the VRP pass.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2017-11-27  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/80788
        * match.pd (X +- C1 CMP C2 -> X CMP C2 -+ C1): If res
        has TREE_OVERFLOW set, call drop_tree_overflow.

        * gcc.dg/pr80788.c: New test.

--- gcc/match.pd.jj     2017-11-24 22:38:53.000000000 +0100
+++ gcc/match.pd        2017-11-27 13:02:37.385280024 +0100
@@ -4393,7 +4393,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
          && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
       { constant_boolean_node (cmp == NE_EXPR, type); }
       (if (single_use (@3))
-       (cmp @0 { res; }))))))))
+       (cmp @0 { TREE_OVERFLOW (res)
+                ? drop_tree_overflow (res) : res; }))))))))
 (for cmp (lt le gt ge)
  (for op (plus minus)
       rop (minus plus)
--- gcc/testsuite/gcc.dg/pr80788.c.jj   2017-11-27 13:05:08.554378216 +0100
+++ gcc/testsuite/gcc.dg/pr80788.c      2017-11-27 13:04:42.000000000 +0100
@@ -0,0 +1,13 @@
+/* PR tree-optimization/80788 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fwrapv" } */
+
+void
+foo (signed char x)
+{
+  signed char a = (x + 1) ^ 128;
+  x &= !!a;
+  if (x != 0)
+    for (;;)
+      ;
+}

        Jakub

Reply via email to