Message ID | 20131126203323.GO892@tucnak.redhat.com |
---|---|
State | New |
Headers | show |
On 11/26/13 13:33, Jakub Jelinek wrote: > 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 <jakub@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. OK. jeff
--- 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; +}