Add intrinsics for float arithmetic with fast flag enabled

`fast` a.k.a UnsafeAlgebra is the flag for enabling all "unsafe"
(according to llvm) float optimizations.

See LangRef for more information http://llvm.org/docs/LangRef.html#fast-math-flags

Providing these operations with less precise associativity rules (for
example) is useful to numerical applications.

For example, the summation loop:

    let sum = 0.;
    for element in data {
        sum += *element;
    }

Using the default floating point semantics, this loop expresses the
floats must be added in a sequence, one after another. This constraint
is usually completely unintended, and it means that no autovectorization
is possible.
This commit is contained in:
Ulrik Sverdrup
2016-03-15 00:01:12 +01:00
parent 235d77457d
commit 2dbac1fb8e
9 changed files with 261 additions and 0 deletions

View File

@@ -539,6 +539,32 @@ extern "rust-intrinsic" {
/// Returns the nearest integer to an `f64`. Rounds half-way cases away from zero.
pub fn roundf64(x: f64) -> f64;
/// Float addition that allows optimizations based on algebraic rules.
/// May assume inputs are finite.
#[cfg(not(stage0))]
pub fn fadd_fast<T>(a: T, b: T) -> T;
/// Float subtraction that allows optimizations based on algebraic rules.
/// May assume inputs are finite.
#[cfg(not(stage0))]
pub fn fsub_fast<T>(a: T, b: T) -> T;
/// Float multiplication that allows optimizations based on algebraic rules.
/// May assume inputs are finite.
#[cfg(not(stage0))]
pub fn fmul_fast<T>(a: T, b: T) -> T;
/// Float division that allows optimizations based on algebraic rules.
/// May assume inputs are finite.
#[cfg(not(stage0))]
pub fn fdiv_fast<T>(a: T, b: T) -> T;
/// Float remainder that allows optimizations based on algebraic rules.
/// May assume inputs are finite.
#[cfg(not(stage0))]
pub fn frem_fast<T>(a: T, b: T) -> T;
/// Returns the number of bits set in an integer type `T`
pub fn ctpop<T>(x: T) -> T;