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

Force evaluation order in set_date_fields #268

Merged
merged 4 commits into from
Feb 22, 2024

Conversation

chqrlie
Copy link
Collaborator

@chqrlie chqrlie commented Feb 18, 2024

  • use volatile to force evaluation order in set_date_fields
  • fix evaluation error in test262/test/built-ins/Date/UTC/fp-evaluation-order.js:19: unexpected error: Test262Error: precision in MakeDate Expected SameValue(«34448384», «34447360») to be true
  • this error occurs on the macOS target with clang --version:
    Apple clang version 15.0.0 (clang-1500.1.0.2.5)
    Target: arm64-apple-darwin23.3.0

- use `volatile` to force evaluation order in `set_date_fields`
- fix evaluation error in test262/test/built-ins/Date/UTC/fp-evaluation-order.js:19: unexpected error: Test262Error: precision in MakeDate Expected SameValue(«34448384», «34447360») to be true
- this error occurs on the macOS target with clang --version:
  Apple clang version 15.0.0 (clang-1500.1.0.2.5)
  Target: arm64-apple-darwin23.3.0
@bnoordhuis
Copy link
Contributor

Is the volatile strictly to work around a compiler bug? If so, can I suggest updating the comment to call that out explicitly - naming and shaming, basically? To a casual reader (that is to say, me) it looks like the changes cannot and should not make an observable difference.

@chqrlie
Copy link
Collaborator Author

chqrlie commented Feb 18, 2024

This is not strict speaking a compiler bug, but ECMA insists on the order of operations when converting the date components into an actual time value, whereas the order of evaluation is not so easy to force in C. There are 2 tests in test262 that keep failing on macOS with M2 hardware and clang v15. Making one of the double variables volatile enforces the order of evaluation and fixes the problem. There is an explanatory comment in the code. If you have a cleaner solution, I would be glad to see it.

@bnoordhuis
Copy link
Contributor

bnoordhuis commented Feb 19, 2024

I believe I figured out the cause. It's not order of evaluation, not exactly. It's rounding.

days * 86400000 + h gets lowered to a single FMA instruction (fused multiply-add) when supported, and that produces a different result than multiply-then-add because FMA doesn't round between steps.

The ECMA spec however defines arithmetic in terms of discrete rounding.

Your fix is correct. volatile forces a switch from FMA to multiply-then-add.

Further evidence: when I add -mfma to the compile flags, the test starts failing on x86 too.

The only thing I'd ask of you is to update the comment with an abridged version of the above, otherwise this tidbit of institutional knowledge is bound to get forgotten again. :-)

- use `double` arithmetic where necessary to match the spec
- use `volatile` to ensure correct order of evaluation
  and prevent FMA code generation
- reject some border cases.
- avoid undefined behavior in `double` -> `int64_t` conversions
- improved tests/test_builtin.js `assert` function to compare
  values more reliably.
- added some tests in `test_date()`
@chqrlie
Copy link
Collaborator Author

chqrlie commented Feb 21, 2024

I added the offending tests in our tests/test_builtin.js and I get failures from the CI jobs on Windows (windows-mingw32-debug [Debug and Release]).

Looking into that, I noticed the test262 suite is not run on all targets, hence these failures might already be present in the current version and my code does not fix them for those compiler/target combinations.

Beside the long run times, are there specific reasons to omit the test262 suite on many target systems?

I saw that you disabled some numeric conversion tests on the windows targets, I shall use the same work around for these precision / evaluation order date tests, but what about other targets, why not run the test262 suite?

@chqrlie
Copy link
Collaborator Author

chqrlie commented Feb 21, 2024

Is there a way to configure github CI to only report failing CI jobs in their reports (both on this page and in the emails) ?

@saghul
Copy link
Contributor

saghul commented Feb 21, 2024

I added the offending tests in our tests/test_builtin.js and I get failures from the CI jobs on Windows (windows-mingw32-debug [Debug and Release]).

Looking into that, I noticed the test262 suite is not run on all targets, hence these failures might already be present in the current version and my code does not fix them for those compiler/target combinations.

Beside the long run times, are there specific reasons to omit the test262 suite on many target systems?

I saw that you disabled some numeric conversion tests on the windows targets, I shall use the same work around for these precision / evaluation order date tests, but what about other targets, why not run the test262 suite?

We made 262 run in a representative subset of the targets, happy to add more if necessary.

Regarding MinGW: there is indeed something going on with floating point rounding. We haven't gotten to the bottom of it yet.

@chqrlie
Copy link
Collaborator Author

chqrlie commented Feb 21, 2024

Did you decide on a big-endian target ?
Can you approve the workflow for the last commit ?

@saghul
Copy link
Contributor

saghul commented Feb 21, 2024

Approved the workflow.

I'm traveling this week and hope to add the CI the next week.

If all is well we can land this before no problem.

- use `double` arithmetic where necessary to match the spec
- use `volatile` to ensure correct order of evaluation
  and prevent FMA code generation
- reject some border cases.
- avoid undefined behavior in `double` -> `int64_t` conversions
- improved tests/test_builtin.js `assert` function to compare
  values more reliably.
- added some tests in `test_date()`
- disable date precision tests on win32 and cygwin targets
- remove unused variable
@saghul saghul merged commit ef4d8ab into quickjs-ng:master Feb 22, 2024
35 checks passed
@chqrlie chqrlie deleted the fix-eval-order branch February 25, 2024 08:00
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.

3 participants