Thanks to visit codestin.com
Credit goes to github.com

Skip to content

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

Merged

Conversation

dpgeorge
Copy link
Member

Summary

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.

Testing

This is currently tested only by inspecting output of mpy-cross -march=debug for the following code:

import array

@micropython.native
def a():
        array.array('B', b'12')

a()

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.

@dpgeorge dpgeorge added py-core Relates to py/ directory in source board-definition New or updated board definition files. Combine with a port- label. labels Jul 31, 2024
Copy link

codecov bot commented Jul 31, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.43%. Comparing base (d2e33fe) to head (afba3e0).

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.
📢 Have feedback on the report? Share it here.

Copy link

Code size report:

   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:    +0 +0.000% standard
      stm32:    +0 +0.000% PYBV10
     mimxrt:    +0 +0.000% TEENSY40
        rp2:    +0 +0.000% RPI_PICO_W
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS

@dpgeorge dpgeorge removed the board-definition New or updated board definition files. Combine with a port- label. label Aug 1, 2024
Copy link
Member

@jimmo jimmo left a 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]>
@dpgeorge dpgeorge force-pushed the py-emitnative-fix-clobbered-temp0 branch from 8155655 to afba3e0 Compare August 7, 2024 02:25
@dpgeorge dpgeorge merged commit afba3e0 into micropython:master Aug 7, 2024
63 checks passed
@dpgeorge dpgeorge deleted the py-emitnative-fix-clobbered-temp0 branch August 7, 2024 02:33
@dpgeorge
Copy link
Member Author

dpgeorge commented Aug 7, 2024

Can you raise an issue describing this in more detail?

See #15609 which sets the stage to run native .mpy tests on the qemu-* ports.

it would be good to know whether the suggested improvement to the qemu-testing is likely to be able to catch other cases?

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
py-core Relates to py/ directory in source
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants