Match: Allow more types truncation for .SAT_TRUNC

The .SAT_TRUNC has the input and output types,  aka cvt from
itype to otype and the sizeof (otype) < sizeof (itype).  The
previous patch only allows the sizeof (otype) == sizeof (itype) / 2.
But actually we have 1/4 and 1/8 truncation.

This patch would like to support more types trunction when
sizeof (otype) < sizeof (itype).  The below truncation will be
covered.

* uint64_t => uint8_t
* uint64_t => uint16_t
* uint64_t => uint32_t
* uint32_t => uint8_t
* uint32_t => uint16_t
* uint16_t => uint8_t

The below test suites are passed for this patch:
1. The rv64gcv fully regression tests.
2. The rv64gcv build with glibc.
3. The x86 bootstrap tests.
4. The x86 fully regression tests.

gcc/ChangeLog:

	* match.pd: Allow any otype is less than itype truncation.

Signed-off-by: Pan Li <pan2.li@intel.com>
This commit is contained in:
Pan Li 2024-07-02 08:57:50 +08:00
parent 8d2c460e79
commit 44c767c06b

View file

@ -3239,16 +3239,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(match (unsigned_integer_sat_trunc @0)
(bit_ior:c (negate (convert (gt @0 INTEGER_CST@1)))
(convert @0))
(with {
(if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
&& TYPE_UNSIGNED (TREE_TYPE (@0)))
(with
{
unsigned itype_precision = TYPE_PRECISION (TREE_TYPE (@0));
unsigned otype_precision = TYPE_PRECISION (type);
wide_int trunc_max = wi::mask (itype_precision / 2, false, itype_precision);
wide_int trunc_max = wi::mask (otype_precision, false, itype_precision);
wide_int int_cst = wi::to_wide (@1, itype_precision);
}
(if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
&& TYPE_UNSIGNED (TREE_TYPE (@0))
&& otype_precision < itype_precision
&& wi::eq_p (trunc_max, int_cst)))))
(if (otype_precision < itype_precision && wi::eq_p (trunc_max, int_cst))))))
/* x > y && x != XXX_MIN --> x > y
x > y && x == XXX_MIN --> false . */