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?

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.

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