On Tue, Sep 5, 2023 at 12:28 AM Jakub Jelinek via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > On Wed, Aug 09, 2023 at 12:19:54PM -0700, Andrew Pinski via Gcc-patches wrote: > > PR tree-optimization/110937 > > PR tree-optimization/100798 > > --- a/gcc/match.pd > > +++ b/gcc/match.pd > > @@ -6460,6 +6460,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > > (if (cmp == NE_EXPR) > > { constant_boolean_node (true, type); }))))))) > > > > +#if GIMPLE > > +/* a?~t:t -> (-(a))^t */ > > +(simplify > > + (cond @0 @1 @2) > > + (if (INTEGRAL_TYPE_P (type) > > + && bitwise_inverted_equal_p (@1, @2)) > > + (with { > > + auto prec = TYPE_PRECISION (type); > > + auto unsign = TYPE_UNSIGNED (type); > > + tree inttype = build_nonstandard_integer_type (prec, unsign); > > + } > > + (convert (bit_xor (negate (convert:inttype @0)) (convert:inttype > > @2)))))) > > +#endif > > This broke one bitint test - bitint-42.c for -O1 and -Os (in admittedly not > yet > committed series). > Using build_nonstandard_integer_type this way doesn't work well for larger > precision BITINT_TYPEs, because it always creates an INTEGER_TYPE and > say 467-bit INTEGER_TYPE doesn't work very well. To get a BITINT_TYPE, one > needs to use build_bitint_type instead (but similarly to > build_nonstandard_integer_type one should first make sure such a type > actually can be created). > > I admit it isn't really clear to me what do you want to achieve by the > above build_nonstandard_integer_type. Is it because of BOOLEAN_TYPE > or perhaps ENUMERAL_TYPE as well?
Yes I was worried about types where the precision was set but MIN/MAX of that type was not over the full precision and would not include both 0 and allones in that range. There is another match.pd pattern where we do a similar thing with calling build_nonstandard_integer_type for a similar reason but because we don't know if the type includes 0, 1, and allones in their range. > > If type is INTEGER_TYPE or BITINT_TYPE, one doesn't really need to create a > new type, type already is an integral type with that precision and > signedness. In other places using unsigned_type_for or signed_type_for > might be better than using build_nonstandard_integer_type if that is what > one wants to achieve, those functions handle BITINT_TYPE. Maybe here we should just use `signed_or_unsigned_type_for (type, TYPE_SIGN (type));` instead of build_nonstandard_integer_type. Thanks, Andrew > > Or shall we instead test for == BOOLEAN_TYPE (or if ENUMERAL_TYPE for > some reason needs the same treatment also || == ENUMERAL_TYPE)? > > 2023-09-05 Jakub Jelinek <ja...@redhat.com> > > PR c/102989 > * match.pd (a ? ~b : b): Don't use build_nonstandard_integer_type > for INTEGER_TYPE or BITINT_TYPE. > > --- gcc/match.pd.jj 2023-09-04 09:45:33.553058301 +0200 > +++ gcc/match.pd 2023-09-05 08:45:53.258078971 +0200 > @@ -6631,7 +6631,9 @@ (define_operator_list SYNC_FETCH_AND_AND > (with { > auto prec = TYPE_PRECISION (type); > auto unsign = TYPE_UNSIGNED (type); > - tree inttype = build_nonstandard_integer_type (prec, unsign); > + tree inttype = type; > + if (TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != BITINT_TYPE) > + inttype = build_nonstandard_integer_type (prec, unsign); > } > (convert (bit_xor (negate (convert:inttype @0)) (convert:inttype > @2))))))) > #endif > > > Jakub >