On Thu, 26 Sep 2019, Eric Botcazou wrote:

> > I see.  So I misremember seeing aggregate typed BIT_FIELD_REFs
> > (that was probably VIEW_CONVERTs then...).  Still the GIMPLE verifier
> > only has
> > 
> >           else if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
> >                    && TYPE_MODE (TREE_TYPE (expr)) != BLKmode
> >                    && maybe_ne (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE
> > (expr))),
> >                                 size))
> >             {
> >               error ("mode size of non-integral result does not "
> >                      "match field size of %qs",
> >                      code_name);
> >               return true;
> >             }
> > 
> > it doesn't verify that besides integral typed expressions only
> > vector typed expressions are allowed.
> 
> I think that the !INTEGRAL_TYPE_P is simply the opposite of the first case:
> 
>         if (INTEGRAL_TYPE_P (TREE_TYPE (t))
>             && maybe_ne (TYPE_PRECISION (TREE_TYPE (t)), size))
>           {
>             error ("integral result type precision does not match "
>                    "field size of BIT_FIELD_REF");
>             return t;
>           }
> 
> > Anyhow - the original patch succeeded bootstrapping and testing.
> > The way I proposed it:
> > 
> >       /* For vector types, with the correct size of access, use the mode
> > of
> >          inner type.  */
> >       if (((TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == VECTOR_TYPE
> >             && TREE_TYPE (exp) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp,
> > 0))))
> > 
> >            || !INTEGRAL_TYPE_P (TREE_TYPE (exp)))
> > 
> >           && tree_int_cst_equal (size_tree, TYPE_SIZE (TREE_TYPE (exp))))
> >         mode = TYPE_MODE (TREE_TYPE (exp));
> > 
> > matches in sofar that we only restrict integer types (not modes) and
> > for integer types allow extracts from vectors (the preexisting
> > check for a matching component type is a bit too strict I guess).
> 
> IMO if the !VECTOR_TYPE case cannot be covered, changes in this delicate area 
> ought to be restricted to VECTOR_TYPE.

OK, so I'm testing the following then, simply adding the VECTOR_TYPE_P
case in addition to the existing one plus adjusting the comment
accordingly.

Bootstrap / regtest running on x86_64-unknown-linux-gnu, OK if that 
passes?

Thanks,
Richard.

2019-09-26  Richard Biener  <rguent...@suse.de>

        PR middle-end/91897
        * expr.c (get_inner_reference): For BIT_FIELD_REF with
        vector type retain the original mode.

        * gcc.target/i386/pr91897.c: New testcase.

Index: gcc/testsuite/gcc.target/i386/pr91897.c
===================================================================
--- gcc/testsuite/gcc.target/i386/pr91897.c     (nonexistent)
+++ gcc/testsuite/gcc.target/i386/pr91897.c     (working copy)
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+
+typedef double Double16 __attribute__((vector_size(8*16)));
+
+void mult(Double16 *res, const Double16 *v1, const Double16 *v2)
+{
+  *res = *v1 * *v2;
+}
+
+/* We want 4 ymm loads and 4 ymm stores.  */
+/* { dg-final { scan-assembler-times "movapd" 8 } } */
Index: gcc/expr.c
===================================================================
--- gcc/expr.c  (revision 276147)
+++ gcc/expr.c  (working copy)
@@ -7230,12 +7230,13 @@ get_inner_reference (tree exp, poly_int6
       *punsignedp = (! INTEGRAL_TYPE_P (TREE_TYPE (exp))
                     || TYPE_UNSIGNED (TREE_TYPE (exp)));
 
-      /* For vector types, with the correct size of access, use the mode of
-        inner type.  */
-      if (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == VECTOR_TYPE
-         && TREE_TYPE (exp) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)))
-         && tree_int_cst_equal (size_tree, TYPE_SIZE (TREE_TYPE (exp))))
-        mode = TYPE_MODE (TREE_TYPE (exp));
+      /* For vector element types with the correct size of access or for
+         vector typed accesses use the mode of the access type.  */
+      if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == VECTOR_TYPE
+          && TREE_TYPE (exp) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)))
+          && tree_int_cst_equal (size_tree, TYPE_SIZE (TREE_TYPE (exp))))
+         || VECTOR_TYPE_P (TREE_TYPE (exp)))
+       mode = TYPE_MODE (TREE_TYPE (exp));
     }
   else
     {

Reply via email to