/* Unsigned saturation sub, case 2 (branch with ge):
SAT_U_SUB = X >= Y ? X - Y : 0. */
(match (unsigned_integer_sat_sub @0 @1)
- (cond^ (ge @0 @1) (minus @0 @1) integer_zerop)
+ (cond^ (ge @0 @1) (convert? (minus (convert1? @0) (convert1? @1))) integer_zerop)
(if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
- && types_match (type, @0, @1))))
+ && TYPE_UNSIGNED (TREE_TYPE (@0)) && types_match (@0, @1))))
/* Unsigned saturation sub, case 3 (branchless with gt):
SAT_U_SUB = (X - Y) * (X > Y). */
extern bool gimple_unsigned_integer_sat_add (tree, tree*, tree (*)(tree));
extern bool gimple_unsigned_integer_sat_sub (tree, tree*, tree (*)(tree));
-static gcall *
-vect_recog_build_binary_gimple_call (vec_info *vinfo, gimple *stmt,
+static gimple *
+vect_recog_build_binary_gimple_stmt (vec_info *vinfo, stmt_vec_info stmt_info,
internal_fn fn, tree *type_out,
- tree op_0, tree op_1)
+ tree lhs, tree op_0, tree op_1)
{
tree itype = TREE_TYPE (op_0);
- tree vtype = get_vectype_for_scalar_type (vinfo, itype);
+ tree otype = TREE_TYPE (lhs);
+ tree v_itype = get_vectype_for_scalar_type (vinfo, itype);
+ tree v_otype = get_vectype_for_scalar_type (vinfo, otype);
- if (vtype != NULL_TREE
- && direct_internal_fn_supported_p (fn, vtype, OPTIMIZE_FOR_BOTH))
+ if (v_itype != NULL_TREE && v_otype != NULL_TREE
+ && direct_internal_fn_supported_p (fn, v_itype, OPTIMIZE_FOR_BOTH))
{
gcall *call = gimple_build_call_internal (fn, 2, op_0, op_1);
+ tree in_ssa = vect_recog_temp_ssa_var (itype, NULL);
- gimple_call_set_lhs (call, vect_recog_temp_ssa_var (itype, NULL));
+ gimple_call_set_lhs (call, in_ssa);
gimple_call_set_nothrow (call, /* nothrow_p */ false);
- gimple_set_location (call, gimple_location (stmt));
+ gimple_set_location (call, gimple_location (STMT_VINFO_STMT (stmt_info)));
+
+ *type_out = v_otype;
- *type_out = vtype;
+ if (types_compatible_p (itype, otype))
+ return call;
+ else
+ {
+ append_pattern_def_seq (vinfo, stmt_info, call, v_itype);
+ tree out_ssa = vect_recog_temp_ssa_var (otype, NULL);
- return call;
+ return gimple_build_assign (out_ssa, NOP_EXPR, in_ssa);
+ }
}
return NULL;
if (gimple_unsigned_integer_sat_add (lhs, ops, NULL))
{
- gcall *call = vect_recog_build_binary_gimple_call (vinfo, last_stmt,
- IFN_SAT_ADD, type_out,
- ops[0], ops[1]);
- if (call)
+ gimple *stmt = vect_recog_build_binary_gimple_stmt (vinfo, stmt_vinfo,
+ IFN_SAT_ADD, type_out,
+ lhs, ops[0], ops[1]);
+ if (stmt)
{
vect_pattern_detected ("vect_recog_sat_add_pattern", last_stmt);
- return call;
+ return stmt;
}
}
if (gimple_unsigned_integer_sat_sub (lhs, ops, NULL))
{
- gcall *call = vect_recog_build_binary_gimple_call (vinfo, last_stmt,
- IFN_SAT_SUB, type_out,
- ops[0], ops[1]);
- if (call)
+ gimple *stmt = vect_recog_build_binary_gimple_stmt (vinfo, stmt_vinfo,
+ IFN_SAT_SUB, type_out,
+ lhs, ops[0], ops[1]);
+ if (stmt)
{
vect_pattern_detected ("vect_recog_sat_sub_pattern", last_stmt);
- return call;
+ return stmt;
}
}