aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2019-12-05 09:45:46 +0000
committerRichard Biener <rguenther@suse.de>2019-12-05 09:45:46 +0000
commit40c72a264df777f3d80928f58e06ca1bc30ff285 (patch)
treedda93429be6382ac5c36b78294568cd9e9e898be
parent47b69accc5c3d0c073be0528043beddf619894aa (diff)
2019-12-05 Richard Biener <rguenther@suse.de>
PR tree-optimization/92803 * tree-ssa-forwprop.c (simplify_vector_constructor): Fix invariant vector construction. * gcc.target/i386/pr92803.c: New testcase. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@278991 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr92803.c38
-rw-r--r--gcc/tree-ssa-forwprop.c18
4 files changed, 60 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b736bb291d4..f17fc102a07 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2019-12-05 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/92803
+ * tree-ssa-forwprop.c (simplify_vector_constructor): Fix
+ invariant vector construction.
+
2019-12-05 Martin Liska <mliska@suse.cz>
PR gcov-profile/91971
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 89066e87356..b075e7e3eab 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-12-05 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/92803
+ * gcc.target/i386/pr92803.c: New testcase.
+
2019-12-05 Jakub Jelinek <jakub@redhat.com>
PR fortran/92781
diff --git a/gcc/testsuite/gcc.target/i386/pr92803.c b/gcc/testsuite/gcc.target/i386/pr92803.c
new file mode 100644
index 00000000000..fc8d64efb83
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr92803.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wno-psabi -mavx2 -fdump-tree-forwprop1" } */
+
+typedef double v4df __attribute__((vector_size (32)));
+typedef float v8sf __attribute__((vector_size (32)));
+typedef float v4sf __attribute__((vector_size (16)));
+typedef int v4si __attribute__((vector_size (16)));
+typedef double v2df __attribute__((vector_size (16)));
+
+v2df
+foo (v4df x, double *p, v2df y)
+{
+ return (v2df) { x[3], *p };
+}
+
+v4sf
+bar (v4si x, float *p)
+{
+ return (v4sf) { x[0], x[1], x[2], *p };
+}
+
+v4sf
+baz (v4si x)
+{
+ return (v4sf) { x[0], x[1], 3.0f, 1.0f };
+}
+
+v4sf
+barf (v8sf x)
+{
+ return (v4sf) { x[4], x[5], 1.0f, 2.0f };
+}
+
+/* We expect all CTORs to turn into permutes, the FP converting ones
+ to two each with the one with constants possibly elided in the future
+ by converting 3.0f and 1.0f "back" to integers. */
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 6 "forwprop1" } } */
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 5 "forwprop1" { xfail *-*-* } } } */
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 4a831242c0e..a27a4cfb379 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -2286,24 +2286,28 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
else if (orig[1] == error_mark_node
&& one_nonconstant)
{
- orig[1] = gimple_build_vector_from_val (&stmts, UNKNOWN_LOCATION,
- type, one_nonconstant);
/* ??? We can see if we can safely convert to the original
element type. */
converted_orig1 = conv_code != ERROR_MARK;
+ orig[1] = gimple_build_vector_from_val (&stmts, UNKNOWN_LOCATION,
+ converted_orig1
+ ? type : perm_type,
+ one_nonconstant);
}
else if (orig[1] == error_mark_node)
{
- tree_vector_builder vec (type, nelts, 1);
- for (unsigned i = 0; i < nelts; ++i)
- if (constants[i])
+ /* ??? See if we can convert the vector to the original type. */
+ converted_orig1 = conv_code != ERROR_MARK;
+ unsigned n = converted_orig1 ? nelts : refnelts;
+ tree_vector_builder vec (converted_orig1
+ ? type : perm_type, n, 1);
+ for (unsigned i = 0; i < n; ++i)
+ if (i < nelts && constants[i])
vec.quick_push (constants[i]);
else
/* ??? Push a don't-care value. */
vec.quick_push (one_constant);
orig[1] = vec.build ();
- /* ??? See if we can convert the vector to the original type. */
- converted_orig1 = conv_code != ERROR_MARK;
}
tree blend_op2 = NULL_TREE;
if (converted_orig1)