/* Unsigned saturation sub, case 1 (branch with gt):
SAT_U_SUB = X > Y ? X - Y : 0 */
(match (unsigned_integer_sat_sub @0 @1)
- (cond (gt @0 @1) (minus @0 @1) integer_zerop)
+ (cond^ (gt @0 @1) (minus @0 @1) integer_zerop)
(if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
&& types_match (type, @0, @1))))
/* 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) (minus @0 @1) integer_zerop)
(if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
&& types_match (type, @0, @1))))
(if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
&& types_match (type, @0, @1))))
+/* Unsigned saturation sub, case 5 (branchless bit_and with .SUB_OVERFLOW). */
+(match (unsigned_integer_sat_sub @0 @1)
+ (bit_and:c (realpart (IFN_SUB_OVERFLOW@2 @0 @1))
+ (plus (imagpart @2) integer_minus_onep))
+ (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
+ && types_match (type, @0, @1))))
+
+/* Unsigned saturation sub, case 6 (branchless mult with .SUB_OVERFLOW). */
+(match (unsigned_integer_sat_sub @0 @1)
+ (mult:c (realpart (IFN_SUB_OVERFLOW@2 @0 @1))
+ (bit_xor (imagpart @2) integer_onep))
+ (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
+ && types_match (type, @0, @1))))
+
+/* Unsigned saturation sub, case 7 (branch with .SUB_OVERFLOW). */
+(match (unsigned_integer_sat_sub @0 @1)
+ (cond^ (eq (imagpart (IFN_SUB_OVERFLOW@2 @0 @1)) integer_zerop)
+ (realpart @2) integer_zerop)
+ (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
+ && types_match (type, @0, @1))))
+
/* x > y && x != XXX_MIN --> x > y
x > y && x == XXX_MIN --> false . */
(for eqne (eq ne)
build_saturation_binary_arith_call (gsi, IFN_SAT_SUB, lhs, ops[0], ops[1]);
}
+/*
+ * Try to match saturation unsigned sub.
+ * <bb 2> [local count: 1073741824]:
+ * if (x_2(D) > y_3(D))
+ * goto <bb 3>; [50.00%]
+ * else
+ * goto <bb 4>; [50.00%]
+ *
+ * <bb 3> [local count: 536870912]:
+ * _4 = x_2(D) - y_3(D);
+ *
+ * <bb 4> [local count: 1073741824]:
+ * # _1 = PHI <0(2), _4(3)>
+ * =>
+ * <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)
+{
+ 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))
+ build_saturation_binary_arith_call (gsi, phi, IFN_SAT_SUB, phi_result,
+ ops[0], ops[1]);
+}
+
/* Recognize for unsigned x
x = y - z;
if (x > y)
{
gimple_stmt_iterator gsi = gsi_after_labels (bb);
match_unsigned_saturation_add (&gsi, psi.phi ());
+ match_unsigned_saturation_sub (&gsi, psi.phi ());
}
for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)
continue;
}
match_arith_overflow (&gsi, stmt, code, m_cfg_changed_p);
+ match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt));
break;
case PLUS_EXPR:
break;
case COND_EXPR:
+ case BIT_AND_EXPR:
match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt));
break;