diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp116.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp116.c new file mode 100644 index 0000000..d9d7b23 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp116.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-vrp1" } */ + +int +f (int m1, int m2, int c) +{ + int d = m1 > m2; + int e = d * c; + return e ? m1 : m2; +} + +/* { dg-final { scan-tree-dump-times "\\? c_\[0-9\]\\(D\\) : 0" 1 "vrp1" } } */ diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 9ca3924..291b87f 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -9146,6 +9146,46 @@ vrp_visit_phi_node (gphi *phi) return SSA_PROP_NOT_INTERESTING; } +static bool +simplify_mult_ops_using_ranges (gimple_stmt_iterator * gsi, gimple *stmt) +{ + enum tree_code rhs_code = gimple_assign_rhs_code (stmt); + tree op0, op1, lhs; + + op0 = gimple_assign_rhs1 (stmt); + op1 = gimple_assign_rhs2 (stmt); + lhs = gimple_assign_lhs (stmt); + + if (!op_with_boolean_value_range_p (op0) + && !op_with_boolean_value_range_p (op1)) + return false; + + if (rhs_code == MULT_EXPR) + { + if (op_with_boolean_value_range_p (op0)) + { + tree t = build_int_cst (TREE_TYPE (lhs), 0); + tree tmp = build3 (COND_EXPR, TREE_TYPE (lhs), + build2 (NE_EXPR, boolean_type_node, op0, t), + op1, t); + gimple *new_assign = gimple_build_assign (lhs, tmp); + gsi_replace (gsi, new_assign, true); + return true; + } + if (op_with_boolean_value_range_p (op1)) + { + tree t = build_int_cst (TREE_TYPE (lhs), 0); + tree tmp = build3 (COND_EXPR, TREE_TYPE (lhs), + build2 (NE_EXPR, boolean_type_node, op1, t), + op0, t); + gimple *new_assign = gimple_build_assign (lhs, tmp); + gsi_replace (gsi, new_assign, true); + return true; + } + } + return false; +} + /* Simplify boolean operations if the source is known to be already a boolean. */ static bool @@ -10345,6 +10385,11 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi) return simplify_div_or_mod_using_ranges (gsi, stmt); break; + case MULT_EXPR: + if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))) + return simplify_mult_ops_using_ranges (gsi, stmt); + break; + /* Transform ABS (X) into X or -X as appropriate. */ case ABS_EXPR: if (TREE_CODE (rhs1) == SSA_NAME