Generally LGTM, just a few minor comments for the C-ish stuff...
> +
> + /* At least one more version other than the default. */
> + unsigned int num_versions = fndecls->length ();
> + gcc_assert (num_versions >= 2);
> +
> + struct function_version_info
> + {
> + tree version_decl;
> + int prio;
> + struct riscv_feature_bits features;
> + } *function_versions;
> +
> + function_versions = (struct function_version_info *)
> + XNEWVEC (struct function_version_info, (num_versions));
Use std::vector instead
> +
> + unsigned int actual_versions = 0;
> +
> + for (tree version_decl : *fndecls)
> + {
> + function_versions[actual_versions].version_decl = version_decl;
> + // Get attribute string, parse it and find the right features.
> + parse_features_for_version (version_decl,
> + function_versions[actual_versions].features,
> + function_versions[actual_versions].prio);
> + actual_versions++;
> + }
> +
> +
> + auto compare_feature_version_info = [](const void *p1, const void *p2)
> + {
> + const function_version_info v1 = *(const function_version_info *)p1;
> + const function_version_info v2 = *(const function_version_info *)p2;
> + return - compare_fmv_features (v1.features, v2.features,
> + v1.prio, v2.prio);
> + };
> +
> + /* Sort the versions according to descending order of dispatch priority.
> */
> + qsort (function_versions, actual_versions,
> + sizeof (struct function_version_info), compare_feature_version_info);
Use std::sort instead, I