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*"
> 
>

Reply via email to