new file mode 100644
@@ -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" } } */
@@ -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