| Issue |
107520
|
| Summary |
[RISC-V] Outliner can place paired %pcrel_hi/%pcrel_lo in different sections resulting in link errors for GNU ld
|
| Labels |
backend:RISC-V
|
| Assignees |
jonathonpenix
|
| Reporter |
jonathonpenix
|
Please see below for a small-ish reproducer to demonstrate the issue. I am testing with LLVM built at ede40da1f8c1e91601b985cd32ad785aa8806880 and GNU ld from binutils v2.39.
```
$ cat test.c
#include <stdio.h>
#include <stdlib.h>
int v1 = 0;
int v2 = 1;
int *a1;
int *a2;
int main(int argc, char **argv)
{
a1 = malloc(sizeof(int) * 2);
a2 = malloc(sizeof(int) * 2);
fprintf(stderr, "%d\n", 0);
for (int i = 0; i <= 1; i++) {
printf("%d %d\n", a1[v1], a2[v1]);
printf("%d %d\n", a1[v2], a2[v2]);
}
}
$ clang --target=riscv32-linux-gnu -mabi=ilp32 --sysroot=/path/to/riscv/sysroot --gcc-toolchain=/path/to/gcc/toolchain test.c -Oz
/tmp/test-5a64de.o: in function `OUTLINED_FUNCTION_0':
test.c:(.text+0x4): dangerous relocation: %pcrel_lo missing matching %pcrel_hi
clang: error: linker command failed with exit code 1 (use -v to see invocation)
```
Relevant assembly snippet:
```
$ llvm-objdump -dr test.o
...
Disassembly of section .text:
00000000 <OUTLINED_FUNCTION_0>:
0: 00092583 lw a1, 0x0(s2)
00000000: R_RISCV_PCREL_LO12_I .Lpcrel_hi0
00000000: R_RISCV_RELAX *ABS*
4: 0009a603 lw a2, 0x0(s3)
00000004: R_RISCV_PCREL_LO12_I .Lpcrel_hi1
00000004: R_RISCV_RELAX *ABS*
...
Disassembly of section .text.unlikely.:
00000000 <main>:
...
0000001a <.Lpcrel_hi0>:
1a: 00000917 auipc s2, 0x0
0000001a: R_RISCV_PCREL_HI20 a1
0000001a: R_RISCV_RELAX *ABS*
1e: 00a92023 sw a0, 0x0(s2)
0000001e: R_RISCV_PCREL_LO12_S .Lpcrel_hi0
0000001e: R_RISCV_RELAX *ABS*
...
00000036 <.Lpcrel_hi1>:
36: 00000997 auipc s3, 0x0
00000036: R_RISCV_PCREL_HI20 a2
00000036: R_RISCV_RELAX *ABS*
3a: 00a9a023 sw a0, 0x0(s3)
0000003a: R_RISCV_PCREL_LO12_S .Lpcrel_hi1
0000003a: R_RISCV_RELAX *ABS*
...
```
After 6b11573b8c5e3d36beee099dbe7347c2a007bf53 (though I don't think that commit is actually the problem here) `main` seems to be marked as cold and ultimately placed in `.text.unlikely` (and contains the pcrel_hi) but the outlined function with the pcrel_lo is placed into `.text`. My understanding is that GNU ld erroring here is expected based on https://reviews.llvm.org/D132528.
As a quick fix for this, I think we can take an approach similar to https://reviews.llvm.org/D132528 and make sure that functions that will be prefixed (with unlikely, unknown, etc.) will also be disallowed for outlining when the outlining candidate contains pcrel_lo.
I'm planning to try to submit a PR for this soon, but any suggestions/thoughts/etc. would be greatly appreciated!
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs