[PATCH] Fix PR91790 by considering different first_stmt_info for realign
authorKewen Lin <linkw@gcc.gnu.org>
Wed, 27 Nov 2019 09:08:20 +0000 (09:08 +0000)
committerKewen Lin <linkw@gcc.gnu.org>
Wed, 27 Nov 2019 09:08:20 +0000 (09:08 +0000)
As PR91790 exposed, when we have one slp node whose first_stmt_info_for_drptr
is different from first_stmt_info, it's possible that the first_stmt DR isn't
initialized yet before stmt SLP_TREE_SCALAR_STMTS[0] of slp node. So we
shouldn't use first_stmt_info for vect_setup_realignment, instead we can use
the one based on first_stmt_info_for_drptr DR with additional adjustment by
bumping the distance from first_stmt DR.

gcc/ChangeLog

2019-11-27  Kewen Lin  <linkw@gcc.gnu.org>

    PR tree-optimization/91790
    * gcc/tree-vect-stmts.c (vectorizable_load): Use the adjusted DR for
    vect_setup_realignment when first_stmt_info is different from
    first_stmt_info_for_drptr.

From-SVN: r278760

gcc/ChangeLog
gcc/tree-vect-stmts.c

index 78aa3ca818950f9439eedc9fe8b21f825f0f8a4f..78b2f46c2d9ff682ecb6272a4f182402a4eebb05 100644 (file)
@@ -1,3 +1,10 @@
+2019-11-27  Kewen Lin  <linkw@gcc.gnu.org>
+
+       PR tree-optimization/91790
+       * gcc/tree-vect-stmts.c (vectorizable_load): Use the adjusted
+       DR for vect_setup_realignment when first_stmt_info is different
+       from first_stmt_info_for_drptr.
+
 2019-11-27  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/92645
index 6890837bf9f0be29009ff17177eb93f44cf4b76b..f555fccde8ef2fe0a7cc0edeb17fa833c4c71a0e 100644 (file)
@@ -9274,18 +9274,27 @@ vectorizable_load (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
       compute_in_loop = true;
     }
 
+  bool diff_first_stmt_info
+    = first_stmt_info_for_drptr && first_stmt_info != first_stmt_info_for_drptr;
+
   if ((alignment_support_scheme == dr_explicit_realign_optimized
        || alignment_support_scheme == dr_explicit_realign)
       && !compute_in_loop)
     {
-      msq = vect_setup_realignment (first_stmt_info, gsi, &realignment_token,
-                                   alignment_support_scheme, NULL_TREE,
-                                   &at_loop);
+      /* If we have different first_stmt_info, we can't set up realignment
+        here, since we can't guarantee first_stmt_info DR has been
+        initialized yet, use first_stmt_info_for_drptr DR by bumping the
+        distance from first_stmt_info DR instead as below.  */
+      if (!diff_first_stmt_info)
+       msq = vect_setup_realignment (first_stmt_info, gsi, &realignment_token,
+                                     alignment_support_scheme, NULL_TREE,
+                                     &at_loop);
       if (alignment_support_scheme == dr_explicit_realign_optimized)
        {
          phi = as_a <gphi *> (SSA_NAME_DEF_STMT (msq));
          byte_offset = size_binop (MINUS_EXPR, TYPE_SIZE_UNIT (vectype),
                                    size_one_node);
+         gcc_assert (!first_stmt_info_for_drptr);
        }
     }
   else
@@ -9341,8 +9350,7 @@ vectorizable_load (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
              dataref_ptr = unshare_expr (DR_BASE_ADDRESS (first_dr_info->dr));
              dataref_offset = build_int_cst (ref_type, 0);
            }
-         else if (first_stmt_info_for_drptr
-                  && first_stmt_info != first_stmt_info_for_drptr)
+         else if (diff_first_stmt_info)
            {
              dataref_ptr
                = vect_create_data_ref_ptr (first_stmt_info_for_drptr,
@@ -9359,6 +9367,14 @@ vectorizable_load (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
                                            DR_INIT (ptrdr)));
              dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi,
                                             stmt_info, diff);
+             if (alignment_support_scheme == dr_explicit_realign)
+               {
+                 msq = vect_setup_realignment (first_stmt_info_for_drptr, gsi,
+                                               &realignment_token,
+                                               alignment_support_scheme,
+                                               dataref_ptr, &at_loop);
+                 gcc_assert (!compute_in_loop);
+               }
            }
          else if (STMT_VINFO_GATHER_SCATTER_P (stmt_info))
            vect_get_gather_scatter_ops (loop, stmt_info, &gs_info,