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

f32/f64 sqrt has undefined behaviour for values less than -0.0 #9987

Closed
thestinger opened this issue Oct 21, 2013 · 14 comments
Closed

f32/f64 sqrt has undefined behaviour for values less than -0.0 #9987

thestinger opened this issue Oct 21, 2013 · 14 comments

Comments

@thestinger
Copy link
Contributor

http://llvm.org/docs/LangRef.html#llvm-sqrt-intrinsic

@thestinger
Copy link
Contributor Author

cc @bjz, @jensnockert

@auroranockert
Copy link
Contributor

It is correct that this is an issue, but I think the solution is wrong.

We should not break with IEEE 754 unless we have really good reason. The correct thing imho is to essentially to return NaN, but we should double-check the standard.

@thestinger
Copy link
Contributor Author

@jensnockert: The POSIX/C solution is to set errno to EDOM and set the floating point exception to FE_INVALID. I don't know if anything is specified by IEEE754.

@auroranockert
Copy link
Contributor

POSIX/C does not follow IEEE 754, it allows for different formats of floating-point, and doesn't require NaN. That is why it has an additional way to signal out-of-domain. IEEE 754 was not ubiquitous when they were designed.

From the POSIX standard

Finite values of x < -0, a domain error shall occur, and either a NaN (if supported), or an implementation-defined value shall be returned.

But since we can assume IEEE 754 in the standard library (there are no other floating-point standards that are popular anymore) I think we should just return NaN.

From IEEE 754-2008

7.2 Invalid operation 7.2.0
…, the default result of an operation that signals the invalid operation exception shall be a quiet NaN that should provide some diagnostic information (see 6.2). These operations are:

g) squareRoot if the operand is less than zero

I believe that the POSIX workaround will be surprising to others, since we have an in-band signalling mechanism that is standardized. This is the same in-band mechanism we use for example overflow and division by zero for floating-point operands.

@thestinger
Copy link
Contributor Author

Ah, okay, that's a much simpler way to do it.

@thestinger
Copy link
Contributor Author

@jensnockert: would we just be returning 0.0 / 0.0? or is there something special you have to do for the diagnostic part?

@auroranockert
Copy link
Contributor

That should be fine.

@thestinger
Copy link
Contributor Author

Wouldn't we have to also make sure the floating point environment exception is set properly? Or are we not worrying about that?

@auroranockert
Copy link
Contributor

0 / 0 throws the same exception as sqrt of something negative (invalid operation), so it should be fine. But if we ever expose floating-point exceptions, then we would probably need to check the f32/f64 modules for similar issues.

@thestinger
Copy link
Contributor Author

@jensnockert: I'll get around to sending in a fix like this to the standard library then: https://github.com/thestinger/rust-core/commit/b5cdd2c10952527f100bc439b1ecb993dface0d1

@auroranockert
Copy link
Contributor

Looks awesome.

@thestinger
Copy link
Contributor Author

@thestinger thestinger removed their assignment Jun 16, 2014
@DanielKeep
Copy link
Contributor

The following is true as of right now on the playpen:

assert_eq!((-1.0f32).sqrt(), 0.0f32);

sqrt of a negative number should return NaN.

@thestinger
Copy link
Contributor Author

@DanielKeep: It's undefined behaviour. The returned result is arbitrary so it will change based on optimizations. It will crash / corrupt memory in some cases. Even if it happened to return NaN in any test cases we tried, this would still be a bug.

bors added a commit that referenced this issue Oct 20, 2014
@huonw huonw closed this as completed in a1d5cd2 Oct 20, 2014
wthrowe added a commit to wthrowe/rust that referenced this issue Aug 23, 2015
This fixes a reappearance of bug rust-lang#9987 introduced in
1ddee80, which caused
f64::tests::test_sqrt_domain to fail (at least on some systems).
bors added a commit that referenced this issue Aug 23, 2015
This fixes a reappearance of bug #9987 introduced in
1ddee80, which caused
f64::tests::test_sqrt_domain to fail (at least on some systems).
flip1995 pushed a commit to flip1995/rust that referenced this issue Dec 1, 2022
Don't cross contexts while building the suggestion for `redundant_closure_call`

fixes rust-lang#9957

changelog: `redundant_closure_call`: Don't cross macro contexts while building the suggestion
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 a pull request may close this issue.

4 participants