Issue |
137968
|
Summary |
[RISCV] `clang` generates incorrect code and uses wrong register during array indexing when using any optimization level other than `-O0`
|
Labels |
clang
|
Assignees |
|
Reporter |
thebigclub
|
Found a case where `clang` misbehaves. The wrong register is being used to generate the memory address that's read. This causes the generated program to crash because an incorrect location (`0xffffffff`) is accessed:
```bash
$ cat << EOF > test.c
#include <stddef.h>
size_t fn(const char *str) {
size_t ret = 4, sp = 4;
char c0 = str[0 - sp], c3 = str[3 - sp];
if (c0 == 0) return ret + 0 - sp;
if (c3 == 0) return ret + 3 - sp;
return 0;
}
EOF
$ clang -O3 -c test.c
$ llvm-objdump -d test.o
test.o: file format elf32-littleriscv
Disassembly of section .text:
00000000 <fn>:
0: ffc54503 lbu a0, -0x4(a0)
4: c101 beqz a0, 0x4 <fn+0x4>
6: fff04503 lbu a0, -0x1(zero)
a: 00a03533 snez a0, a0
e: 157d addi a0, a0, -0x1
10: 890d andi a0, a0, 0x3
12: 8082 ret
$ clang -v
clang version 21.0.0git (https://github.com/llvm/llvm-project.git 4aca20c8b6dcf86696db03d860e635112601a7f9)
Target: riscv32-unknown-unknown-elf
```
Notice that the second load uses the `zero` register (`x0`). This register always returns the value zero when read. It should be using the `a0` register instead.
If you change the _expression_ `3 - sp` to `-1`, the correct code is generated:
```bash
test.o: file format elf32-littleriscv
Disassembly of section .text:
00000000 <fn>:
0: ffc54583 lbu a1, -0x4(a0)
4: c181 beqz a1, 0x4 <fn+0x4>
6: fff54503 lbu a0, -0x1(a0)
a: 00a03533 snez a0, a0
e: 157d addi a0, a0, -0x1
10: 890d andi a0, a0, 0x3
12: 8082 ret
14: 4501 li a0, 0x0
16: 8082 ret
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs