https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61839
kugan at gcc dot gnu.org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |kugan at gcc dot gnu.org Known to fail|4.10.0 |5.0 --- Comment #2 from kugan at gcc dot gnu.org --- > - c = b != 0 ? 486097858 : 972195717; > + c = a + 972195718 >> (b != 0); ... > until the very end, not transforming c_6. Note that VRP could do the > missing transform as it knows that _5 is [0, 1] (it has to jump through > the shift - the value-range for the shift itself is too broad). > > If written this kind of transform should be applied more generally, not > just for shifts. It basically wants to ask whether a conditional test > can be carried out against another SSA name (and another constant) if > an intermediate compute can be omitted in that case. Do you mean something like, diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index bbdf9ce..dfce619 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -9902,6 +9902,47 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi) { enum tree_code rhs_code = gimple_assign_rhs_code (stmt); tree rhs1 = gimple_assign_rhs1 (stmt); + tree rhs2 = gimple_assign_rhs2 (stmt); + tree var; + + /* Convert: + COND_RES = X COMPARE Y + TMP = (CAST) COND_RES + LHS = CST BINOP TMP + + To: + LHS = COND_RES ? (CST BINOP 1) : (CST BINOP 0) */ + + if (TREE_CODE_CLASS (rhs_code) == tcc_binary + && TREE_CODE (rhs1) == INTEGER_CST + && TREE_CODE (rhs2) == SSA_NAME + && is_gimple_assign (SSA_NAME_DEF_STMT (rhs2)) + && gimple_assign_rhs_code (SSA_NAME_DEF_STMT (rhs2)) == NOP_EXPR + && (var = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (rhs2))) + && TREE_CODE (var) == SSA_NAME + && is_gimple_assign (SSA_NAME_DEF_STMT (var)) + && TREE_CODE_CLASS (gimple_assign_rhs_code (SSA_NAME_DEF_STMT (var))) + == tcc_comparison) + + { + gimple_stmt_iterator gsi = gsi_for_stmt (stmt); + value_range *vr = get_value_range (var); + if (range_int_cst_p (vr) + && integer_zerop (vr->min) + && integer_onep (vr->max)) + { + + tree lhs = gimple_assign_lhs (stmt); + tree new_rhs1 = int_const_binop (rhs_code, rhs1, vr->min); + tree new_rhs2 = int_const_binop (rhs_code, rhs1, vr->max); + + gimple *s = gimple_build_assign (lhs, COND_EXPR, var, + new_rhs1, + new_rhs2 PASS_MEM_STAT); + gsi_replace (&gsi, s, false); + return true; + } + } switch (rhs_code) {