One way is to use the Function Multiversioning feature in GCC, write a test program, and see what version of the function (dependent on your CPU arch) will it pick.
The foo function from the program below will create multiple symbols in the binary, and the "best" version will be picked at runtime
$ nm a.out | grep foo
0000000000402236 T _Z3foov
000000000040224c T _Z3foov.arch_x86_64
0000000000402257 T _Z3foov.arch_x86_64_v2
0000000000402262 T _Z3foov.arch_x86_64_v3
000000000040226d T _Z3foov.arch_x86_64_v4
0000000000402290 W _Z3foov.resolver
0000000000402241 T _Z3foov.sse4.2
0000000000402290 i _Z7_Z3foovv
// multiversioning.c
#include <stdio.h>
__attribute__ ((target ("default")))
const char* foo () { return "default"; }
__attribute__ ((target ("sse4.2")))
const char* foo () { return "sse4.2"; }
__attribute__ ((target ("arch=x86-64")))
const char* foo () { return "x86-64-v1"; }
__attribute__ ((target ("arch=x86-64-v2")))
const char* foo () { return "x86-64-v2"; }
__attribute__ ((target ("arch=x86-64-v3")))
const char* foo () { return "x86-64-v3"; }
__attribute__ ((target ("arch=x86-64-v4")))
const char* foo () { return "x86-64-v4"; }
int main ()
{
printf("%s\n", foo());
return 0;
}
On my laptop, this prints
$ g++ multiversioning.c
$ ./a.out
x86-64-v3
Note that the use of g++ is intentional here.
If I used gcc to compile, it would fail with error: redefinition of ‘foo’.