diff --git a/libvips/conversion/premultiply.c b/libvips/conversion/premultiply.c index cc960cdb..6fd75814 100644 --- a/libvips/conversion/premultiply.c +++ b/libvips/conversion/premultiply.c @@ -121,6 +121,7 @@ G_DEFINE_TYPE( VipsPremultiply, vips_premultiply, VIPS_TYPE_CONVERSION ); } \ } +VIPS_TARGET_CLONES("default,avx") static int vips_premultiply_gen( VipsRegion *or, void *vseq, void *a, void *b, gboolean *stop ) diff --git a/libvips/conversion/unpremultiply.c b/libvips/conversion/unpremultiply.c index 2bab161a..3e2e00eb 100644 --- a/libvips/conversion/unpremultiply.c +++ b/libvips/conversion/unpremultiply.c @@ -174,6 +174,7 @@ G_DEFINE_TYPE( VipsUnpremultiply, vips_unpremultiply, VIPS_TYPE_CONVERSION ); } \ } +VIPS_TARGET_CLONES("default,avx") static int vips_unpremultiply_gen( VipsRegion *or, void *vseq, void *a, void *b, gboolean *stop ) diff --git a/libvips/include/vips/util.h b/libvips/include/vips/util.h index 35d9531f..9dd343da 100644 --- a/libvips/include/vips/util.h +++ b/libvips/include/vips/util.h @@ -215,6 +215,16 @@ G_STMT_START { \ */ #define VIPS_PATH_MAX (4096) +/* Create multiple copies of a function targeted at groups of SIMD intrinsics, + * with the most suitable selected at runtime via dynamic dispatch. + */ +#ifdef HAVE_TARGET_CLONES + #define VIPS_TARGET_CLONES( TARGETS ) \ + __attribute__(( target_clones( TARGETS ) )) +#else + #define VIPS_TARGET_CLONES( TARGETS ) +#endif + VIPS_API const char *vips_enum_string( GType enm, int value ); VIPS_API diff --git a/meson.build b/meson.build index 64ee961d..98e527ee 100644 --- a/meson.build +++ b/meson.build @@ -131,6 +131,20 @@ if cpp.compiles(vector_arithmetic_check, name: 'Has vector arithmetic', dependen endif endif +# HAVE_TARGET_CLONES +target_clones_check = ''' +static int __attribute__((target_clones("default,avx"))) +has_target_clones(void) { + return 0; +} +int main(void) { + return has_target_clones(); +} +''' +if cc.compiles(target_clones_check, args: '-Werror', name: 'Has target_clones attribute') + cfg_var.set('HAVE_TARGET_CLONES', '1') +endif + func_names = [ 'vsnprintf', '_aligned_malloc', 'posix_memalign', 'memalign', 'cbrt', 'hypot', 'atan2', 'asinh' ] foreach func_name : func_names if cc.has_function(func_name, dependencies: m_dep)