Profiling a recent demo I was playing with on `wasm32-unknown-unknown`
pointed me to the surprising result that 15% of the execution time was
in the `sqrt` intrinsic (there's a lot of math here). Upon investigation
I remembered that wasm (unconditionally) has a native `f32.sqrt`
instruction!
I was then subsequently confused that a simple `f.sqrt()` actually
codegens to use `f32.sqrt` in Rust, but I later realized that the
implementations of intrinsics in this library often use other intrinsics
to implement them. That means that the real intrinsic here, `acos`,
internally called `sqrt` at some point but wasn't using the optimized
implementation!
To help fix this situation this PR is intended on providing the
infrastructure for optimized implementations (via code generation) to be
used for each intrinsic. I've gone thorugh the various math instructions
that wasm has available and updated each of the intrinsic
implementations in this crate to optionally use the LLVM intrinsic
versions, which are known to unconditionally compile down to a single
instruction (unlike the arbitrary platform, where we don't know what it
will compile down to!).
To do this I created a new macro to wrap the invocation of LLVM
intrinsics. Invoking LLVM intrinsics is turned off by default (through a
new and on-by-default feature, `stable`). When the `stable` feature is
disabled, however, then the wasm-target specifically will enable usage
of the LLVM intrinsics. I've additionally added a CI builder which
should verify that these continue to build on Travis.
After this I intended to update the submodule in the `compiler-builtins`
repository so we can pull in the optimized implementation there, and
`compiler-builtins` naturally won't set `feature = "stable"` when
compiling so all the intrinsics should get compiled in by default. After
a further update of `the libcompiler_builtins` submodule in
rust-lang/rust we should be good to go!
131: omit bounds check in release mode r=japaric a=japaric
this eliminates panicking branches in the optimized version of the functions. We keep the bounds
checks when running the test suite to check that we never do an out of bounds access.
This commit also adds a "must link" test that ensures that future changes in our implementation
won't add panicking branches.
closesrust-lang/libm#129
Co-authored-by: Jorge Aparicio <jorge@japaric.io>
this eliminates panicking branches in the optimized version of the functions. We keep the bounds
checks when running the test suite to check that we never do an out of bounds access.
This commit also adds a "must link" test that ensures that future changes in our implementation
won't add panicking branches.
closesrust-lang/libm#129
122: Add sanity_check for atan2 r=japaric a=P1n3appl3
It's already been merged, but now I can say with certainty that this closesrust-lang/libm#9
Co-authored-by: Joseph Ryan <josephryan3.14@gmail.com>
112: [WIP]: implement atan2 r=japaric a=P1n3appl3
This depends on `atan()`. There was a pr for that but it seems to have been closed without adding it?
Co-authored-by: Joseph Ryan <josephryan3.14@gmail.com>
Co-authored-by: Jorge Aparicio <jorge@japaric.io>
120: test edge cases r=japaric a=japaric
the test generator is not good at generating test cases that contain values like inf, zero and nan.
This commit adds test cases that contain those values.
Co-authored-by: Jorge Aparicio <jorge@japaric.io>