This improves VRP for cases of x = (T) y; if (y !=/== CST) { ... use of X
to insert asserts for X similar to how we handle x = y +- CST. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied. Richard. 2015-06-30 Richard Biener <rguent...@suse.de> * tree-vrp.c (register_edge_assert_for_2): Also register asserts for dominating conversion results. Index: gcc/tree-vrp.c =================================================================== *** gcc/tree-vrp.c (revision 225115) --- gcc/tree-vrp.c (working copy) *************** register_edge_assert_for_2 (tree name, e *** 5359,5365 **** /* In the case of post-in/decrement tests like if (i++) ... and uses of the in/decremented value on the edge the extra name we want to assert for is not on the def chain of the name compared. Instead ! it is in the set of use stmts. */ if ((comp_code == NE_EXPR || comp_code == EQ_EXPR) && TREE_CODE (val) == INTEGER_CST) --- 5359,5367 ---- /* In the case of post-in/decrement tests like if (i++) ... and uses of the in/decremented value on the edge the extra name we want to assert for is not on the def chain of the name compared. Instead ! it is in the set of use stmts. ! Similar cases happen for conversions that were simplified through ! fold_{sign_changed,widened}_comparison. */ if ((comp_code == NE_EXPR || comp_code == EQ_EXPR) && TREE_CODE (val) == INTEGER_CST) *************** register_edge_assert_for_2 (tree name, e *** 5368,5396 **** gimple use_stmt; FOR_EACH_IMM_USE_STMT (use_stmt, ui, name) { - /* Cut off to use-stmts that are in the predecessor. */ - if (gimple_bb (use_stmt) != e->src) - continue; - if (!is_gimple_assign (use_stmt)) continue; ! enum tree_code code = gimple_assign_rhs_code (use_stmt); ! if (code != PLUS_EXPR ! && code != MINUS_EXPR) continue; ! tree cst = gimple_assign_rhs2 (use_stmt); ! if (TREE_CODE (cst) != INTEGER_CST) continue; ! tree name2 = gimple_assign_lhs (use_stmt); ! if (live_on_edge (e, name2)) { cst = int_const_binop (code, val, cst); - register_new_assert_for (name2, name2, comp_code, cst, - NULL, e, bsi); } } } --- 5370,5406 ---- gimple use_stmt; FOR_EACH_IMM_USE_STMT (use_stmt, ui, name) { if (!is_gimple_assign (use_stmt)) continue; ! /* Cut off to use-stmts that are dominating the predecessor. */ ! if (!dominated_by_p (CDI_DOMINATORS, e->src, gimple_bb (use_stmt))) continue; ! tree name2 = gimple_assign_lhs (use_stmt); ! if (TREE_CODE (name2) != SSA_NAME ! || !live_on_edge (e, name2)) continue; ! enum tree_code code = gimple_assign_rhs_code (use_stmt); ! tree cst; ! if (code == PLUS_EXPR ! || code == MINUS_EXPR) { + cst = gimple_assign_rhs2 (use_stmt); + if (TREE_CODE (cst) != INTEGER_CST) + continue; cst = int_const_binop (code, val, cst); } + else if (CONVERT_EXPR_CODE_P (code)) + cst = fold_convert (TREE_TYPE (name2), val); + else + continue; + + if (TREE_OVERFLOW_P (cst)) + cst = drop_tree_overflow (cst); + register_new_assert_for (name2, name2, comp_code, cst, + NULL, e, bsi); } }