Fix PR92803
diff mbox series

Message ID nycvar.YFH.7.76.1912051041540.5566@zhemvz.fhfr.qr
State New
Headers show
Series
  • Fix PR92803
Related show

Commit Message

Richard Biener Dec. 5, 2019, 9:42 a.m. UTC
The following patch fixes invariant vector construction in vector CTOR
optimization.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

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.

Patch
diff mbox series

Index: gcc/tree-ssa-forwprop.c
===================================================================
--- gcc/tree-ssa-forwprop.c	(revision 278985)
+++ gcc/tree-ssa-forwprop.c	(working copy)
@@ -2286,24 +2286,28 @@  simplify_vector_constructor (gimple_stmt
       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)
Index: gcc/testsuite/gcc.target/i386/pr92803.c
===================================================================
--- gcc/testsuite/gcc.target/i386/pr92803.c	(revision 0)
+++ gcc/testsuite/gcc.target/i386/pr92803.c	(working copy)
@@ -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 *-*-* } } } */