Hi! The last case of this optimization assumes that if 2 integral types have same precision and TYPE_UNSIGNED, then they are uselessly convertible. While that is very likely the case for GIMPLE, it is not the case for GENERIC, so the following patch adds there a convert so that the optimization produces also valid GENERIC. Without it we got (int) p == b where b had _BitInt(32) type, so incompatible types.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2025-01-17 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/118522 * match.pd ((FTYPE) N CMP (FTYPE) M): Add convert, as in GENERIC integral types with the same precision and sign might actually not be compatible types. * gcc.dg/bitint-120.c: New test. --- gcc/match.pd.jj 2025-01-16 09:09:06.000000000 +0100 +++ gcc/match.pd 2025-01-16 19:24:16.838305254 +0100 @@ -7253,7 +7253,7 @@ (define_operator_list SYNC_FETCH_AND_AND (icmp (convert:type2 @1) @2) (if (TYPE_PRECISION (type1) == TYPE_PRECISION (type2) && type1_signed_p == type2_signed_p) - (icmp @1 @2)))))))))) + (icmp @1 (convert @2))))))))))) /* Optimize various special cases of (FTYPE) N CMP CST. */ (for cmp (lt le eq ne ge gt) --- gcc/testsuite/gcc.dg/bitint-120.c.jj 2025-01-16 19:30:14.816518100 +0100 +++ gcc/testsuite/gcc.dg/bitint-120.c 2025-01-16 19:29:56.429763982 +0100 @@ -0,0 +1,11 @@ +/* PR tree-optimization/118522 */ +/* { dg-do compile { target bitint } } */ +/* { dg-options "-O2" } */ + +_BitInt(32) b; + +int +foo (unsigned short p) +{ + return p == (double) b; +} Jakub