-
-
Notifications
You must be signed in to change notification settings - Fork 8.3k
py/emitnative: Fix case of clobbered REG_TEMP0 when loading const obj. #15573
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
py/emitnative: Fix case of clobbered REG_TEMP0 when loading const obj. #15573
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #15573 +/- ##
=======================================
Coverage 98.43% 98.43%
=======================================
Files 161 161
Lines 21281 21281
=======================================
Hits 20948 20948
Misses 333 333 ☔ View full report in Codecov by Sentry. |
Code size report:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: would be good to improve the qemu-riscv (and qemu-arm) ports so they can test this case by generating .mpy files using mpy-cross with a native emitter for all their tests, and running the .mpy. But that requires a bit of upfront leg work.
Can you raise an issue describing this in more detail? (I'm not quite sure from the description above what needs to be done).
This change looks good otherwise, although given that this is not the first example of this sort of clobbering it would be good to know whether the suggested improvement to the qemu-testing is likely to be able to catch other cases?
The `emit_load_reg_with_object()` helper function will clobber `REG_TEMP0`. This is currently OK on architectures where `REG_RET` and `REG_TEMP0` are the same (all architectures except RV32), because all callers of `emit_load_reg_with_object()` use either `REG_RET` or `REG_TEMP0` as the destination register. But on RV32 these registers are different and so when `REG_RET` is the destination, `REG_TEMP0` is clobbered, leading to incorrectly generated machine code. This commit fixes the issue simply by using `REG_TEMP0` as the destination register for all uses of `emit_load_reg_with_object()`, and adds a comment to make sure the caller of this function is careful. Signed-off-by: Damien George <[email protected]>
8155655
to
afba3e0
Compare
See #15609 which sets the stage to run native .mpy tests on the qemu-* ports.
We currently only run full native tests under CI for the x86 and x64 emitters. Enabling all the native tests under CI using qemu-arm and qemu-riscv, it's highly likely that would expose some of the bugs that we already found and fixed (which were found by running native tests on hardware, mostly ARM Thumb and Xtensa hardware). |
Summary
The
emit_load_reg_with_object()
helper function will clobberREG_TEMP0
. This is currently OK on architectures whereREG_RET
andREG_TEMP0
are the same (all architectures except RV32), because all callers ofemit_load_reg_with_object()
use eitherREG_RET
orREG_TEMP0
as the destination register. But on RV32 these registers are different and so whenREG_RET
is the destination,REG_TEMP0
is clobbered, leading to incorrectly generated machine code.This commit fixes the issue simply by using
REG_TEMP0
as the destination register for all uses ofemit_load_reg_with_object()
, and adds a comment to make sure the caller of this function is careful.Testing
This is currently tested only by inspecting output of
mpy-cross -march=debug
for the following code:See #15551 (comment) for background.
TODO: would be good to improve the qemu-riscv (and qemu-arm) ports so they can test this case by generating .mpy files using mpy-cross with a native emitter for all their tests, and running the .mpy. But that requires a bit of upfront leg work.