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. */