diff options
author | Jakub Jelinek <jakub@redhat.com> | 2020-06-08 11:05:10 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2020-06-08 11:05:10 +0200 |
commit | 8be374e02761c9d63d2753d71e4bd4874a1577b1 (patch) | |
tree | e5c255a79cc9cac5ee35611d8ab5aa9beae861cb | |
parent | 296d644b9f526e44fbe574426f24799c1d545fd3 (diff) | |
download | gcc-8be374e02761c9d63d2753d71e4bd4874a1577b1.zip gcc-8be374e02761c9d63d2753d71e4bd4874a1577b1.tar.gz gcc-8be374e02761c9d63d2753d71e4bd4874a1577b1.tar.bz2 |
forwprop: Ignore scalar mode vectors in simplify_vector_constructor [PR95528]
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.
2020-06-08 Jakub Jelinek <jakub@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.
-rw-r--r-- | gcc/testsuite/g++.dg/opt/pr95528.C | 27 | ||||
-rw-r--r-- | gcc/tree-ssa-forwprop.c | 11 |
2 files changed, 38 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/opt/pr95528.C b/gcc/testsuite/g++.dg/opt/pr95528.C new file mode 100644 index 0000000..6407329 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr95528.C @@ -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); } diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 759baf5..494c9e9 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -2401,6 +2401,10 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) && (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_iterator *gsi) && (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)) |