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

Reply via email to