rL131311 added asm() support for builtin functions, but asm() for builtins with
specialized emitting (e.g. memcpy, various math functions) still do not work.
This patch makes these functions work for asm() and #pragma redefine_extname.
glibc uses asm() to redirect internal libc function calls to hidden aliases.
Limitation: such a function is a builtin in clang, but will not be recognized as
a libcall in optimization passes because Clang does not annotate the renamed
function as a libcall. In GCC -O1 or above, abs can be optimized out but we can't.
Additionally, we cannot redirect __builtin_sin to real_sin in the following example:
double sin(double x) asm("real_sin"); double f(double d) { return __builtin_sin(d); }
According to @rsmith, the following three statements cannot be simultaneously true:
(1) The frontend function foo has known, builtin semantics X.
(2) The symbol foo has known, builtin semantics X.
(3) It's not correct to lower a call to the frontend function foo to the symbol foo.
People do want to keep (1) (if it is profitable to expand a memcpy, do it).
This also means that people do not want to add -fno-builtin-memcpy.
People do want (3): that is why they use asm("__GI_memcpy") in the first place.
So unfortunately we make a compromise by not refuting (2) (see the limitation above).
For most libcalls, there is a small loss because compilers don't synthesize them.
For the few glibc cares about, it uses asm("memcpy = __GI_memcpy"); to make
the assembly level redirection.
(Changing function names (e.g. __memcpy) is a hit to ergonomics which is not acceptable).