When versioning is run the IL is already mangled and finding
a VECTORIZED_CALL IFN can fail.

Bootstrapped / tested on x86_64-unknown-linux-gnu, pushed.

Richard.

2020-01-15  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/93094
        * tree-vectorizer.h (vect_loop_versioning): Adjust.
        (vect_transform_loop): Likewise.
        * tree-vectorizer.c (try_vectorize_loop_1): Pass down
        loop_vectorized_call to vect_transform_loop.
        * tree-vect-loop.c (vect_transform_loop): Pass down
        loop_vectorized_call to vect_loop_versioning.
        * tree-vect-loop-manip.c (vect_loop_versioning): Use
        the earlier discovered loop_vectorized_call.

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

diff --git a/gcc/testsuite/gcc.dg/vect/pr93094.c 
b/gcc/testsuite/gcc.dg/vect/pr93094.c
new file mode 100644
index 00000000000..79c3e891db1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr93094.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O3 -fno-tree-pre" } */
+/* { dg-additional-options "-mavx512bw" { target x86_64-*-* i?86-*-* } } */
+
+void
+ll (char *un, char *rr, int te, int fp, int nb)
+{
+  const int xe = nb & 1;
+
+  while (fp-- != 0)
+    {
+      if ((rr[0] & xe) == 0)
+        un[0] = 0;
+
+      un += te;
+      rr += te;
+    }
+}
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index 52ca4e3e56c..0ee1ab45c07 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -3205,7 +3205,8 @@ vect_create_cond_for_alias_checks (loop_vec_info 
loop_vinfo, tree * cond_expr)
    *COND_EXPR_STMT_LIST.  */
 
 class loop *
-vect_loop_versioning (loop_vec_info loop_vinfo)
+vect_loop_versioning (loop_vec_info loop_vinfo,
+                     gimple *loop_vectorized_call)
 {
   class loop *loop = LOOP_VINFO_LOOP (loop_vinfo), *nloop;
   class loop *scalar_loop = LOOP_VINFO_SCALAR_LOOP (loop_vinfo);
@@ -3339,18 +3340,18 @@ vect_loop_versioning (loop_vec_info loop_vinfo)
      if-conversion re-use that.  Note we cannot re-use the copy of
      an if-converted outer-loop when vectorizing the inner loop only.  */
   gcond *cond;
-  gimple *call;
   if ((!loop_to_version->inner || loop == loop_to_version)
-      && (call = vect_loop_vectorized_call (loop_to_version, &cond)))
+      && loop_vectorized_call)
     {
       gcc_assert (scalar_loop);
-      condition_bb = gimple_bb (cond);
+      condition_bb = gimple_bb (loop_vectorized_call);
+      cond = as_a <gcond *> (last_stmt (condition_bb));
       gimple_cond_set_condition_from_tree (cond, cond_expr);
       update_stmt (cond);
 
       if (cond_expr_stmt_list)
        {
-         cond_exp_gsi = gsi_for_stmt (call);
+         cond_exp_gsi = gsi_for_stmt (loop_vectorized_call);
          gsi_insert_seq_before (&cond_exp_gsi, cond_expr_stmt_list,
                                 GSI_SAME_STMT);
        }
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index faf816116de..27834ebabcd 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -8481,7 +8481,7 @@ update_epilogue_loop_vinfo (class loop *epilogue, tree 
advance)
    Returns scalar epilogue loop if any.  */
 
 class loop *
-vect_transform_loop (loop_vec_info loop_vinfo)
+vect_transform_loop (loop_vec_info loop_vinfo, gimple *loop_vectorized_call)
 {
   class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
   class loop *epilogue = NULL;
@@ -8532,7 +8532,7 @@ vect_transform_loop (loop_vec_info loop_vinfo)
   if (LOOP_REQUIRES_VERSIONING (loop_vinfo))
     {
       class loop *sloop
-       = vect_loop_versioning (loop_vinfo);
+       = vect_loop_versioning (loop_vinfo, loop_vectorized_call);
       sloop->force_vectorize = false;
       check_profitability = false;
     }
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index aa22fd1034c..8f9444d58a3 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -986,7 +986,8 @@ try_vectorize_loop_1 (hash_table<simduid_to_vf> 
*&simduid_to_vf_htab,
                         "loop vectorized using variable length vectors\n");
     }
 
-  loop_p new_loop = vect_transform_loop (loop_vinfo);
+  loop_p new_loop = vect_transform_loop (loop_vinfo,
+                                        loop_vectorized_call);
   (*num_vectorized_loops)++;
   /* Now that the loop has been vectorized, allow it to be unrolled
      etc.  */
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index ed7fcb0b825..f7becb34ab4 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -1682,7 +1682,7 @@ extern void vect_set_loop_condition (class loop *, 
loop_vec_info,
 extern bool slpeel_can_duplicate_loop_p (const class loop *, const_edge);
 class loop *slpeel_tree_duplicate_loop_to_edge_cfg (class loop *,
                                                     class loop *, edge);
-class loop *vect_loop_versioning (loop_vec_info);
+class loop *vect_loop_versioning (loop_vec_info, gimple *);
 extern class loop *vect_do_peeling (loop_vec_info, tree, tree,
                                    tree *, tree *, tree *, int, bool, bool,
                                    tree *);
@@ -1821,7 +1821,7 @@ extern tree vect_get_loop_mask (gimple_stmt_iterator *, 
vec_loop_masks *,
 extern stmt_vec_info info_for_reduction (stmt_vec_info);
 
 /* Drive for loop transformation stage.  */
-extern class loop *vect_transform_loop (loop_vec_info);
+extern class loop *vect_transform_loop (loop_vec_info, gimple *);
 extern opt_loop_vec_info vect_analyze_loop_form (class loop *,
                                                 vec_info_shared *);
 extern bool vectorizable_live_operation (stmt_vec_info, gimple_stmt_iterator *,

Reply via email to