(bit_xor:c @0 INTEGER_CST@3)) integer_zerop)
(signed_integer_sat_val @0)
@2)
- (if (wi::bit_and (wi::to_wide (@1), wi::to_wide (@3)) == 0))))
+ (if (wi::bit_and (wi::to_wide (@1), wi::to_wide (@3)) == 0)))
+
+(match (signed_integer_sat_add @0 @1)
+ /* T SUM = (T)((UT)X + (UT)-1);
+ SAT_S_ADD = (X ^ -1) < 0 ? SUM : (X ^ SUM) >= 0 ? SUM
+ : (x < 0) ? MIN : MAX */
+ (convert (cond^ (lt (bit_and:c @0 (nop_convert (negate (nop_convert @0))))
+ integer_zerop)
+ INTEGER_CST@2
+ (plus (nop_convert @0) integer_all_onesp@1)))
+ (with
+ {
+ unsigned precision = TYPE_PRECISION (type);
+ wide_int c1 = wi::to_wide (@1);
+ wide_int c2 = wi::to_wide (@2);
+ wide_int sum = wi::add (c1, c2);
+ }
+ (if (wi::eq_p (sum, wi::max_value (precision, SIGNED)))))))
/* Saturation sub for signed integer. */
(if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type))
* _10 = -_9;
* _12 = _7 | _10;
* =>
- * _12 = .SAT_ADD (_4, _6); */
+ * _12 = .SAT_ADD (_4, _6);
+ *
+ * Try to match IMM=-1 saturation signed add with assign.
+ * <bb 2> [local count: 1073741824]:
+ * x.0_1 = (unsigned char) x_5(D);
+ * _3 = -x.0_1;
+ * _10 = (signed char) _3;
+ * _8 = x_5(D) & _10;
+ * if (_8 < 0)
+ * goto <bb 4>; [1.40%]
+ * else
+ * goto <bb 3>; [98.60%]
+ * <bb 3> [local count: 434070867]:
+ * _2 = x.0_1 + 255;
+ * <bb 4> [local count: 1073741824]:
+ * # _9 = PHI <_2(3), 128(2)>
+ * _4 = (int8_t) _9;
+ * =>
+ * _4 = .SAT_ADD (x_5, -1); */
static void
-match_unsigned_saturation_add (gimple_stmt_iterator *gsi, gassign *stmt)
+match_saturation_add_with_assign (gimple_stmt_iterator *gsi, gassign *stmt)
{
tree ops[2];
tree lhs = gimple_assign_lhs (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))
build_saturation_binary_arith_call_and_replace (gsi, IFN_SAT_ADD, lhs,
ops[0], ops[1]);
}
break;
case PLUS_EXPR:
- match_unsigned_saturation_add (&gsi, as_a<gassign *> (stmt));
+ match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt));
match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt));
/* fall-through */
case MINUS_EXPR:
break;
case BIT_IOR_EXPR:
- match_unsigned_saturation_add (&gsi, as_a<gassign *> (stmt));
+ match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt));
match_unsigned_saturation_trunc (&gsi, as_a<gassign *> (stmt));
/* fall-through */
case BIT_XOR_EXPR:
case NOP_EXPR:
match_unsigned_saturation_trunc (&gsi, as_a<gassign *> (stmt));
+ match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt));
break;
default:;