Skip to content

interp: resize ptrtoint and inttoptr results - #5745

Merged
deadprogram merged 3 commits into
devfrom
interp-ptrtoint-size
Sep 25, 2026
Merged

deadprogram merged 3 commits into
devfrom
interp-ptrtoint-size

Conversation

@deadprogram

Copy link
Copy Markdown
Member

This PR fixes #5642.

The interpreter treated ptrtoint and inttoptr as identity operations, so the result kept the width of the operand. The interface method thunk for a receiver narrower than a pointer does this:

%unpack.int = ptrtoint ptr %0 to i8

The method then got a pointer-sized value where it expected an i8, and interp panicked with "comparing values of different size".

This PR changes the following:

  • Integer operands are truncated or zero-extended to the result width, as in the LLVM LangRef.
  • When the operand is a real pointer, the instruction is emitted at runtime.
  • runAtRuntime now supports ptrtoint and inttoptr.

The new test interp/testdata/ptrtoint.ll covers narrowing, widening, and the runtime fallback for a pointer. Without the fix, it fails with the same panic as the issue. The reproducer from the issue now builds for -target=pico.

The interpreter treated ptrtoint and inttoptr as identity operations, so
the result kept the width of the operand. A method call through an
interface on a receiver narrower than a pointer then passed a value of
the wrong size, and interp panicked with "comparing values of different
size".

Truncate or zero-extend integer operands to the result width. Emit the
instruction at runtime when the operand is a pointer.

Fixes #5642
@github-actions

Copy link
Copy Markdown

Size difference with the dev branch:

Binary size difference
 flash                          ram
 before   after   diff          before   after   diff
  19884   19884      0   0.00%    7060    7060      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/adafruit4650
  63316   63316      0   0.00%    6860    6860      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/adt7410/main.go
  11300   11300      0   0.00%    5412    5412      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/adxl345/main.go
  15460   15460      0   0.00%    7468    7468      0   0.00% tinygo build -size short -o ./build/test.hex -target=pybadge ./examples/amg88xx
  10516   10516      0   0.00%    5372    5372      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/apa102/main.go
  13188   13188      0   0.00%    7204    7204      0   0.00% tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/apds9960/proximity/main.go
  12720   12720      0   0.00%    5384    5384      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/apa102/itsybitsy-m0/main.go
   8840    8840      0   0.00%    2320    2320      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/at24cx/main.go
  10004   10004      0   0.00%    5412    5412      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bh1750/main.go
   9300    9300      0   0.00%    5412    5412      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/blinkm/main.go
  71856   71856      0   0.00%    3728    3728      0   0.00% tinygo build -size short -o ./build/test.hex -target=pinetime     ./examples/bma42x/main.go
  67940   67940      0   0.00%    6828    6828      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmi160/main.go
  29140   29140      0   0.00%    5412    5412      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmp180/main.go
  66596   66596      0   0.00%    6860    6860      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmp280/main.go
  13700   13700      0   0.00%    5444    5444      0   0.00% tinygo build -size short -o ./build/test.hex -target=trinket-m0 ./examples/bmp388/main.go
  24540   24540      0   0.00%    6300    6300      0   0.00% tinygo build -size short -o ./build/test.hex -target=metro-rp2350 ./examples/bno08x/i2c/main.go
   9256    9256      0   0.00%    3360    3360      0   0.00% tinygo build -size short -o ./build/test.hex -target=bluepill ./examples/ds1307/sram/main.go
  22868   22868      0   0.00%    3592    3592      0   0.00% tinygo build -size short -o ./build/test.hex -target=bluepill ./examples/ds1307/time/main.go
  31248   31248      0   0.00%    5644    5644      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/ds3231/alarms/main.go
  45136   45136      0   0.00%    5644    5644      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/ds3231/basic/main.go
   4760    4760      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/easystepper/main.go
   6976    6976      0   0.00%    2344    2344      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/easystepper/async/main.go
  72952   72952      0   0.00%    7688    7688      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/flash/console/spi
  68808   68808      0   0.00%    9728    9728      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/flash/console/qspi
   7540    7540      0   0.00%    2284    2284      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/gc9a01/main.go
  23684   23684      0   0.00%    8588    8588      0   0.00% tinygo build -size short -o ./build/test.bin -target=esp32-coreboard-v2 ./examples/gdew0154m09/main.go
  69800   69800      0   0.00%    7060    7060      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/gps/i2c/main.go
  70304   70304      0   0.00%    7164    7164      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/gps/uart/main.go
  10076   10076      0   0.00%    5436    5436      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/hcsr04/main.go
   5880    5880      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hd44780/customchar/main.go
   5960    5960      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hd44780/text/main.go
  12036   12036      0   0.00%    5396    5396      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/hd44780i2c/main.go
  16068   16068      0   0.00%    7204    7204      0   0.00% tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/hts221/main.go
  16564   16564      0   0.00%    2428    2428      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hub75/main.go
  11620   11620      0   0.00%    7612    7612      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/basic
  14100   14100      0   0.00%    5572    5572      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/ili9341/basic
  30972   30972      0   0.00%   38772   38772      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/pyportal_boing
  11596   11596      0   0.00%    7612    7612      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/scroll
  14124   14124      0   0.00%    5572    5572      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/ili9341/scroll
 265908  265908      0   0.00%   47456   47456      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/slideshow
  12340   12340      0   0.00%    5412    5412      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/lis3dh/main.go
  15476   15476      0   0.00%    7204    7204      0   0.00% tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/lps22hb/main.go
  26600   26600      0   0.00%    2328    2328      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/lsm303agr/main.go
  29748   29748      0   0.00%    7460    7460      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m4 ./examples/lsm303dlhc/main.go
  13988   13988      0   0.00%    5420    5420      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/lsm6ds3/main.go
  12580   12580      0   0.00%    5412    5412      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mag3110/main.go
  11356   11356      0   0.00%    5404    5404      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp23017/main.go
  11772   11772      0   0.00%    5412    5412      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp23017-multiple/main.go
  11716   11716      0   0.00%    5372    5372      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp3008/main.go
  74380   74380      0   0.00%    6940    6940      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp2515/main.go
  30376   30376      0   0.00%    4152    4152      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/microbitmatrix/main.go
  30328   30328      0   0.00%    6196    6196      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit-v2 ./examples/microbitmatrix/main.go
  10052   10052      0   0.00%    5412    5412      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mma8653/main.go
  10004   10004      0   0.00%    5412    5412      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mpu6050/main.go
  79540   79540      0   0.00%    8092    8092      0   0.00% tinygo build -size short -o ./build/test.hex -target=p1am-100 ./examples/p1am/main.go
  15632   15632      0   0.00%    6240    6240      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/pca9685/main.go
   6676    6676      0   0.00%    3292    3292      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/pcd8544/setbuffer/main.go
   5076    5076      0   0.00%    2284    2284      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/pcd8544/setpixel/main.go
  15376   15376      0   0.00%    6224    6224      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/seesaw/soil-sensor
  14992   14992      0   0.00%    6224    6224      0   0.00% tinygo build -size short -o ./build/test.hex -target=qtpy-rp2040 ./examples/seesaw/rotary-encoder
   2899    2899      0   0.00%     560     560      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino ./examples/servo
  17208   17208      0   0.00%    6304    6304      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico     ./examples/sgp30
   9412    9412      0   0.00%    7412    7412      0   0.00% tinygo build -size short -o ./build/test.hex -target=pybadge ./examples/shifter/main.go
  58624   58624      0   0.00%    3728    3728      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/sht3x/main.go
  58576   58576      0   0.00%    3728    3728      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/sht4x/main.go
  58640   58640      0   0.00%    3728    3728      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/shtc3/main.go
  14268   14268      0   0.00%    9092    9092      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao-ble ./examples/ssd1306/
  15072   15072      0   0.00%    6264    6264      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao-rp2040 ./examples/ssd1306/
  15008   15008      0   0.00%    6256    6256      0   0.00% tinygo build -size short -o ./build/test.hex -target=thumby ./examples/ssd1306/
   6372    6372      0   0.00%    2284    2284      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1331/main.go
   7220    7220      0   0.00%    2284    2284      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/st7735/main.go
   6916    6916      0   0.00%    2284    2284      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/st7789/main.go
  18692   18692      0   0.00%    5364    5364      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/thermistor/main.go
  11956   11956      0   0.00%    5180    5180      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-bluefruit ./examples/tone
  11956   11956      0   0.00%    5364    5364      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/tm1637/main.go
  14212   14212      0   0.00%    6236    6236      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/touch/capacitive
  10764   10764      0   0.00%    7404    7404      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/touch/resistive/fourwire/main.go
  13800   13800      0   0.00%    7672    7672      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/touch/resistive/pyportal_touchpaint/main.go
  17132   17132      0   0.00%    5484    5484      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/vl53l1x/main.go
  15804   15804      0   0.00%    5484    5484      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/vl6180x/main.go
  26416   26416      0   0.00%   14368   14368      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-nrf52840-sense ./examples/waveshare-epd/epd1in54/main.go
   6788    6788      0   0.00%    2324    2324      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd2in13/main.go
   6468    6468      0   0.00%    2316    2316      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd2in13x/main.go
   6660    6660      0   0.00%    2324    2324      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd4in2/main.go
  31024   31024      0   0.00%   19304   19304      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/waveshare-epd/epd2in66b/main.go
   8628    8628      0   0.00%    5404    5404      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/ws2812
   6122    6122      0   0.00%    8464    8464      0   0.00% tinygo build -size short -o ./build/test.bin -target=m5stamp-c3          ./examples/ws2812
  64636   64636      0   0.00%    6580    6580      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-nrf52840 ./examples/is31fl3731/main.go
   1799    1799      0   0.00%     600     600      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino   ./examples/ws2812
   1280    1280      0   0.00%     182     182      0   0.00% tinygo build -size short -o ./build/test.hex -target=digispark ./examples/ws2812
   7776    7776      0   0.00%    8744    8744      0   0.00% tinygo build -size short -o ./build/test.bin -target=xiao-esp32c3 ./examples/ws2812
  33364   33364      0   0.00%    5412    5412      0   0.00% tinygo build -size short -o ./build/test.hex -target=trinket-m0 ./examples/bme280/main.go
  18204   18204      0   0.00%    5348    5348      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/microphone/main.go
  12964   12964      0   0.00%    5364    5364      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/buzzer/main.go
  13924   13924      0   0.00%    5412    5412      0   0.00% tinygo build -size short -o ./build/test.hex -target=trinket-m0 ./examples/veml6070/main.go
   8388    8388      0   0.00%    5364    5364      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l293x/simple/main.go
  10340   10340      0   0.00%    5364    5364      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l293x/speed/main.go
   8372    8372      0   0.00%    5364    5364      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l9110x/simple/main.go
  10756   10756      0   0.00%    5364    5364      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l9110x/speed/main.go
   8180    8180      0   0.00%    3324    3324      0   0.00% tinygo build -size short -o ./build/test.hex -target=nucleo-f103rb ./examples/shiftregister/main.go
   7596    7596      0   0.00%    2288    2288      0   0.00% tinygo build -size short -o ./build/test.hex -target=hifive1b ./examples/ssd1351/main.go
  15156   15156      0   0.00%    5412    5412      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/lis2mdl/main.go
  12852   12852      0   0.00%    5388    5388      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/max72xx/main.go
  79812   79812      0   0.00%    7008    7008      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/dht/main.go
  40012   40012      0   0.00%    6812    6812      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/pcf8523/
  72980   72980      0   0.00%    7048    7048      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/alarm/
   8980    8980      0   0.00%    5404    5404      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/clkout/
  67680   67680      0   0.00%    7044    7044      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/time/
  72820   72820      0   0.00%    7048    7048      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/timer/
  15584   15584      0   0.00%    6232    6232      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/qmi8658c/main.go
  14656   14656      0   0.00%    6224    6224      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/pcf8591/
  10500   10500      0   0.00%    5412    5412      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/ina260/main.go
  14676   14676      0   0.00%    5412    5412      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/ina219/main.go
  10600   10600      0   0.00%    5280    5280      0   0.00% tinygo build -size short -o ./build/test.hex -target=nucleo-l432kc ./examples/aht20/main.go
  76268   76268      0   0.00%   11484   11484      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m4 ./examples/sdcard/console/
  62788   62788      0   0.00%    8868    8868      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m4 ./examples/i2csoft/adt7410/
  11620   11620      0   0.00%    7420    7420      0   0.00% tinygo build -size short -o ./build/test.elf -target=wioterminal ./examples/axp192/m5stack-core2-blinky/
  12332   12332      0   0.00%    6164    6164      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/xpt2046/main.go
  12464   12464      0   0.00%    4696    4696      0   0.00% tinygo build -size short -o ./build/test.elf -target=m5stack-core2 ./examples/ft6336/basic/
  20044   20044      0   0.00%    4964    4964      0   0.00% tinygo build -size short -o ./build/test.elf -target=m5stack-core2 ./examples/ft6336/touchpaint/
  14416   14416      0   0.00%    5060    5060      0   0.00% tinygo build -size short -o ./build/test.hex -target=nucleo-wl55jc ./examples/sx126x/lora_rxtx/
  46784   46784      0   0.00%    9584    9584      0   0.00% tinygo build -size short -o ./build/test.hex -target=pybadge ./examples/sx127x/lora_rxtx/
  37160   37160      0   0.00%    7944    7944      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/ssd1289/main.go
  15088   15088      0   0.00%    7216    7216      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/irremote/main.go
  15352   15352      0   0.00%    6248    6248      0   0.00% tinygo build -size short -o ./build/test.hex -target=badger2040 ./examples/uc8151/main.go
  15752   15752      0   0.00%    6684    6684      0   0.00% tinygo build -size short -o ./build/test.hex -target=badger2040 ./examples/waveshare-epd/epd2in9v2/main.go
  17364   17364      0   0.00%    6276    6276      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/scd30/main.go
  13680   13680      0   0.00%    6252    6252      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/scd4x/main.go
   9532    9532      0   0.00%    5364    5364      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=circuitplay-express ./examples/makeybutton/main.go
  11236   11236      0   0.00%    5388    5388      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/ds18b20/main.go
 125652  125652      0   0.00%    8416    8416      0   0.00% tinygo build -size short -o ./build/test.hex -target=nucleo-wl55jc ./examples/lora/lorawan/atcmd/
  19932   19932      0   0.00%    7820    7820      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/as560x/main.go
  15328   15328      0   0.00%    6224    6224      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/mpu6886/main.go
   9412    9412      0   0.00%    5364    5364      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/ttp229/main.go
  70928   70928      0   0.00%    7712    7712      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/ndir/main_ndir.go
  63272   63272      0   0.00%    3792    3792      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ndir/main_ndir.go
  67652   67652      0   0.00%    6900    6900      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/ndir/main_ndir.go
  13136   13136      0   0.00%    6216    6216      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/mpu9150/main.go
  15036   15036      0   0.00%    6284    6284      0   0.00% tinygo build -size short -o ./build/test.hex -target=macropad-rp2040 ./examples/sh1106/macropad_spi
  11752   11752      0   0.00%    6664    6664      0   0.00% tinygo build -size short -o ./build/test.hex -target=macropad-rp2040 ./examples/encoders/quadrature-interrupt
  69328   69328      0   0.00%    7672    7672      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/mcp9808/main.go
  46856   46856      0   0.00%    8328    8328      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/tmc2209/main.go
  15196   15196      0   0.00%    6172    6172      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/tmc5160/main.go
  13912   13912      0   0.00%    5168    5168      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=nicenano ./examples/sharpmem/main.go
  63648   63648      0   0.00%    6608    6608      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-nrf52840 ./examples/max6675/main.go
  15968   15968      0   0.00%    6232    6232      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/ens160/main.go
  19864   19864      0   0.00%    6336    6336      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/si5351/main.go
  24904   24904      0   0.00%    7584    7584      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/w5500/main.go
  92048   92048      0   0.00%    7964    7964      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/sd
  90996   90996      0   0.00%    8116    8116      0   0.00% tinygo build -size short -o ./build/test.hex -target=challenger-rp2040 ./examples/net/ntpclient/
 379000  379000      0   0.00%   14824   14824      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal -stack-size 8kb ./examples/net/http-get/
 126236  126236      0   0.00%    9056    9056      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 -stack-size 8kb ./examples/net/tcpclient/
 358556  358556      0   0.00%   13520   13520      0   0.00% tinygo build -size short -o ./build/test.hex -target=nano-rp2040 -stack-size 8kb ./examples/net/websocket/dial/
 108192  108192      0   0.00%   11036   11036      0   0.00% tinygo build -size short -o ./build/test.hex -target=metro-m4-airlift -stack-size 8kb ./examples/net/socket/
 426432  426432      0   0.00%   17500   17500      0   0.00% tinygo build -size short -o ./build/test.hex -target=matrixportal-m4 -stack-size 8kb ./examples/net/webstatic/
 172456  172456      0   0.00%    9184    9184      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-mkrwifi1010 -stack-size 8kb ./examples/net/tlsclient/
 163516  163516      0   0.00%   10020   10020      0   0.00% tinygo build -size short -o ./build/test.hex -target=nano-rp2040 -stack-size 8kb ./examples/net/mqttclient/natiu/
 122252  122252      0   0.00%   14348   14348      0   0.00% tinygo build -size short -o ./build/test.hex -target=wioterminal -stack-size 8kb ./examples/net/webclient/
 374908  374908      0   0.00%   19964   19964      0   0.00% tinygo build -size short -o ./build/test.hex -target=wioterminal -stack-size 8kb ./examples/net/webserver/
 373532  373532      0   0.00%   19024   19024      0   0.00% tinygo build -size short -o ./build/test.hex -target=wioterminal -stack-size 8kb ./examples/net/mqttclient/paho/
 180560  180560      0   0.00%   12464   12464      0   0.00% tinygo build -size short -o ./build/test.hex -target=elecrow-rp2040 -stack-size 8kb ./examples/net/tlsclient/
 126572  126572      0   0.00%   12332   12332      0   0.00% tinygo build -size short -o ./build/test.hex -target=elecrow-rp2350 -stack-size 8kb ./examples/net/ntpclient/
7023980 7023980      0   0.00% 1114870 1114870      0   0.00%

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Constant-expression sizing and same-width pointer conversion handling remain unresolved.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity

Open (1)
What changed in this PR

This PR fixes interpreter sizing for ptrtoint and inttoptr, including runtime handling for real pointers.

Changes:

  • Truncates or zero-extends integer conversion results.
  • Adds runtime support for pointer conversions.
  • Adds regression tests and expected output.
File Description
interp/​testdata/​ptrtoint.out.ll Defines expected transformed IR.
interp/​testdata/​ptrtoint.ll Covers narrowing, widening, and pointer conversions.
interp/​interpreter.go Implements conversion sizing and runtime support.
interp/​interp_test.go Registers the new test case.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread interp/interpreter.go
Comment on lines +671 to +675
if inst.opcode != llvm.BitCast {
bits := int(r.pointerSize * 8)
if inst.opcode == llvm.PtrToInt {
bits = inst.llvmInst.Type().IntTypeWidth()
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Constant expressions now truncate or zero-extend too. If a real pointer would need resizing, the value falls back to runtime, and a global with such an initializer is treated as external. Added test cases for both.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dkegel-fastly the requested changes have been made.

Comment thread interp/interpreter.go
if inst.opcode == llvm.PtrToInt {
bits = inst.llvmInst.Type().IntTypeWidth()
}
if int(operands[0].len(r)*8) != bits {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still misses same-width casts of real pointers. On a 64-bit target, converting a global pointer to uintptr and comparing it with a number fails in pointerValue.Uint, because the cast stays in the interpreter instead of running at runtime.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @jakebailey. I tried this with ptrtoint ptr @global to i64 followed by icmp ugt against a constant on x86_64. The result is the same on dev and on this PR. pointerValue.Uint sets a recoverable error, so interp gives up on that package init and runs it at runtime. It does not crash, but the whole init loses compile time evaluation.

The same width case is left as an identity on purpose. Keeping the pointer lets interp handle unsafe.Pointer(uintptr(p) + off), the strings.noescape xor trick, and pointer tagging with &. Sending every same width ptrtoint of a real pointer to runtime would push those to runtime too.

A narrower fix is to have icmp run at runtime when an ordered compare gets a pointer operand. That is not related to the size bug, so how about doing that in a separate PR?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems fine, however you want it; glad I was wrong

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opened #5748 for the icmp fix.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Address the moderate i1 ptrtoint truncation issue in interp/memory.go.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity · 1 Medium severity

Open (2)

Comment thread interp/memory.go

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Constant conversions produce incorrect values on big-endian targets.

Review effort: Balanced
Findings: 1 High severity

Open (1)
Resolved since last review (1)
Previously missed (1)

In code that hasn't changed since last review

Medium severity Use endian-correct byte selection for constant conversions

interp/​memory.go:1042

This copies low-address bytes. On big-endian MIPS, truncation needs the trailing bytes and widening needs leading zero bytes, so constant conversions get the wrong value.

@deadprogram

Copy link
Copy Markdown
Member Author

Thanks everyone, now squash/merging.

@deadprogram
deadprogram merged commit 835e0eb into dev Sep 25, 2026
40 checks passed
@deadprogram
deadprogram deleted the interp-ptrtoint-size branch September 25, 2026 20:11
zombieleet pushed a commit to zombieleet/tinygo that referenced this pull request Sep 26, 2026
* interp: resize ptrtoint and inttoptr results

The interpreter treated ptrtoint and inttoptr as identity operations, so
the result kept the width of the operand. A method call through an
interface on a receiver narrower than a pointer then passed a value of
the wrong size, and interp panicked with "comparing values of different
size".

Truncate or zero-extend integer operands to the result width. Emit the
instruction at runtime when the operand is a pointer.

Fixes tinygo-org#5642

* interp: resize constant ptrtoint and inttoptr expressions

* interp: defer constant ptrtoint to non-byte-sized integers
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.

interp: panic "reading values of different sizes" on short-receiver method call in init

3 participants