JuliaLang/julia — pull request #3969 by simonster (2013-08-07 02:28:38+00:00)
Title: Allow ccall of LLVM intrinsics

This simplifies things while adding flexibility, and as far as I can tell it generates exactly the same code.

For the moment, I've only converted the `bswap_int` and `ctpop_int` intrinsics, but more could potentially be done with this:
- If we can drop support for LLVM <3.1, `ctlz_int` (`leading_zeros`) and `cttz_int` (`trailing_zeros`) can be converted from Julia intrinsics to ccalls to LLVM intrinsics
- If we can drop support for LLVM <3.2, `abs_float` can be converted from a Julia intrinsic to a ccall to `llvm.fabs`
- If we can drop support for LLVM <3.3, we can replace `floor`, `ceil`, and `trunc` calls to libm with `llvm.floor`, `llvm.ceil`, and `llvm.trunc`, which compile to a single instruction and are considerably faster
- `llvm.sqrt` compiles down to a single instruction, but the LLVM intrinsic has undefined behavior on negative values, so at the moment I think this would still need a Julia intrinsic to be inlineable. In a naïve benchmark it also doesn't seem any faster than calling into libm, although it might be faster in cases where the next operation is not a sqrt
- `llvm.powi` was discussed in #2741. It looks like LLVM just lowers this into a bunch of multiply instructions if the exponent is a constant. It doesn't sound like this will always give the same result as `pow`
- LLVM has intrinsics for several other mathematical functions, but AFAICT they just call libm and the only advantage is that constant expressions can be evaluated at compile time
- LLVM has intrinsics for `memcpy`/`memmove`/`memset`, but AFAICT they also just call the library functions unless they can be optimized out, and in the few cases where they're used I doubt they can be