Skip to content
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

Certain simd math operations imply fast-math, but operation naming does not make it apparent #84268

Closed
calebzulawski opened this issue Apr 17, 2021 · 5 comments · Fixed by #84274
Assignees
Labels
A-codegen Area: Code generation A-SIMD Area: SIMD (Single Instruction Multiple Data) C-bug Category: This is a bug. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@calebzulawski
Copy link
Member

calebzulawski commented Apr 17, 2021

In the following, is_infinite is optimized to always return zero, but it should instead perform fabs and cmp:

#![feature(platform_intrinsics, repr_simd)]

extern "platform-intrinsic" {
    fn simd_fabs<T>(x: T) -> T;
    fn simd_eq<T, U>(x: T, y: T) -> U;
}

#[repr(simd)]
pub struct V([f32; 4]);

#[repr(simd)]
pub struct M([i32; 4]);

pub fn is_infinite(v: V) -> M {
    unsafe {
        simd_eq(simd_fabs(v), V([f32::INFINITY; 4]))
    }
}

It works correctly in debug, and fails in release.

Playground link: https://play.rust-lang.org/?version=nightly&mode=release&edition=2018&gist=49b790d5e14139e6bea9e57b0ae381d5

The problem is related to simd_fabs, because in stdsimd we are currently using simd_xor instead of simd_fabs and that optimizes correctly.

Meta

rustc --version --verbose:

rustc 1.53.0-nightly (b0c818c5e 2021-04-16)
binary: rustc
commit-hash: b0c818c5e0fa37251d9fda2f656bf1041a2e1e1d
commit-date: 2021-04-16
host: x86_64-unknown-linux-gnu
release: 1.53.0-nightly
LLVM version: 12.0.0
@calebzulawski
Copy link
Member Author

I just tried this with nightly-2021-02-11 and it optimizes correctly, so I think this is an LLVM 12 regression.

@calebzulawski calebzulawski changed the title simd_fabs incorrect optimization LLVM 12 regression: simd_fabs incorrect optimization Apr 17, 2021
@nikic
Copy link
Contributor

nikic commented Apr 17, 2021

The optimization is correct from LLVM's perspective, because rustc is emitting fast flags on the fabs: https://rust.godbolt.org/z/17h48dWha

This is done here:

unsafe { llvm::LLVMRustSetHasUnsafeAlgebra(c) };

The change was made in #50521. This is almost certainly wrong under rust semantics. Based on the comments there, possibly the intention was to set just afn and not the full set of fast flags.

@jonas-schievink jonas-schievink added A-codegen Area: Code generation T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-SIMD Area: SIMD (Single Instruction Multiple Data) I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness labels Apr 17, 2021
@rustbot rustbot added the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Apr 17, 2021
@nagisa nagisa added the requires-nightly This issue requires a nightly compiler in some way. label Apr 17, 2021
@nagisa nagisa self-assigned this Apr 17, 2021
@calebzulawski
Copy link
Member Author

calebzulawski commented Apr 17, 2021

Hmm, the LLVM docs don't seem to indicate fast (or ninf in this case) does anything for fabs--this probably changed in LLVM 12, but I agree that it's correct.

@nagisa
Copy link
Member

nagisa commented Apr 17, 2021

The documentation for fast-math says:

fast: This flag implies all of the others.

And amongst the implied ones:

ninf: No Infs - Allow optimizations to assume the arguments and result are not +/-Inf. If an argument is +/-Inf, or the result would be +/-Inf, it produces a poison value instead.

In this particular case the property that's exploited is that the result is assumed to not be +inf and the comparison is optimized out. Once that's done the fabs is also just dead code and is removed.

@nagisa
Copy link
Member

nagisa commented Apr 17, 2021

I made a PR for this at #84274. Somebody else will have to coordinate changes to stdarch so that it can land, though.

@nagisa nagisa changed the title LLVM 12 regression: simd_fabs incorrect optimization simd math operations imply fast-math, but operation naming does not make it apparent Apr 17, 2021
@nagisa nagisa changed the title simd math operations imply fast-math, but operation naming does not make it apparent Certain simd math operations imply fast-math, but operation naming does not make it apparent Apr 17, 2021
bors added a commit to rust-lang-ci/rust that referenced this issue Apr 18, 2021
Don't set fast-math for the SIMD operations we set it for previously

Instead of `fast-math`. `fast-math` implies things like functions not
being able to accept as an argument or return as a result, say, `inf`
which made these functions confusingly named or behaving incorrectly,
depending on how you interpret it. It seems that the intended behaviour
was to set a `afn` flag instead. In doing so we also renamed the
intrinsics to say `_approx` so that it is clear these are not precision
oriented and the users can act accordingly.

Fixes rust-lang#84268
@bors bors closed this as completed in 487e273 Apr 18, 2021
@apiraino apiraino removed the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Mar 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-codegen Area: Code generation A-SIMD Area: SIMD (Single Instruction Multiple Data) C-bug Category: This is a bug. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants