There's a bit left in this PR which the following fixes.  The root
only became external late and the check more naturally belongs to
the new place.

Boostrap and regtest running on x86_64-unknown-linux-gnu.

Richard.

2019-11-20  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/92537
        * tree-vect-slp.c (vect_analyze_slp_instance): Move CTOR
        vectorization validity check...
        (vect_slp_analyze_operations): ... here.

        * gfortran.dg/pr92537.f90: New testcase.

Index: gcc/tree-vect-slp.c
===================================================================
--- gcc/tree-vect-slp.c (revision 278477)
+++ gcc/tree-vect-slp.c (working copy)
@@ -2253,18 +2264,6 @@ vect_analyze_slp_instance (vec_info *vin
          matches[group_size / const_max_nunits * const_max_nunits] = false;
          vect_free_slp_tree (node, false);
        }
-      else if (constructor
-              && SLP_TREE_DEF_TYPE (node) != vect_internal_def)
-       {
-         /* CONSTRUCTOR vectorization relies on a vector stmt being
-            generated, that doesn't work for fully external ones.  */
-         if (dump_enabled_p ())
-           dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-                            "Build SLP failed: CONSTRUCTOR of external "
-                            "or constant elements\n");
-         vect_free_slp_tree (node, false);
-         return false;
-       }
       else
        {
          /* Create a new SLP instance.  */
@@ -2939,7 +2939,12 @@ vect_slp_analyze_operations (vec_info *v
       if (!vect_slp_analyze_node_operations (vinfo,
                                             SLP_INSTANCE_TREE (instance),
                                             instance, visited, lvisited,
-                                            &cost_vec))
+                                            &cost_vec)
+         /* Instances with a root stmt require vectorized defs for the
+            SLP tree root.  */
+         || (SLP_INSTANCE_ROOT_STMT (instance)
+             && (SLP_TREE_DEF_TYPE (SLP_INSTANCE_TREE (instance))
+                 != vect_internal_def)))
         {
          slp_tree node = SLP_INSTANCE_TREE (instance);
          stmt_vec_info stmt_info = SLP_TREE_SCALAR_STMTS (node)[0];
Index: gcc/testsuite/gfortran.dg/pr92537.f90
===================================================================
--- gcc/testsuite/gfortran.dg/pr92537.f90       (nonexistent)
+++ gcc/testsuite/gfortran.dg/pr92537.f90       (working copy)
@@ -0,0 +1,32 @@
+! { dg-do compile }
+! { dg-options "-O2 -ftree-vectorize -fno-inline" }
+! { dg-additional-options "-march=skylake" { target x86_64-*-* i?86-*-* } }
+MODULE pr93527
+  implicit none
+  integer, parameter :: wp = kind (1.d0)
+  interface p_min
+     module procedure p_min_wp
+  end interface
+contains
+  subroutine foo (pr)
+    real(wp), pointer     :: pr(:)
+    integer  ::  nzd
+    real(wp) ::  pmin
+    real(wp) ::  pmin_diag
+    integer  ::  i
+    nzd  = 15
+    allocate (pr(nzd))
+    pmin_diag = 4000._wp
+    pmin = p_min(pmin_diag)
+    pmin = min (pmin,pmin_diag)
+    pr(1) = log(pmin)
+    do i=1,nzd-1
+       pr(i+1) = log(pmin) + i
+    end do
+  end subroutine foo
+  function p_min_wp (x) result (p_min)
+    real(wp), intent(in) :: x
+    real(wp)             :: p_min
+    p_min = x
+  end function p_min_wp
+end module pr93527

Reply via email to