Repository navigation
fix(relinker): move legacy CMPSS and CMPSD out of line for Rosetta - #5762
Conversation
The Rosetta split covered only VEX scalar compares. boykopovar#5642 measured the same lost load after legacy CMPSS and CMPSD, and the decoder already hands them to the matcher with the right length and RIP offset. Recognise F3 or F2, segment overrides and an optional REX before 0F C2 /r ib, with the same predicate rule as the VEX forms. A 66, 67 or LOCK prefix, or both F2 and F3, keeps the instruction inline as before.
|
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
|
Measured under Rosetta 2 on an M2 Max, macOS 27.2 (26B5091g). Relinker-only build of this branch (
|
| Load after the compare | CMPSS failures |
CMPSD failures |
|---|---|---|
SSE movaps / movapd |
0/16 | 0/16 |
VEX vmovaps / vmovapd |
4/16 | 0/16 |
- The four failures are predicates 3, 5 and 6, all with a false result (zero mask).
- Predicates 0–2 never fail, which matches the rule of keeping them inline.
- Only a VEX load after the compare triggers the hazard. A legacy compare followed by an SSE load is correct here.
- I did not see
CMPSDfail in this pattern. Moving it out of line is still harmless.
Written with AI assistance (Claude Code). I ran the builds and tests above on my machine.
|
Verified on macOS 27.0.1 (26A434), Apple M4, x86-64 under Rosetta 2, Apple clang 21: the relinker-only build passes |
|
ran the relinker output end to end under Rosetta, since the PR says it wasnt run there same synthetic check as on #5683: 40 sites, each a compare, a vmovaps load and a vucomiss, relinked and then called from an x86_64 harness under Rosetta AI-assisted (Claude Code), I ran all of the above on my machine |
|
Checked the prefix/REX/segment decoding in |
What
Follow-up to #5683 for #5642. The Rosetta split there covers only VEX scalar compares, because legacy compares were thought not to reach the matcher intact. They do:
InstructionScannerpasses every instruction with its decoded length, andX64InstructionDecoderdecodesF3/F2 0F C2 /r ibwith the right length and RIP offset (checked against iced-x86 in #5642's follow-up audit). #5642 measured the same lost load after the legacy forms.DecodeScalarComparenow also recognisesF3orF2, segment overrides and an optional REX before0F C2 /r ib, with the same rule as the VEX forms: predicates 0 to 2 stay inline, every other predicate moves out of line unchanged, with a RIP-relative source relocated. A66,67orLOCKprefix, or bothF2andF3, keeps the instruction inline as before.This branch contains #5683's commit; only the last commit is new. I will rebase it onto
mainonce #5683 is merged.Tested
Linux, relinker-only build on #5683: ctest passes 158/158 with
--timeout 30. Newamd64_only_convertercases cover the legacy register, REX, segment-prefixed memory and RIP-relative forms, the predicates that stay inline, the prefixes that are rejected, the fmax shape through the converter and the Intel target; six parser faults each fail them. A differential run ofDecodeScalarCompareagainst iced-x86 over 15,264 valid legacy and VEX encodings (21 prefix sets, 7 REX values, 9 ModRM forms, 8 predicates) finds no case where it moves anything but a hazard CMPSS/CMPSD or misses one, and all 704 RIP-relative relocation targets match. Not run under Rosetta.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)