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

JitArm64: Fix frsqrte misclassifying large negative inputs as NaN #13241

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

JosJuice
Copy link
Member

The frsqrte routine has a little trick where it uses TBNZ(ARM64Reg::X1, 62) to check if the input is NaN/Inf. This only works if we've checked that the input isn't normal. While we have checked that the input isn't a positive normal at this point, it could still be a negative normal. Because of this, the frsqrte routine would incorrectly treat certain negative normal inputs as NaNs, causing it to output the wrong exception in FPSCR (while still producing the correct numerical value).

To fix the problem, I'm swapping the order of the lines FixupBranch nan_or_inf = TBNZ(ARM64Reg::X1, 62); and FixupBranch negative = TBNZ(ARM64Reg::X1, 63);, and then instead of having the nan_or_inf case do a special check for negative infinity, I'm making the negative case do a special check for NaN. The total instruction count is the same.

No games are known to care about this, but since we've gone through the
effort of implementing it, we should also go through the effort of
testing it.
The frsqrte routine has a little trick where it uses
`TBNZ(ARM64Reg::X1, 62)` to check if the input is NaN/Inf. This only
works if we've checked that the input isn't normal. While we have
checked that the input isn't a positive normal at this point, it could
still be a negative normal. Because of this, the frsqrte routine would
incorrectly treat certain negative normal inputs as NaNs, causing it to
output the wrong exception in FPSCR (while still producing the correct
numerical value).

To fix the problem, I'm swapping the order of the lines
`FixupBranch nan_or_inf = TBNZ(ARM64Reg::X1, 62);` and
`FixupBranch negative = TBNZ(ARM64Reg::X1, 63);`, and then instead of
having the `nan_or_inf` case do a special check for negative infinity,
I'm making the `negative` case do a special check for NaN. The total
instruction count is the same.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

1 participant