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
>

Reply via email to