Hi! Given: _6 = (_Bool) a.1_5; _7 = _4 | _6; if (_7 != 0) goto <bb 5>; else goto <bb 6>; where a.1_5 has int type and _6/_4/_7 are _Bool, register_edge_assert_for_1 happily inserts: <bb 6>: a.1_14 = ASSERT_EXPR <a.1_5, a.1_5 == 0>; assertion, which is wrong, the fact that _6 is known to be 0 doesn't imply that a.1_5 is zero, as there is a narrowing conversion. We can only safely look through integer->integer conversions which are widening or preserve precision.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? I'll try to create a testcase for 4.8 branch tomorrow. 2013-11-26 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/59014 * tree-vrp.c (register_edge_assert_for_1): Don't look through conversions from non-integral types or through narrowing conversions. * gcc.c-torture/execute/pr59014.c: New test. --- gcc/tree-vrp.c.jj 2013-11-22 21:03:03.000000000 +0100 +++ gcc/tree-vrp.c 2013-11-26 18:13:37.227600646 +0100 @@ -5434,9 +5434,13 @@ register_edge_assert_for_1 (tree op, enu } else if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (op_def))) { - /* Recurse through the type conversion. */ - retval |= register_edge_assert_for_1 (gimple_assign_rhs1 (op_def), - code, e, bsi); + /* Recurse through the type conversion, unless it is a narrowing + conversion or conversion from non-integral type. */ + tree rhs = gimple_assign_rhs1 (op_def); + if (INTEGRAL_TYPE_P (TREE_TYPE (rhs)) + && (TYPE_PRECISION (TREE_TYPE (rhs)) + <= TYPE_PRECISION (TREE_TYPE (op)))) + retval |= register_edge_assert_for_1 (rhs, code, e, bsi); } return retval; --- gcc/testsuite/gcc.c-torture/execute/pr59014.c.jj 2013-11-26 18:15:06.274152877 +0100 +++ gcc/testsuite/gcc.c-torture/execute/pr59014.c 2013-11-26 18:14:52.000000000 +0100 @@ -0,0 +1,25 @@ +/* PR tree-optimization/59014 */ + +int a = 2, b, c, d; + +int +foo () +{ + for (;; c++) + if ((b > 0) | (a & 1)) + ; + else + { + d = a; + return 0; + } +} + +int +main () +{ + foo (); + if (d != 2) + __builtin_abort (); + return 0; +} Jakub