diff options
-rw-r--r-- | gcc/match.pd | 16 | ||||
-rw-r--r-- | gcc/tree-vect-patterns.cc | 5 |
2 files changed, 20 insertions, 1 deletions
diff --git a/gcc/match.pd b/gcc/match.pd index a664be5..4cef965 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3221,6 +3221,22 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (bit_xor:c (negate (convert (lt @0 integer_zerop))) max_value)) (if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type)))) +/* Signed saturation add, case 3: + T sum = (T)((UT)X + (UT)Y) + SAT_S_ADD = (X ^ Y) < 0 && (X ^ sum) >= 0 ? (-(T)(X < 0) ^ MAX) : sum; + + The T and UT are type pair like T=int8_t, UT=uint8_t. */ +(match (signed_integer_sat_add @0 @1) + (cond^ (bit_and:c (lt (bit_xor @0 (nop_convert@2 (plus (nop_convert @0) + (nop_convert @1)))) + integer_zerop) + (ge (bit_xor:c @0 @1) integer_zerop)) + (bit_xor:c (nop_convert (negate (nop_convert (convert + (lt @0 integer_zerop))))) + max_value) + @2) + (if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type)))) + /* Unsigned saturation sub, case 1 (branch with gt): SAT_U_SUB = X > Y ? X - Y : 0 */ (match (unsigned_integer_sat_sub @0 @1) diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc index 3a0d4cb..a2bf90a 100644 --- a/gcc/tree-vect-patterns.cc +++ b/gcc/tree-vect-patterns.cc @@ -4497,6 +4497,8 @@ extern bool gimple_unsigned_integer_sat_add (tree, tree*, tree (*)(tree)); extern bool gimple_unsigned_integer_sat_sub (tree, tree*, tree (*)(tree)); extern bool gimple_unsigned_integer_sat_trunc (tree, tree*, tree (*)(tree)); +extern bool gimple_signed_integer_sat_add (tree, tree*, tree (*)(tree)); + static gimple * vect_recog_build_binary_gimple_stmt (vec_info *vinfo, stmt_vec_info stmt_info, internal_fn fn, tree *type_out, @@ -4557,7 +4559,8 @@ vect_recog_sat_add_pattern (vec_info *vinfo, stmt_vec_info stmt_vinfo, tree ops[2]; tree lhs = gimple_assign_lhs (last_stmt); - if (gimple_unsigned_integer_sat_add (lhs, ops, NULL)) + if (gimple_unsigned_integer_sat_add (lhs, ops, NULL) + || gimple_signed_integer_sat_add (lhs, ops, NULL)) { if (TREE_CODE (ops[1]) == INTEGER_CST) ops[1] = fold_convert (TREE_TYPE (ops[0]), ops[1]); |