Strange invalid 16-bit optimization
- Dominant language
- Scala
- Stars
- 279
- Forks
- 21
- PR merge metrics
- No merged PRs in 30d
Description
I ran across this while working on my Millfork NES game, and initially patched it up with some inline assembly because I wanted to keep going, but it's getting to the point of being annoying. I can try to create a minimal reproducible example if that's necessary, but this is my code:
```
// i'm using addresses for these so my emulator script for drawing a debug overlay knows where to find them
array(word) enemy_xs[12] align(fast) @ $a8
array enemy_ys[12] @ $62
array enemy_types[12] @ $580
array enemy_healths[12] @ $ca
array enemy_data1[12] @ $f1
array enemy_data2[12] @ $6f
array enemy_data3[12] @ $1b
array enemy_tags[12] @ $9d
byte enemy_count @ $9a
// [...]
// part of the code for enemies dying
if (enemy_healths[i] == 0 && enemy_flags[enemy_types[i]] & $20 == 0) {
create_effect($80, enemy_xs[i], enemy_ys[i], $20, 0) // enemy dying from damage
}
destroy_enemy(i)
i += 1
```
On optimization level 1 (which I don't want to use unless I have to), those arguments are compiled into
```
LDA #$80
STA create_effect$type
LDA main$i
ASL
TAY
LDA $A8, Y
INY
STA create_effect$x
LDA $A8, Y
STA create_effect$x + 1
LDY main$i
LDA $62, Y
STA create_effect$y
LDA #$20
STA create_effect$timer
LDA #0
STA create_effect$flags
```
On O2 and up, we instead get
```
LDA main$i
ASL
TAY
LDA $A8, Y
STA create_effect$x + 1
STA create_effect$x
LDY main$i
LDA $62, Y
STA create_effect$y
LDA #$80
```
Some of the arguments are optimized into registers (yay!) but the sketchy thing here is those two `STA` back to back. The low and high bytes of entries of `enemy_xs` are NOT the same. This has shown up in other situations before involving loading from array of words.
Contributor guide
Research direction
Start by reproducing the supplied enemy_xs array-of-word case in Millfork and compare generated assembly at optimization levels 1 and 2. Inspect the compiler's 16-bit array-load optimization and verify that the low and high bytes remain distinct in the output, including for a minimal reproducible example.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- scala
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100