Skip to content

Add intrinsics for float arithmetic with fast flag enabled #32256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 19, 2016

Conversation

bluss
Copy link
Member

@bluss bluss commented Mar 15, 2016

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 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 that the
floats must be added in a sequence, one after another. This constraint
is usually completely unintended, and it means that no auto-vectorization
is possible.

@bluss
Copy link
Member Author

bluss commented Mar 15, 2016

Related to #21690

@rust-highfive
Copy link
Contributor

r? @nikomatsakis

(rust_highfive has picked a reviewer for you, use r? to override)

@aturon aturon added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Mar 15, 2016
@aturon
Copy link
Member

aturon commented Mar 15, 2016

cc @rust-lang/libs

@alexcrichton
Copy link
Member

Sounds reasonable to me, and API-wise also seems fine for now!

@hanna-kruppe
Copy link
Contributor

So IIUC this "fast" flag allows all transformation: No NaNs, no infinities, no signed zeros, reassociation, etc. C compilers typically expose more fine-grained control, allowing one to enable any subset of those assumptions (e.g., -ffinite-math-only). I don't have a concrete use case for this, but it seems like the "right" thing to do. For example I know a couple of algorithms that probably depend on infinites to correctly handle (rare but important) edge cases. On the other hand it might substantially complicate the API. Thoughts?

@bluss
Copy link
Member Author

bluss commented Mar 15, 2016

@rkruppe One question I have is if any of the flags except fast allow the compiler to reassociate operations. GCC too has the similar set of detailed float optimization flags (though for the whole compilation unit). They have a flag called -fassoicative-math too, but I can't see from llvm's docs if anything more than fast can do the same thing.

@bluss
Copy link
Member Author

bluss commented Mar 15, 2016

To answer my question, the fast (a k a UnsafeAlgebra) flag is the only way to have general operations reassociate. Using the code / documentation here. http://llvm.org/docs/doxygen/html/Reassociate_8cpp_source.html

@DemiMarie
Copy link
Contributor

Perhaps there should be a feature request against LLVM for more fine-grained control.

@alexcrichton
Copy link
Member

The libs team discussed this during triage yesterday and the conclusion was that this seems good to merge. We liked the idea of having tagged types that are "fast math" as opposed to the C mode of globally turning it on/off for now. Note that this is also quite related to the checked arithmetic story!

@bors: r+ 04d03a68ce1377b664441aaf164d052b00ee403e

@alexcrichton alexcrichton removed the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Mar 17, 2016
@bluss
Copy link
Member Author

bluss commented Mar 17, 2016

Thanks. It's a good step to put this into the unstable toolbox so we can find out where using these relaxed semantics helps and where it doesn't matter.

@bors
Copy link
Collaborator

bors commented Mar 18, 2016

⌛ Testing commit 04d03a6 with merge 0af284c...

@bors
Copy link
Collaborator

bors commented Mar 18, 2016

⛄ The build was interrupted to prioritize another pull request.

@bors
Copy link
Collaborator

bors commented Mar 18, 2016

⌛ Testing commit 04d03a6 with merge 379d18e...

@bors
Copy link
Collaborator

bors commented Mar 18, 2016

⛄ The build was interrupted to prioritize another pull request.

@bors
Copy link
Collaborator

bors commented Mar 18, 2016

⌛ Testing commit 04d03a6 with merge 493dbab...

@bors
Copy link
Collaborator

bors commented Mar 18, 2016

💔 Test failed - auto-win-msvc-32-opt

`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.
@bluss bluss force-pushed the float-fast-math branch from 04d03a6 to 2dbac1f Compare March 18, 2016 16:34
@bluss
Copy link
Member Author

bluss commented Mar 18, 2016

rebased

@bors r=alexcrichton

@bors
Copy link
Collaborator

bors commented Mar 18, 2016

📌 Commit 2dbac1f has been approved by alexcrichton

@bors
Copy link
Collaborator

bors commented Mar 19, 2016

⌛ Testing commit 2dbac1f with merge b9a93fa...

bors added a commit that referenced this pull request Mar 19, 2016
Add intrinsics for float arithmetic with `fast` flag enabled

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 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 that the
floats must be added in a sequence, one after another. This constraint
is usually completely unintended, and it means that no auto-vectorization
is possible.
@bors bors merged commit 2dbac1f into rust-lang:master Mar 19, 2016
@bluss bluss deleted the float-fast-math branch March 19, 2016 08:29
@@ -254,6 +263,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
}

pub fn fsub_fast(&self, lhs: ValueRef, rhs: ValueRef) -> ValueRef {
self.count_insn("sub");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be 'fsub'?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That seems logical, this just repeats what fsub did above, both should be fixed.

@maciejkula
Copy link

Does this mean that passing llvm-args="-fast" to rustc will enable autovectorization of float operations?

@bluss
Copy link
Member Author

bluss commented Mar 22, 2016

This PR just adds intrinsics that you need to use explicitly to get for example an "fadd" instruction with the "fast" flag enabled. For example, replace a + b with unsafe { std::intrinsics::fadd_fast(a, b) }. The intrinsics support f32 and f64.

These are just intrinsics, so it's a small step towards exposing it as a stable feature in libcore/libstd eventually.

@bluss
Copy link
Member Author

bluss commented Mar 22, 2016

Oh, flag. They are called flags http://llvm.org/docs/LangRef.html#fast-math-flags and it's a configuration put on the instruction itself, nothing about the command line interface.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants