JitArm64: Fix frsqrte misclassifying large negative inputs as NaN #13241
+94
−15
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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);
andFixupBranch negative = TBNZ(ARM64Reg::X1, 63);
, and then instead of having thenan_or_inf
case do a special check for negative infinity, I'm making thenegative
case do a special check for NaN. The total instruction count is the same.