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.
This commit is contained in:
Jakub Jelinek 2020-06-08 11:05:10 +02:00
parent 296d644b9f
commit 8be374e027
2 changed files with 38 additions and 0 deletions

View File

@ -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); }

View File

@ -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))