Skip to content

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
@codecov
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.

@github-actions
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
@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