https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113988
--- Comment #20 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to rguent...@suse.de from comment #19) > I think the usual BLKmode check would be better here? Apart from > that this looks correct, we shouldn't use a regular convert on > a non-register type. In fact, it looks like all bitint types are > register types because we want SSA names for them. A bit of a > "bad" design ... > > We've used BLKmode checks elsewhere so I think it would be appropriate > here, too. But we don't want to disallow turning VIEW_CONVERT_EXPR from one _BitInt to another _BitInt of the same size, even if they both have BLKmode. So, if we'd use BLKmode check, it would need to be one of the types is INTEGER_TYPE and the other type is BLKmode BITINT_TYPE (or vice versa). Or shall the test be TYPE_MODE (type) == TYPE_MODE (TREE_TYPE (@0)) regardless of precision? Or it could be the mode check && at least one of the involved types is BITINT_TYPE, that would maintain existing behavior when _BitInt isn't involved. The #c18 patch passed bootstrap/regtest, the following: 2024-02-22 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/113988 * match.pd (view_convert -> convert): Punt for VCEs involving BITINT_TYPEs if there is mode mismatch. * gcc.dg/bitint-91.c: New test. --- gcc/match.pd.jj 2024-02-19 09:42:16.583617451 +0100 +++ gcc/match.pd 2024-02-22 09:00:34.302420089 +0100 @@ -4679,7 +4679,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (view_convert @0) (if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)) && (INTEGRAL_TYPE_P (TREE_TYPE (@0)) || POINTER_TYPE_P (TREE_TYPE (@0))) - && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (@0))) + && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (@0)) + /* Punt for conversions with mode mismatches if BITINT_TYPEs are + involved. */ + && (TYPE_MODE (type) == TYPE_MODE (TREE_TYPE (@0)) + || (TREE_CODE (type) != BITINT_TYPE + && TREE_CODE (TREE_TYPE (@0)) != BITINT_TYPE))) (convert @0))) /* Strip inner integral conversions that do not change precision or size, or --- gcc/testsuite/gcc.dg/bitint-91.c.jj 2024-02-21 13:47:55.244885020 +0100 +++ gcc/testsuite/gcc.dg/bitint-91.c 2024-02-21 12:51:16.900026979 +0100 @@ -0,0 +1,38 @@ +/* PR tree-optimization/113988 */ +/* { dg-do compile { target bitint } } */ +/* { dg-options "-O2" } */ +/* { dg-additional-options "-mavx512f" { target i?86-*-* x86_64-*-* } } */ + +int i; + +#if __BITINT_MAXWIDTH__ >= 256 +void +foo (void *p, _BitInt(256) x) +{ + __builtin_memcpy (p, &x, sizeof x); +} + +_BitInt(256) +bar (void *p, _BitInt(256) x) passed make check-gcc check-g++ -j32 -k GCC_TEST_RUN_EXPENSIVE=1 RUNTESTFLAGS="GCC_TEST_RUN_EXPENSIVE=1 dg.exp='*bitint* pr112673.c builtin-stdc-bit-*.c pr112566-2.c pr112511.c' dg-torture.exp=*bitint* dfp.exp=*bitint*"