https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113988
--- Comment #21 from rguenther at suse dot de <rguenther at suse dot de> --- On Thu, 22 Feb 2024, jakub at gcc dot gnu.org wrote: > 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)) I like the mode check and I think we should avoid the transform also for non-bit-int in case the mode differs, I can only think of odd partial-int vs int mode cases here with pointer vs. integer? > + || (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*" > >