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

Reply via email to