On Sat, Sep 30, 2023 at 11:44:59AM +0200, Jakub Jelinek wrote: > I really can't figure out why one would need to add extra casts. > type must be an integral type which has BIT_NOT_EXPR applied on it > which yields all ones and we need a type in which negating 0 or 1 > range will yield 0 or all ones, I think all integral types satisfy > that. > This fixes PR111369, where one of the bitint*.c tests FAILs with > GCC_TEST_RUN_EXPENSIVE=1.
Though, I think there is an preexisting issue which the build_nonstandard_integer_type didn't help with; if type is signed 1-bit precision, then I think a ? ~t : t could be valid, but -(type)a would invoke UB if a is 1 - the cast would make it -1 and negation of -1 in signed 1-bit invokes UB. So perhaps we should guard this optimization on type having element precision > 1 or being unsigned. Plus the (convert:type @2) didn't make sense, @2 already must have TREE_TYPE type. So untested patch would be then: 2023-09-29 Jakub Jelinek <ja...@redhat.com> PR middle-end/111369 * match.pd (a?~t:t -> (-(a))^t): Always convert to type rather than using build_nonstandard_integer_type. Punt if type is signed 1-bit precision type. --- gcc/match.pd.jj 2023-09-29 18:58:42.724956659 +0200 +++ gcc/match.pd 2023-09-30 11:54:16.603280666 +0200 @@ -6741,13 +6741,9 @@ (define_operator_list SYNC_FETCH_AND_AND (with { bool wascmp; } (if (INTEGRAL_TYPE_P (type) && bitwise_inverted_equal_p (@1, @2, wascmp) - && (!wascmp || element_precision (type) == 1)) - (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))))))) + && (!wascmp || element_precision (type) == 1) + && (!TYPE_OVERFLOW_WRAPS (type) || element_precision (type) > 1)) + (bit_xor (negate (convert:type @0)) @2)))) #endif /* Simplify pointer equality compares using PTA. */ Jakub