https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123986

--- Comment #3 from Hongtao Liu <liuhongt at gcc dot gnu.org> ---
GPT suggestion for reference:

SLP simd-clone lowering could dereference an unset bestn->simdclone when
analysis failed to record clone info, leading to a null pointer segfault in
vectorizable_simd_clone_call. 
I now re-run the clone-selection logic during transform when the recorded clone
is missing and guard against null metadata, so we bail out cleanly instead of
crashing (tree-vect-stmts.cc:4370-4423).
Uninitialized SIMD-clone pointers in the per-node data are now defaulted to
null to prevent use of garbage values (tree-vectorizer.h:262-269).

patch:

diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index e7d6b4c123a..4afd54b3dde 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -4253,10 +4253,7 @@ vectorizable_simd_clone_call (vec_info *vinfo,
stmt_vec_info stmt_info,
   unsigned int badness_inbranch = 0;
   struct cgraph_node *bestn = NULL;
   struct cgraph_node *bestn_inbranch = NULL;
-  if (!cost_vec)
-    bestn = ((loop_vinfo && LOOP_VINFO_FULLY_MASKED_P (loop_vinfo))
-            ? data.clone_inbranch : data.clone);
-  else
+  auto pick_best_clone = [&] () {
     for (struct cgraph_node *n = node->simd_clones; n != NULL;
         n = n->simdclone->next_clone)
       {
@@ -4400,8 +4397,24 @@ vectorizable_simd_clone_call (vec_info *vinfo,
stmt_vec_info stmt_info,
            badness_inbranch = this_badness;
          }
       }
+  };
+
+  if (cost_vec)
+    pick_best_clone ();
+  else
+    {
+      bestn = ((loop_vinfo && LOOP_VINFO_FULLY_MASKED_P (loop_vinfo))
+              ? data.clone_inbranch : data.clone);
+      bestn_inbranch = data.clone_inbranch;
+
+      /* If analysis didn't record a usable clone, recompute here.  */
+      if (bestn == NULL || bestn->simdclone == NULL)
+       pick_best_clone ();
+    }

-  if (bestn == NULL)
+  /* If the chosen cgraph node has no SIMD clone metadata, bail out to avoid
+     dereferencing a null simdclone pointer during SLP transformation.  */
+  if (bestn == NULL || bestn->simdclone == NULL)
     return false;

   fndecl = bestn->decl;
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 4849830204d..3fc938554f1 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -262,7 +262,8 @@ struct vect_data {
    call_simd_clone_vec_info_type.  */
 struct vect_simd_clone_data : vect_data {
   virtual ~vect_simd_clone_data () = default;
-  vect_simd_clone_data () = default;
+   vect_simd_clone_data ()
+      : clone (NULL), clone_inbranch (NULL) {}
   vect_simd_clone_data (vect_simd_clone_data &&other) = default;

   /* Selected SIMD clone and clone for in-branch.  */

Reply via email to