On Thu, Dec 12, 2024 at 9:45 AM <pan2...@intel.com> wrote: > > From: Pan Li <pan2...@intel.com> > > This patch would like to refactor the all signed SAT_TRUNC patterns, > aka: > * Extract type check outside. > * Re-arrange the related match pattern forms together. > > The below test suites are passed for this patch. > * The rv64gcv fully regression test. > * The x86 bootstrap test. > * The x86 fully regression test.
OK. > gcc/ChangeLog: > > * match.pd: Refactor sorts of signed SAT_TRUNC match patterns > > Signed-off-by: Pan Li <pan2...@intel.com> > --- > gcc/match.pd | 65 ++++++++++++++++++++++++++-------------------------- > 1 file changed, 32 insertions(+), 33 deletions(-) > > diff --git a/gcc/match.pd b/gcc/match.pd > index 1ef504f141f..5b30a1e9990 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -3415,6 +3415,38 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (realpart @2)) > (if (types_match (type, @0, @1))))) > > +(if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type)) > + (match (signed_integer_sat_trunc @0) > + /* SAT_S_TRUNC(X) = (unsigned)X + NT_MAX + 1 > Unsigned_MAX ? (NT)X */ > + (cond^ (gt (plus:c (convert@4 @0) INTEGER_CST@1) INTEGER_CST@2) > + (bit_xor:c (nop_convert? > + (negate (nop_convert? (convert (lt @0 integer_zerop))))) > + INTEGER_CST@3) > + (convert @0)) > + (if (!TYPE_UNSIGNED (TREE_TYPE (@0)) && TYPE_UNSIGNED (TREE_TYPE (@4))) > + (with > + { > + unsigned itype_prec = TYPE_PRECISION (TREE_TYPE (@0)); > + unsigned otype_prec = TYPE_PRECISION (type); > + wide_int offset = wi::uhwi (HOST_WIDE_INT_1U << (otype_prec - 1), > + itype_prec); // Aka 128 for int8_t > + wide_int limit_0 = wi::mask (otype_prec, false, itype_prec); // Aka 255 > + wide_int limit_1 = wi::uhwi ((HOST_WIDE_INT_1U << otype_prec) - 3, > + itype_prec); // Aka 253 > + wide_int limit_2 = wi::uhwi ((HOST_WIDE_INT_1U << otype_prec) - 2, > + itype_prec); // Aka 254 > + wide_int otype_max = wi::mask (otype_prec - 1, false, otype_prec); > + wide_int itype_max = wi::mask (otype_prec - 1, false, itype_prec); > + wide_int int_cst_1 = wi::to_wide (@1); > + wide_int int_cst_2 = wi::to_wide (@2); > + wide_int int_cst_3 = wi::to_wide (@3); > + } > + (if (((wi::eq_p (int_cst_1, offset) && wi::eq_p (int_cst_2, limit_0)) > + || (wi::eq_p (int_cst_1, itype_max) && wi::eq_p (int_cst_2, limit_2)) > + || (wi::eq_p (int_cst_1, offset) && wi::eq_p (int_cst_2, limit_2)) > + || (wi::eq_p (int_cst_1, itype_max) && wi::eq_p (int_cst_2, > limit_1))) > + && wi::eq_p (int_cst_3, otype_max))))))) > + > /* The boundary condition for case 10: IMM = 1: > SAT_U_SUB = X >= IMM ? (X - IMM) : 0. > simplify (X != 0 ? X + ~0 : 0) to X - (X != 0). */ > @@ -3426,39 +3458,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (with { tree itype = TREE_TYPE (@2); } > (convert (minus @2 (convert:itype @1)))))) > > -/* Signed saturation truncate, case 1 and case 2, sizeof (WT) > sizeof (NT). > - SAT_S_TRUNC(X) = (unsigned)X + NT_MAX + 1 > Unsigned_MAX ? (NT)X. */ > -(match (signed_integer_sat_trunc @0) > - (cond^ (gt (plus:c (convert@4 @0) INTEGER_CST@1) INTEGER_CST@2) > - (bit_xor:c (nop_convert? > - (negate (nop_convert? (convert (lt @0 integer_zerop))))) > - INTEGER_CST@3) > - (convert @0)) > - (if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type) > - && !TYPE_UNSIGNED (TREE_TYPE (@0)) && TYPE_UNSIGNED (TREE_TYPE (@4))) > - (with > - { > - unsigned itype_prec = TYPE_PRECISION (TREE_TYPE (@0)); > - unsigned otype_prec = TYPE_PRECISION (type); > - wide_int offset = wi::uhwi (HOST_WIDE_INT_1U << (otype_prec - 1), > - itype_prec); // Aka 128 for int8_t > - wide_int limit_0 = wi::mask (otype_prec, false, itype_prec); // Aka 255 > - wide_int limit_1 = wi::uhwi ((HOST_WIDE_INT_1U << otype_prec) - 3, > - itype_prec); // Aka 253 > - wide_int limit_2 = wi::uhwi ((HOST_WIDE_INT_1U << otype_prec) - 2, > - itype_prec); // Aka 254 > - wide_int otype_max = wi::mask (otype_prec - 1, false, otype_prec); > - wide_int itype_max = wi::mask (otype_prec - 1, false, itype_prec); > - wide_int int_cst_1 = wi::to_wide (@1); > - wide_int int_cst_2 = wi::to_wide (@2); > - wide_int int_cst_3 = wi::to_wide (@3); > - } > - (if (((wi::eq_p (int_cst_1, offset) && wi::eq_p (int_cst_2, limit_0)) > - || (wi::eq_p (int_cst_1, itype_max) && wi::eq_p (int_cst_2, limit_2)) > - || (wi::eq_p (int_cst_1, offset) && wi::eq_p (int_cst_2, limit_2)) > - || (wi::eq_p (int_cst_1, itype_max) && wi::eq_p (int_cst_2, > limit_1))) > - && wi::eq_p (int_cst_3, otype_max)))))) > - > /* x > y && x != XXX_MIN --> x > y > x > y && x == XXX_MIN --> false . */ > (for eqne (eq ne) > -- > 2.43.0 >