re PR tree-optimization/63379 (Incorrect vectorization when enabling SSE and O3,...
authorRichard Biener <rguenther@suse.de>
Fri, 10 Oct 2014 11:17:13 +0000 (11:17 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 10 Oct 2014 11:17:13 +0000 (11:17 +0000)
2014-10-10  Richard Biener  <rguenther@suse.de>

PR tree-optimization/63379
* tree-vect-slp.c (vect_get_constant_vectors): Do not compute
a neutral operand for min/max when it is not a reduction chain.

* gcc.dg/vect/pr63379.c: New testcase.

From-SVN: r216070

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/pr63379.c [new file with mode: 0644]
gcc/tree-vect-slp.c

index dbee77683b7eb8ae802d53183aed985fdd17257c..a42593f960ee232ddafd1341373e6f286a5e1731 100644 (file)
@@ -1,3 +1,9 @@
+2014-10-10  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/63379
+       * tree-vect-slp.c (vect_get_constant_vectors): Do not compute
+       a neutral operand for min/max when it is not a reduction chain.
+
 2014-10-10  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/63476
index d9e93d352a9e4439ad82aacd3e7caa595c5d13cd..632aa84af6a00feb15b7399c70c2d1e8cdeb17fe 100644 (file)
@@ -1,3 +1,8 @@
+2014-10-10  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/63379
+       * gcc.dg/vect/pr63379.c: New testcase.
+
 2014-10-10  Jakub Jelinek  <jakub@redhat.com>
 
        PR fortran/59488
diff --git a/gcc/testsuite/gcc.dg/vect/pr63379.c b/gcc/testsuite/gcc.dg/vect/pr63379.c
new file mode 100644 (file)
index 0000000..f6e8fc6
--- /dev/null
@@ -0,0 +1,43 @@
+/* PR tree-optimization/63379  */
+/* { dg-do run } */
+
+#include "tree-vect.h"
+
+extern void abort (void);
+
+typedef struct {
+    int x;
+    int y;
+} Point;
+
+Point pt_array[25];
+
+void __attribute__((noinline,noclone))
+generate_array(void)
+{
+  unsigned int i;
+  for (i = 0; i<25; i++)
+    {
+      pt_array[i].x = i;
+      pt_array[i].y = 1000+i;
+    }
+}
+
+int main()
+{
+  check_vect ();
+  generate_array ();
+  Point min_pt = pt_array[0];
+  Point *ptr, *ptr_end;
+  for (ptr = pt_array+1, ptr_end = pt_array+25; ptr != ptr_end; ++ptr)
+    {
+      min_pt.x = (min_pt.x < ptr->x) ? min_pt.x : ptr->x;
+      min_pt.y = (min_pt.y < ptr->y) ? min_pt.y : ptr->y;
+    }
+
+  if (min_pt.x != 0 || min_pt.y != 1000)
+    abort ();
+  return 0;
+}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
index d48d3f571e3714eff676abe84df80402e8b06bef..59842291a9987806b8d5af023e3f2946cc7f6443 100644 (file)
@@ -2395,13 +2395,21 @@ vect_get_constant_vectors (tree op, slp_tree slp_node,
             neutral_op = build_int_cst (TREE_TYPE (op), -1);
             break;
 
-          case MAX_EXPR:
-          case MIN_EXPR:
-            def_stmt = SSA_NAME_DEF_STMT (op);
-            loop = (gimple_bb (stmt))->loop_father;
-            neutral_op = PHI_ARG_DEF_FROM_EDGE (def_stmt,
-                                                loop_preheader_edge (loop));
-            break;
+         /* For MIN/MAX we don't have an easy neutral operand but
+            the initial values can be used fine here.  Only for
+            a reduction chain we have to force a neutral element.  */
+         case MAX_EXPR:
+         case MIN_EXPR:
+           if (!GROUP_FIRST_ELEMENT (stmt_vinfo))
+             neutral_op = NULL;
+           else
+             {
+               def_stmt = SSA_NAME_DEF_STMT (op);
+               loop = (gimple_bb (stmt))->loop_father;
+               neutral_op = PHI_ARG_DEF_FROM_EDGE (def_stmt,
+                                                   loop_preheader_edge (loop));
+             }
+           break;
 
           default:
             neutral_op = NULL;