On Sat, Jul 1, 2023 at 10:23 AM Andrew Pinski via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > The problem here is we might produce some values out of the type's > min/max (and/or valid values, e.g. signed booleans). The fix is to > use an integer type which has the same precision and signedness > as the original type. > > Note two_value_replacement in phiopt had the same issue in previous > versions; though I don't know if a problem will show up there. > > OK? Bootstrapped and tested on x86_64-linux-gnu.
OK. > gcc/ChangeLog: > > PR tree-optimization/110487 > * match.pd (a !=/== CST1 ? CST2 : CST3): Always > build a nonstandard integer and use that. > --- > gcc/match.pd | 24 ++++++++---------------- > 1 file changed, 8 insertions(+), 16 deletions(-) > > diff --git a/gcc/match.pd b/gcc/match.pd > index a0d114f6a16..9748ad8466e 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -4797,24 +4797,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > tree type1; > if ((eqne == EQ_EXPR) ^ (wi::to_wide (@1) == min)) > std::swap (arg0, arg1); > - if (TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (type)) > - { > - /* Avoid performing the arithmetics in bool type which has > different > - semantics, otherwise prefer unsigned types from the two with > - the same precision. */ > - if (TREE_CODE (TREE_TYPE (arg0)) == BOOLEAN_TYPE > - || !TYPE_UNSIGNED (type)) > - type1 = TREE_TYPE (@0); > - else > - type1 = TREE_TYPE (arg0); > - } > - else if (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (type)) > + if (TYPE_PRECISION (TREE_TYPE (@0)) > TYPE_PRECISION (type)) > type1 = TREE_TYPE (@0); > else > type1 = type; > - min = wide_int::from (min, TYPE_PRECISION (type1), > + auto prec = TYPE_PRECISION (type1); > + auto unsign = TYPE_UNSIGNED (type1); > + type1 = build_nonstandard_integer_type (prec, unsign); > + min = wide_int::from (min, prec, > TYPE_SIGN (TREE_TYPE (@0))); > - wide_int a = wide_int::from (wi::to_wide (arg0), TYPE_PRECISION > (type1), > + wide_int a = wide_int::from (wi::to_wide (arg0), prec, > TYPE_SIGN (type)); > enum tree_code code; > wi::overflow_type ovf; > @@ -4822,7 +4814,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > { > code = PLUS_EXPR; > a -= min; > - if (!TYPE_UNSIGNED (type1)) > + if (!unsign) > { > /* lhs is known to be in range [min, min+1] and we want to add > a > to it. Check if that operation can overflow for those 2 > values > @@ -4836,7 +4828,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > { > code = MINUS_EXPR; > a += min; > - if (!TYPE_UNSIGNED (type1)) > + if (!unsign) > { > /* lhs is known to be in range [min, min+1] and we want to > subtract > it from a. Check if that operation can overflow for those 2 > -- > 2.31.1 >