On Mon, Jun 20, 2022 at 09:36:28AM +0200, Richard Biener wrote: > > --- a/gcc/match.pd > > +++ b/gcc/match.pd > > @@ -2080,6 +2080,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > > (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0)) > > && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0))) > > (op @0 @1)))) > > + > > +/* As a special case, X + C < Y + C is the same as (signed) X < (signed) Y > > + when C is an unsigned integer constant with only the MSB set, and X and > > + Y have types of equal or lower integer conversion rank than C's. */ > > +(for op (lt le ge gt) > > + (simplify > > + (op (plus @1 INTEGER_CST@0) (plus @2 INTEGER_CST@0))
Can't one just omit the INTEGER_CST part on the second @0? > > + (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) > > + && TYPE_UNSIGNED (TREE_TYPE (@0)) > > + && wi::only_sign_bit_p (wi::to_wide (@0))) > > + (with { tree stype = signed_type_for (TREE_TYPE (@0)); } > > + (op (convert:stype @1) (convert:stype @2)))))) As a follow-up, it might be useful to make it work for vector integral types too, typedef unsigned V __attribute__((vector_size (4 * sizeof (int)))); #define M __INT_MAX__ + 1U V foo (V x, V y) { return x + (V) { M, M, M, M } < y + (V) { M, M, M, M }; } using uniform_integer_cst_p. Jakub