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