[M68k] Indexing an array with a variable generates incorrect code
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
This C program generates incorrect code for m68k. Array indexing inside a `for` loop isn't generating correct code.
```C
#include
#include
// printing with linux syscall write (#4)
static void print(const char *bufptr, uint32_t buflen)
{
asm("move.l %0, %%d2" :: "r"(bufptr)); // buf
asm("move.l %0, %%d3" :: "r"(buflen)); // len
asm("movem.l %a0-%a1/%d0-%d1, -(%sp)");
asm("move.l #4, %d0"); // syscall write
asm("move.l #1, %d1"); // fd
asm("trap #0");
asm("movem.l (%sp)+, %d0-%d1/%a0-%a1");
}
// exit with linux syscall (#1)
static void exit(int32_t code)
{
asm("move.l %0, %%d1" :: "r"(code));
asm("move.l #1, %d0"); // syscall exit
asm("trap #0");
}
int main(void) {
uint8_t arr[3];
// ISSUE: this for loop stores 123 only to the first index
for (size_t i = 0; i < 3; ++i) {
arr[i] = 123;
}
if (arr[1] == 123) {
print("123 found!\n", 11);
} else {
print("no 123!\n", 8);
}
exit(0);
}
```
The code can be seen in [Godbolt for M68K clang (trunk)](https://godbolt.org/z/h6j1r49qo):
```asm
28: move.l (65524,%a6), %d0 ; moves i to d0
2c: move.b #123, (65529,%a6) ; moves #123 repeatedly to the same address, ignoring i
```
It's possible to build and run the program by executing these commands:
```
clang -target m68k-unknown-linux -c loop.c -o loop.o
mold loop.o -o loop -m m68kelf # uses mold for linking
qemu-m68k-static loop # runs the executable with qemu
```
The result is that it prints `no 123!`, which shows that indexing the array isn't performed correctly.
If the program is build with `-O3` optimization, then the program works and prints out `123 found!`, because the compiler optimizes away the `for` loop. However, I have been able to create more complex programs where `-O3` can't optimize code away and then the same issue shows up.
Contributor guide
Research direction
Start with the provided loop.c reproduction and build it using clang -target m68k-unknown-linux, mold, and qemu-m68k-static. Inspect the generated m68k assembly around the variable array index, then compare behavior with and without -O3. Done means the unoptimized program stores 123 at each array element and prints "123 found!".
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100