These functions are gcc builtins. They are optimised away. On linux, too. (Compile with -save-temps to see what is produced, or check the disassembly with objdump -d.)
To do a proper test, use separate compilation units.
/* test_isnanl.c */
#include <math.h>
int test_isnanl(long double x) { return isnanl(x); }
And link: cc main.o test_isnanl.o -lm && ./a.out || FAIL
However, the above is not entirely future-proof either—it's defeated with link-time optimisation (-flto).
So perhaps it would be better to
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[]) {
long double x = strtold(argv[1], NULL);
printf("%d", isnanl(x));
printf("%Lf", erfl(x));
return 0;
}
Finally, if you limit your scope to the usual gcc/clang, then there is the -fno-builtin option that will make your original test work as is. This might be the best option of all.