Hi!

As mentioned in the PR, the problem is that at least the x86 backend asumes
that the vec_unpack* and vec_pack* optabs with integral modes are for the
AVX512-ish vector masks rather than for very small vectors done in GPRs.
The only other target that seems to have a scalar mode vec_{,un}pack* optab
is aarch64 as discussed in the PR, so there is also a condition for that.
All other targets have just vector mode optabs.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2020-06-08  Jakub Jelinek  <ja...@redhat.com>

        PR target/95528
        * tree-ssa-forwprop.c (simplify_vector_constructor): Don't use
        VEC_UNPACK*_EXPR or VEC_PACK_TRUNC_EXPR with scalar modes unless the
        type is vector boolean.

        * g++.dg/opt/pr95528.C: New test.

--- gcc/tree-ssa-forwprop.c.jj  2020-05-26 09:28:53.244149208 +0200
+++ gcc/tree-ssa-forwprop.c     2020-06-05 13:10:26.992648945 +0200
@@ -2401,6 +2401,10 @@ simplify_vector_constructor (gimple_stmt
              && (dblvectype
                  = build_vector_type (TREE_TYPE (TREE_TYPE (orig[0])),
                                       nelts * 2))
+             /* Only use it for vector modes or for vector booleans represented
+                as scalar bitmasks.  See PR95528.  */
+             && (VECTOR_MODE_P (TYPE_MODE (dblvectype))
+                 || VECTOR_BOOLEAN_TYPE_P (dblvectype))
              && (optab = optab_for_tree_code (FLOAT_TYPE_P (TREE_TYPE (type))
                                               ? VEC_UNPACK_FLOAT_LO_EXPR
                                               : VEC_UNPACK_LO_EXPR,
@@ -2442,6 +2446,13 @@ simplify_vector_constructor (gimple_stmt
                   && (halfvectype
                         = build_vector_type (TREE_TYPE (TREE_TYPE (orig[0])),
                                              nelts / 2))
+                  /* Only use it for vector modes or for vector booleans
+                     represented as scalar bitmasks, or allow halfvectype
+                     be the element mode.  See PR95528.  */
+                  && (VECTOR_MODE_P (TYPE_MODE (halfvectype))
+                      || VECTOR_BOOLEAN_TYPE_P (halfvectype)
+                      || (TYPE_MODE (halfvectype)
+                          == TYPE_MODE (TREE_TYPE (halfvectype))))
                   && (optab = optab_for_tree_code (VEC_PACK_TRUNC_EXPR,
                                                    halfvectype,
                                                    optab_default))
--- gcc/testsuite/g++.dg/opt/pr95528.C.jj       2020-06-05 13:13:17.137165849 
+0200
+++ gcc/testsuite/g++.dg/opt/pr95528.C  2020-06-05 13:13:13.144224118 +0200
@@ -0,0 +1,27 @@
+// PR target/95528
+// { dg-do compile { target c++11 } }
+// { dg-options "-O3" }
+// { dg-additional-options "-march=skylake-avx512" { target i?86-*-*- 
x86_64-*-* } }
+
+template <typename a> struct b {
+  typedef a c __attribute__((vector_size(sizeof(a) * 4)));
+  union {
+    c d;
+    struct {
+      a e, f, g, h;
+    };
+  };
+  b();
+  b(const b &i) : d(i.d) {}
+  static b j(c);
+  template <typename k> operator b<k>() {
+    b<k>::j(typename b<k>::c{k(e), k(f), k(g), k(h)});
+    return b<k>();
+  }
+};
+template <typename a> using l = b<a>;
+using m = l<char>;
+using n = l<short>;
+m o(n i) { return i; }
+b<short> q;
+void p() { o(q); }

        Jakub

Reply via email to