}
(if (wi::eq_p (sum, wi::uhwi (0, precision)))))))
+/* Signed saturation sub, case 1:
+ T minus = (T)((UT)X - (UT)Y);
+ SAT_S_SUB = (X ^ Y) & (X ^ minus) < 0 ? (-(T)(X < 0) ^ MAX) : minus;
+
+ The T and UT are type pair like T=int8_t, UT=uint8_t. */
+(match (signed_integer_sat_sub @0 @1)
+ (cond^ (lt (bit_and:c (bit_xor:c @0 @1)
+ (bit_xor @0 (nop_convert@2 (minus (nop_convert @0)
+ (nop_convert @1)))))
+ integer_zerop)
+ (bit_xor:c (negate (convert (lt @0 integer_zerop))) max_value)
+ @2)
+ (if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type))))
+
/* Unsigned saturation truncate, case 1, sizeof (WT) > sizeof (NT).
SAT_U_TRUNC = (NT)x | (NT)(-(X > (WT)(NT)(-1))). */
(match (unsigned_integer_sat_trunc @0)
extern bool gimple_unsigned_integer_sat_trunc (tree, tree*, tree (*)(tree));
extern bool gimple_signed_integer_sat_add (tree, tree*, tree (*)(tree));
+extern bool gimple_signed_integer_sat_sub (tree, tree*, tree (*)(tree));
static void
build_saturation_binary_arith_call (gimple_stmt_iterator *gsi, internal_fn fn,
* <bb 4> [local count: 1073741824]:
* _1 = .SAT_SUB (x_2(D), y_3(D)); */
static void
-match_unsigned_saturation_sub (gimple_stmt_iterator *gsi, gphi *phi)
+match_saturation_sub (gimple_stmt_iterator *gsi, gphi *phi)
{
if (gimple_phi_num_args (phi) != 2)
return;
tree ops[2];
tree phi_result = gimple_phi_result (phi);
- if (gimple_unsigned_integer_sat_sub (phi_result, ops, NULL))
+ if (gimple_unsigned_integer_sat_sub (phi_result, ops, NULL)
+ || gimple_signed_integer_sat_sub (phi_result, ops, NULL))
build_saturation_binary_arith_call (gsi, phi, IFN_SAT_SUB, phi_result,
ops[0], ops[1]);
}
/* The match_* may remove phi node. */
match_saturation_add (&gsi, psi.phi ());
- match_unsigned_saturation_sub (&gsi, psi.phi ());
+ match_saturation_sub (&gsi, psi.phi ());
}
for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)