llvm / llvm/llvm-project

[M68k] Indexing an array with a variable generates incorrect code

Open
#187,279 2 comments 0 reactions 0 assignees View on GitHub
backend:m68k inline-asm
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.