[lld] [RISCV] Disable gp relaxation if part of object unreachable (PR #72655)

Nemanja Ivanovic via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 27 09:04:35 PST 2023


https://github.com/nemanjai updated https://github.com/llvm/llvm-project/pull/72655

>From 61f44ad222d9379fab4722ce57aa94ce20b042e7 Mon Sep 17 00:00:00 2001
From: Nemanja Ivanovic <nemanja at synopsys.com>
Date: Fri, 17 Nov 2023 15:49:11 +0100
Subject: [PATCH 1/4] [RISCV] Disable gp relaxation if part of object
 unreachable

Linker gp relaxation is greedy. It will eliminate the LUI
with R_RISCV_HI20 if the base of the object is reachable
from the gp. The relaxation on the R_RISCV_LO12 will be
rejected if it is not reachable, but that is too late if
the corresponding R_RISCV_HI20 is gone.
This patch disables relaxation if the entire portion of
the object that can be relocated together is not reachable.

It is important that this does not necessarily mean the
size of the object since the size doesn't matter if its
alignment is smaller than its size.

In order to achieve correctness without excessively
pessimizing relaxation for large objects, relaxation
is rejected if the base of the object + min(s, ma) is
not reachable from gp, where:
s  - size of the object
ma - maximum alignment of the section that contains
     the object.
---
 lld/ELF/Arch/RISCV.cpp                | 14 +++++++
 lld/test/ELF/riscv-relax-gp-partial.s | 58 +++++++++++++++++++++++++++
 2 files changed, 72 insertions(+)
 create mode 100644 lld/test/ELF/riscv-relax-gp-partial.s

diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 6413dcd7dcd7976..d4c578934a0bb39 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -651,6 +651,20 @@ static void relaxHi20Lo12(const InputSection &sec, size_t i, uint64_t loc,
   if (!isInt<12>(r.sym->getVA(r.addend) - gp->getVA()))
     return;
 
+  // The symbol may be accessed in multiple pieces. We need to make sure that
+  // all of the possible accesses are relaxed or none are. This prevents
+  // relaxing the hi relocation and being unable to relax one of the low
+  // relocations. The compiler will only access multiple pieces of an object
+  // with low relocations on the memory op if the alignment allows it.
+  // Therefore it should suffice to check that the smaller of the alignment
+  // and size can be reached from GP.
+  uint32_t alignAdjust =
+      r.sym->getOutputSection() ? r.sym->getOutputSection()->addralign : 0;
+  alignAdjust = std::min<uint32_t>(alignAdjust, r.sym->getSize());
+
+  if (!isInt<12>(r.sym->getVA() + alignAdjust - gp->getVA()))
+    return;
+
   switch (r.type) {
   case R_RISCV_HI20:
     // Remove lui rd, %hi20(x).
diff --git a/lld/test/ELF/riscv-relax-gp-partial.s b/lld/test/ELF/riscv-relax-gp-partial.s
new file mode 100644
index 000000000000000..79984d9b65b7cfb
--- /dev/null
+++ b/lld/test/ELF/riscv-relax-gp-partial.s
@@ -0,0 +1,58 @@
+# REQUIRES: riscv
+# RUN: rm -rf %t && split-file %s %t && cd %t
+
+# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf -mattr=+relax a.s -o rv32.o
+# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=+relax a.s -o rv64.o
+
+# RUN: ld.lld --relax-gp --undefined=__global_pointer$ rv32.o lds -o rv32
+# RUN: ld.lld --relax-gp --undefined=__global_pointer$ rv64.o lds -o rv64
+# RUN: llvm-objdump -td -M no-aliases --no-show-raw-insn rv32 | FileCheck %s
+# RUN: llvm-objdump -td -M no-aliases --no-show-raw-insn rv64 | FileCheck %s
+ 
+# CHECK: 00000080 l       .data  {{0+}}08 Var0
+# CHECK: 00001000 l       .data  {{0+}}80 Var1
+# CHECK: 00000815 g       .sdata {{0+}}00 __global_pointer$
+
+# CHECK: <_start>:
+# CHECK-NOT:  lui
+# CHECK-NEXT: lw      a0, -1941(gp)
+# CHECK-NEXT: lw      a1, -1937(gp)
+# CHECK-NEXT: lui     a1, 1
+# CHECK-NEXT: lw      a0, 0(a1)
+# CHECK-NEXT: lw      a1, 124(a1)
+
+#--- a.s
+.global _start
+_start:
+        lui     a1, %hi(Var0)
+        lw      a0, %lo(Var0)(a1)
+        lw      a1, %lo(Var0+4)(a1)
+        lui     a1, %hi(Var1)
+        lw      a0, %lo(Var1)(a1)      # First part is reachable from gp
+        lw      a1, %lo(Var1+124)(a1)  # The second part is not reachable
+
+.section .rodata
+foo:
+  .space 1
+.section .sdata,"aw"
+  .space 1
+.section .data,"aw"
+  .p2align 3
+Var0:
+  .quad 0
+  .size   Var0, 8
+  .space 3960
+  .p2align 7
+Var1:
+  .quad 0
+  .zero 120
+  .size   Var1, 128
+
+#--- lds
+    SECTIONS {
+        .text : { }
+        .rodata : { }
+        .sdata : { }
+        .sbss : { }
+        .data : { }
+    }

>From 0a64d43e3cc472a78021b278e8bf9c3cdba57ae4 Mon Sep 17 00:00:00 2001
From: Nemanja Ivanovic <nemanja at synopsys.com>
Date: Mon, 27 Nov 2023 16:24:40 +0100
Subject: [PATCH 2/4] Address review comments

- Add a test that rejects the relaxation due to alignment (smaller
  than object size)
- Fix the adjustment to be 1 byte less since that is the minimum
  requirement for addressability
- Add code to reject relaxing the HI20 relocation when the addend
  is non-zero (i.e. check the range HI20 +/- adjustment)
- Restrict the code that rejects relaxation to the relaxation of
  HI20 since the LO12 can still proceed as nothing depends on it
---
 lld/ELF/Arch/RISCV.cpp                        | 35 ++++++++----
 .../ELF/riscv-relax-gp-partial-align-min.s    | 40 ++++++++++++++
 .../ELF/riscv-relax-gp-partial-hi20-addend.s  | 54 +++++++++++++++++++
 lld/test/ELF/riscv-relax-gp-partial.s         | 16 +++---
 4 files changed, 126 insertions(+), 19 deletions(-)
 create mode 100644 lld/test/ELF/riscv-relax-gp-partial-align-min.s
 create mode 100644 lld/test/ELF/riscv-relax-gp-partial-hi20-addend.s

diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index d4c578934a0bb39..7d01e7f89cd0581 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -651,26 +651,39 @@ static void relaxHi20Lo12(const InputSection &sec, size_t i, uint64_t loc,
   if (!isInt<12>(r.sym->getVA(r.addend) - gp->getVA()))
     return;
 
-  // The symbol may be accessed in multiple pieces. We need to make sure that
-  // all of the possible accesses are relaxed or none are. This prevents
-  // relaxing the hi relocation and being unable to relax one of the low
-  // relocations. The compiler will only access multiple pieces of an object
-  // with low relocations on the memory op if the alignment allows it.
-  // Therefore it should suffice to check that the smaller of the alignment
-  // and size can be reached from GP.
+  // The symbol may be accessed in multiple pieces with different addends.
+  // If we are relaxing the HI20 relocation, we need to ensure that we only
+  // relax (and delete the instruction) if all possible LO12 relocations
+  // that depend on it will be relaxable. The compiler will only access multiple
+  // pieces of an object with low relocations on the memory op if the alignment
+  // allows it. Therefore it should suffice to check that the smaller of the
+  // alignment and size can be reached from GP.
   uint32_t alignAdjust =
       r.sym->getOutputSection() ? r.sym->getOutputSection()->addralign : 0;
   alignAdjust = std::min<uint32_t>(alignAdjust, r.sym->getSize());
-
-  if (!isInt<12>(r.sym->getVA() + alignAdjust - gp->getVA()))
-    return;
+  if (alignAdjust)
+    alignAdjust--;
 
   switch (r.type) {
-  case R_RISCV_HI20:
+  case R_RISCV_HI20: {
+    uint64_t hiAddr = r.sym->getVA(r.addend);
+    // If the addend is zero, the LO12 relocations can only be accessing the
+    // range [base, base+alignAdjust] (where base == r.sym->getVA()).
+    if (r.addend == 0 && !isInt<12>(hiAddr + alignAdjust - gp->getVA()))
+      return;
+
+    // However, if the addend is non-zero, the LO12 relocations may be accessing
+    // the range [HI-alignAdjust-1, HI+alignAdjust].
+    if (r.addend != 0 &&
+        (!isInt<12>(hiAddr - alignAdjust - 1 - gp->getVA()) ||
+         !isInt<12>(hiAddr + alignAdjust - gp->getVA())))
+      return;
+
     // Remove lui rd, %hi20(x).
     sec.relaxAux->relocTypes[i] = R_RISCV_RELAX;
     remove = 4;
     break;
+  }
   case R_RISCV_LO12_I:
     sec.relaxAux->relocTypes[i] = INTERNAL_R_RISCV_GPREL_I;
     break;
diff --git a/lld/test/ELF/riscv-relax-gp-partial-align-min.s b/lld/test/ELF/riscv-relax-gp-partial-align-min.s
new file mode 100644
index 000000000000000..0ffa315991cb823
--- /dev/null
+++ b/lld/test/ELF/riscv-relax-gp-partial-align-min.s
@@ -0,0 +1,40 @@
+# REQUIRES: riscv
+# RUN: rm -rf %t && split-file %s %t && cd %t
+
+# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf -mattr=+relax a.s -o rv32.o
+# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=+relax a.s -o rv64.o
+
+# RUN: ld.lld --relax-gp --undefined=__global_pointer$ rv32.o lds -o rv32
+# RUN: ld.lld --relax-gp --undefined=__global_pointer$ rv64.o lds -o rv64
+# RUN: llvm-objdump -td -M no-aliases --no-show-raw-insn rv32 | FileCheck %s
+# RUN: llvm-objdump -td -M no-aliases --no-show-raw-insn rv64 | FileCheck %s
+ 
+# CHECK: 000017e0 l       .data  {{0+}}80 Var1
+# CHECK: 00000ffc g       .sdata {{0+}}00 __global_pointer$
+
+# CHECK: <_start>:
+# CHECK-NEXT: lui     a1, 1
+# CHECK-NEXT: lw      a0, 2020(gp)
+# CHECK-NEXT: lw      a1, 2044(a1)
+
+#--- a.s
+.global _start
+_start:
+        lui     a1, %hi(Var1)
+        lw      a0, %lo(Var1)(a1)      # First part is reachable from gp
+        lw      a1, %lo(Var1+28)(a1)   # The second part is not reachable
+
+.section .sdata,"aw"
+.section .data,"aw"
+  .p2align 5
+Var1:
+  .quad 0
+  .zero 120
+  .size   Var1, 128
+
+#--- lds
+SECTIONS {
+  .text : { }
+  .sdata 0x07fc : { }
+  .data  0x17E0 : { }
+}
diff --git a/lld/test/ELF/riscv-relax-gp-partial-hi20-addend.s b/lld/test/ELF/riscv-relax-gp-partial-hi20-addend.s
new file mode 100644
index 000000000000000..9877ec8137e4ec2
--- /dev/null
+++ b/lld/test/ELF/riscv-relax-gp-partial-hi20-addend.s
@@ -0,0 +1,54 @@
+# REQUIRES: riscv
+# RUN: rm -rf %t && split-file %s %t && cd %t
+
+# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf -mattr=+relax a.s -o rv32.o
+# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=+relax a.s -o rv64.o
+
+# RUN: ld.lld --relax-gp --undefined=__global_pointer$ rv32.o lds -o rv32
+# RUN: ld.lld --relax-gp --undefined=__global_pointer$ rv64.o lds -o rv64
+# RUN: llvm-objdump -td -M no-aliases --no-show-raw-insn rv32 | FileCheck %s
+# RUN: llvm-objdump -td -M no-aliases --no-show-raw-insn rv64 | FileCheck %s
+ 
+# CHECK: 00001000 l       .data  {{0+}}08 Var0
+# CHECK: 00001f80 l       .data1 {{0+}}80 Var1
+# CHECK: 00001800 g       .sdata {{0+}}00 __global_pointer$
+
+# CHECK: <_start>:
+# CHECK-NEXT: lui     a1, 1
+# CHECK-NEXT: lw      a0, -2048(gp)
+# CHECK-NEXT: lw      a1, -2044(gp)
+# CHECK-NEXT: lui     a1, 2
+# CHECK-NEXT: lw      a0, 1920(gp)
+# CHECK-NEXT: lw      a1, 2044(gp)
+
+#--- a.s
+.global _start
+_start:
+        lui     a1, %hi(Var0+4)        # Cannot prove that %lo relocs will be reachable
+        lw      a0, %lo(Var0)(a1)      # Reachable from GP
+        lw      a1, %lo(Var0+4)(a1)    # Reachable from GP
+        lui     a1, %hi(Var1+124)      # Cannot prove that %lo relocs will be reachable
+        lw      a0, %lo(Var1)(a1)      # Reachable from GP
+        lw      a1, %lo(Var1+124)(a1)  # Reachable from GP
+
+.section .sdata,"aw"
+.section .data,"aw"
+  .p2align 3
+Var0:
+  .quad 0
+  .size   Var0, 8
+
+.section .data1,"aw"
+  .p2align 7
+Var1:
+  .quad 0
+  .zero 120
+  .size   Var1, 128
+
+#--- lds
+SECTIONS {
+  .text : { }
+  .sdata 0x1000 : { }
+  .data  0x1000 : { }
+  .data1 0x1f80 : { }
+}
diff --git a/lld/test/ELF/riscv-relax-gp-partial.s b/lld/test/ELF/riscv-relax-gp-partial.s
index 79984d9b65b7cfb..fedc41f24e2d6a0 100644
--- a/lld/test/ELF/riscv-relax-gp-partial.s
+++ b/lld/test/ELF/riscv-relax-gp-partial.s
@@ -18,7 +18,7 @@
 # CHECK-NEXT: lw      a0, -1941(gp)
 # CHECK-NEXT: lw      a1, -1937(gp)
 # CHECK-NEXT: lui     a1, 1
-# CHECK-NEXT: lw      a0, 0(a1)
+# CHECK-NEXT: lw      a0, 2027(gp)
 # CHECK-NEXT: lw      a1, 124(a1)
 
 #--- a.s
@@ -49,10 +49,10 @@ Var1:
   .size   Var1, 128
 
 #--- lds
-    SECTIONS {
-        .text : { }
-        .rodata : { }
-        .sdata : { }
-        .sbss : { }
-        .data : { }
-    }
+SECTIONS {
+  .text : { }
+  .rodata : { }
+  .sdata : { }
+  .sbss : { }
+  .data : { }
+}

>From b8bd95f9c5590701b371d7d25996efe6d8289308 Mon Sep 17 00:00:00 2001
From: Nemanja Ivanovic <nemanja at synopsys.com>
Date: Mon, 27 Nov 2023 16:31:41 +0100
Subject: [PATCH 3/4] Run clang-format.

---
 lld/ELF/Arch/RISCV.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 7d01e7f89cd0581..ecbf8aaeeb3a510 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -674,9 +674,8 @@ static void relaxHi20Lo12(const InputSection &sec, size_t i, uint64_t loc,
 
     // However, if the addend is non-zero, the LO12 relocations may be accessing
     // the range [HI-alignAdjust-1, HI+alignAdjust].
-    if (r.addend != 0 &&
-        (!isInt<12>(hiAddr - alignAdjust - 1 - gp->getVA()) ||
-         !isInt<12>(hiAddr + alignAdjust - gp->getVA())))
+    if (r.addend != 0 && (!isInt<12>(hiAddr - alignAdjust - 1 - gp->getVA()) ||
+                          !isInt<12>(hiAddr + alignAdjust - gp->getVA())))
       return;
 
     // Remove lui rd, %hi20(x).

>From c4667aa586e71a66efe086492e4f11766c9e2ef9 Mon Sep 17 00:00:00 2001
From: Nemanja Ivanovic <nemanja at synopsys.com>
Date: Mon, 27 Nov 2023 18:03:28 +0100
Subject: [PATCH 4/4] Consolidate tests into a single file.

---
 lld/test/ELF/riscv-relax-gp-edges.s           | 147 ++++++++++++++++++
 .../ELF/riscv-relax-gp-partial-align-min.s    |  40 -----
 .../ELF/riscv-relax-gp-partial-hi20-addend.s  |  54 -------
 lld/test/ELF/riscv-relax-gp-partial.s         |  58 -------
 4 files changed, 147 insertions(+), 152 deletions(-)
 create mode 100644 lld/test/ELF/riscv-relax-gp-edges.s
 delete mode 100644 lld/test/ELF/riscv-relax-gp-partial-align-min.s
 delete mode 100644 lld/test/ELF/riscv-relax-gp-partial-hi20-addend.s
 delete mode 100644 lld/test/ELF/riscv-relax-gp-partial.s

diff --git a/lld/test/ELF/riscv-relax-gp-edges.s b/lld/test/ELF/riscv-relax-gp-edges.s
new file mode 100644
index 000000000000000..e355e242732907d
--- /dev/null
+++ b/lld/test/ELF/riscv-relax-gp-edges.s
@@ -0,0 +1,147 @@
+# REQUIRES: riscv
+# RUN: rm -rf %t && split-file %s %t && cd %t
+
+# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf -mattr=+relax a.s -o rv32a.o
+# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=+relax a.s -o rv64a.o
+# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf -mattr=+relax b.s -o rv32b.o
+# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=+relax b.s -o rv64b.o
+# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf -mattr=+relax c.s -o rv32c.o
+# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=+relax c.s -o rv64c.o
+
+# RUN: ld.lld --relax-gp --undefined=__global_pointer$ rv32a.o lds.a -o rv32a
+# RUN: ld.lld --relax-gp --undefined=__global_pointer$ rv64a.o lds.a -o rv64a
+# RUN: ld.lld --relax-gp --undefined=__global_pointer$ rv32b.o lds.b -o rv32b
+# RUN: ld.lld --relax-gp --undefined=__global_pointer$ rv64b.o lds.b -o rv64b
+# RUN: ld.lld --relax-gp --undefined=__global_pointer$ rv32c.o lds.c -o rv32c
+# RUN: ld.lld --relax-gp --undefined=__global_pointer$ rv64c.o lds.c -o rv64c
+# RUN: llvm-objdump -td -M no-aliases --no-show-raw-insn rv32a | FileCheck %s --check-prefix=CHECK-ALIGN
+# RUN: llvm-objdump -td -M no-aliases --no-show-raw-insn rv64a | FileCheck %s --check-prefix=CHECK-ALIGN
+# RUN: llvm-objdump -td -M no-aliases --no-show-raw-insn rv32b | FileCheck %s --check-prefix=CHECK-HI-ADD
+# RUN: llvm-objdump -td -M no-aliases --no-show-raw-insn rv64b | FileCheck %s --check-prefix=CHECK-HI-ADD
+# RUN: llvm-objdump -td -M no-aliases --no-show-raw-insn rv32c | FileCheck %s --check-prefix=CHECK-SIZE
+# RUN: llvm-objdump -td -M no-aliases --no-show-raw-insn rv64c | FileCheck %s --check-prefix=CHECK-SIZE
+ 
+# CHECK-ALIGN: 000017e0 l       .data  {{0+}}80 Var1
+# CHECK-ALIGN: 00000ffc g       .sdata {{0+}}00 __global_pointer$
+
+# CHECK-ALIGN: <_start>:
+# CHECK-ALIGN-NEXT: lui     a1, 1
+# CHECK-ALIGN-NEXT: lw      a0, 2020(gp)
+# CHECK-ALIGN-NEXT: lw      a1, 2044(a1)
+
+#--- a.s
+# The relaxation on the lui is rejected because the alignment (which is smaller
+# than the size) doesn't allow it.
+.global _start
+_start:
+        lui     a1, %hi(Var1)
+        lw      a0, %lo(Var1)(a1)      # First part is reachable from gp
+        lw      a1, %lo(Var1+28)(a1)   # The second part is not reachable
+
+.section .sdata,"aw"
+.section .data,"aw"
+  .p2align 5
+Var1:
+  .quad 0
+  .zero 120
+  .size   Var1, 128
+
+#--- lds.a
+SECTIONS {
+  .text : { }
+  .sdata 0x07fc : { }
+  .data  0x17E0 : { }
+}
+ 
+# CHECK-HI-ADD: 00001000 l       .data  {{0+}}08 Var0
+# CHECK-HI-ADD: 00001f80 l       .data1 {{0+}}80 Var1
+# CHECK-HI-ADD: 00001800 g       .sdata {{0+}}00 __global_pointer$
+
+# CHECK-HI-ADD: <_start>:
+# CHECK-HI-ADD-NEXT: lui     a1, 1
+# CHECK-HI-ADD-NEXT: lw      a0, -2048(gp)
+# CHECK-HI-ADD-NEXT: lw      a1, -2044(gp)
+# CHECK-HI-ADD-NEXT: lui     a1, 2
+# CHECK-HI-ADD-NEXT: lw      a0, 1920(gp)
+# CHECK-HI-ADD-NEXT: lw      a1, 2044(gp)
+
+#--- b.s
+# The relaxation on the two lui are rejected because the amount of data a LO12
+# reloc is allowed to address below and above the respective HI20 goes past
+# the amount reachable from GP.
+.global _start
+_start:
+        lui     a1, %hi(Var0+4)        # Cannot prove that %lo relocs will be reachable
+        lw      a0, %lo(Var0)(a1)      # Reachable from GP
+        lw      a1, %lo(Var0+4)(a1)    # Reachable from GP
+        lui     a1, %hi(Var1+124)      # Cannot prove that %lo relocs will be reachable
+        lw      a0, %lo(Var1)(a1)      # Reachable from GP
+        lw      a1, %lo(Var1+124)(a1)  # Reachable from GP
+
+.section .sdata,"aw"
+.section .data,"aw"
+  .p2align 3
+Var0:
+  .quad 0
+  .size   Var0, 8
+
+.section .data1,"aw"
+  .p2align 7
+Var1:
+  .quad 0
+  .zero 120
+  .size   Var1, 128
+
+#--- lds.b
+SECTIONS {
+  .text : { }
+  .sdata 0x1000 : { }
+  .data  0x1000 : { }
+  .data1 0x1f80 : { }
+}
+
+# CHECK-SIZE: 00000080 l       .data  {{0+}}08 Var0
+# CHECK-SIZE: 00001000 l       .data1 {{0+}}80 Var1
+# CHECK-SIZE: 00000815 g       .sdata {{0+}}00 __global_pointer$
+
+# CHECK-SIZE: <_start>:
+# CHECK-SIZE-NOT:  lui
+# CHECK-SIZE-NEXT: lw      a0, -1941(gp)
+# CHECK-SIZE-NEXT: lw      a1, -1937(gp)
+# CHECK-SIZE-NEXT: lui     a1, 1
+# CHECK-SIZE-NEXT: lw      a0, 2027(gp)
+# CHECK-SIZE-NEXT: lw      a1, 124(a1)
+
+#--- c.s
+# The relaxation on the second lui is rejected because the size (and alignment)
+# allow for a LO12 that cannot reach its target from GP.
+.global _start
+_start:
+        lui     a1, %hi(Var0)
+        lw      a0, %lo(Var0)(a1)
+        lw      a1, %lo(Var0+4)(a1)
+        lui     a1, %hi(Var1)
+        lw      a0, %lo(Var1)(a1)      # First part is reachable from gp
+        lw      a1, %lo(Var1+124)(a1)  # The second part is not reachable
+
+.section .sdata,"aw"
+.section .data,"aw"
+  .p2align 3
+Var0:
+  .quad 0
+  .size   Var0, 8
+
+.section .data1,"aw"
+  .p2align 7
+Var1:
+  .quad 0
+  .zero 120
+  .size   Var1, 128
+
+#--- lds.c
+SECTIONS {
+  .text : { }
+  .sdata  0x0015 : { }
+  .data   0x0080 : { }
+  .data1  0x1000 : { }
+}
diff --git a/lld/test/ELF/riscv-relax-gp-partial-align-min.s b/lld/test/ELF/riscv-relax-gp-partial-align-min.s
deleted file mode 100644
index 0ffa315991cb823..000000000000000
--- a/lld/test/ELF/riscv-relax-gp-partial-align-min.s
+++ /dev/null
@@ -1,40 +0,0 @@
-# REQUIRES: riscv
-# RUN: rm -rf %t && split-file %s %t && cd %t
-
-# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf -mattr=+relax a.s -o rv32.o
-# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=+relax a.s -o rv64.o
-
-# RUN: ld.lld --relax-gp --undefined=__global_pointer$ rv32.o lds -o rv32
-# RUN: ld.lld --relax-gp --undefined=__global_pointer$ rv64.o lds -o rv64
-# RUN: llvm-objdump -td -M no-aliases --no-show-raw-insn rv32 | FileCheck %s
-# RUN: llvm-objdump -td -M no-aliases --no-show-raw-insn rv64 | FileCheck %s
- 
-# CHECK: 000017e0 l       .data  {{0+}}80 Var1
-# CHECK: 00000ffc g       .sdata {{0+}}00 __global_pointer$
-
-# CHECK: <_start>:
-# CHECK-NEXT: lui     a1, 1
-# CHECK-NEXT: lw      a0, 2020(gp)
-# CHECK-NEXT: lw      a1, 2044(a1)
-
-#--- a.s
-.global _start
-_start:
-        lui     a1, %hi(Var1)
-        lw      a0, %lo(Var1)(a1)      # First part is reachable from gp
-        lw      a1, %lo(Var1+28)(a1)   # The second part is not reachable
-
-.section .sdata,"aw"
-.section .data,"aw"
-  .p2align 5
-Var1:
-  .quad 0
-  .zero 120
-  .size   Var1, 128
-
-#--- lds
-SECTIONS {
-  .text : { }
-  .sdata 0x07fc : { }
-  .data  0x17E0 : { }
-}
diff --git a/lld/test/ELF/riscv-relax-gp-partial-hi20-addend.s b/lld/test/ELF/riscv-relax-gp-partial-hi20-addend.s
deleted file mode 100644
index 9877ec8137e4ec2..000000000000000
--- a/lld/test/ELF/riscv-relax-gp-partial-hi20-addend.s
+++ /dev/null
@@ -1,54 +0,0 @@
-# REQUIRES: riscv
-# RUN: rm -rf %t && split-file %s %t && cd %t
-
-# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf -mattr=+relax a.s -o rv32.o
-# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=+relax a.s -o rv64.o
-
-# RUN: ld.lld --relax-gp --undefined=__global_pointer$ rv32.o lds -o rv32
-# RUN: ld.lld --relax-gp --undefined=__global_pointer$ rv64.o lds -o rv64
-# RUN: llvm-objdump -td -M no-aliases --no-show-raw-insn rv32 | FileCheck %s
-# RUN: llvm-objdump -td -M no-aliases --no-show-raw-insn rv64 | FileCheck %s
- 
-# CHECK: 00001000 l       .data  {{0+}}08 Var0
-# CHECK: 00001f80 l       .data1 {{0+}}80 Var1
-# CHECK: 00001800 g       .sdata {{0+}}00 __global_pointer$
-
-# CHECK: <_start>:
-# CHECK-NEXT: lui     a1, 1
-# CHECK-NEXT: lw      a0, -2048(gp)
-# CHECK-NEXT: lw      a1, -2044(gp)
-# CHECK-NEXT: lui     a1, 2
-# CHECK-NEXT: lw      a0, 1920(gp)
-# CHECK-NEXT: lw      a1, 2044(gp)
-
-#--- a.s
-.global _start
-_start:
-        lui     a1, %hi(Var0+4)        # Cannot prove that %lo relocs will be reachable
-        lw      a0, %lo(Var0)(a1)      # Reachable from GP
-        lw      a1, %lo(Var0+4)(a1)    # Reachable from GP
-        lui     a1, %hi(Var1+124)      # Cannot prove that %lo relocs will be reachable
-        lw      a0, %lo(Var1)(a1)      # Reachable from GP
-        lw      a1, %lo(Var1+124)(a1)  # Reachable from GP
-
-.section .sdata,"aw"
-.section .data,"aw"
-  .p2align 3
-Var0:
-  .quad 0
-  .size   Var0, 8
-
-.section .data1,"aw"
-  .p2align 7
-Var1:
-  .quad 0
-  .zero 120
-  .size   Var1, 128
-
-#--- lds
-SECTIONS {
-  .text : { }
-  .sdata 0x1000 : { }
-  .data  0x1000 : { }
-  .data1 0x1f80 : { }
-}
diff --git a/lld/test/ELF/riscv-relax-gp-partial.s b/lld/test/ELF/riscv-relax-gp-partial.s
deleted file mode 100644
index fedc41f24e2d6a0..000000000000000
--- a/lld/test/ELF/riscv-relax-gp-partial.s
+++ /dev/null
@@ -1,58 +0,0 @@
-# REQUIRES: riscv
-# RUN: rm -rf %t && split-file %s %t && cd %t
-
-# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf -mattr=+relax a.s -o rv32.o
-# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=+relax a.s -o rv64.o
-
-# RUN: ld.lld --relax-gp --undefined=__global_pointer$ rv32.o lds -o rv32
-# RUN: ld.lld --relax-gp --undefined=__global_pointer$ rv64.o lds -o rv64
-# RUN: llvm-objdump -td -M no-aliases --no-show-raw-insn rv32 | FileCheck %s
-# RUN: llvm-objdump -td -M no-aliases --no-show-raw-insn rv64 | FileCheck %s
- 
-# CHECK: 00000080 l       .data  {{0+}}08 Var0
-# CHECK: 00001000 l       .data  {{0+}}80 Var1
-# CHECK: 00000815 g       .sdata {{0+}}00 __global_pointer$
-
-# CHECK: <_start>:
-# CHECK-NOT:  lui
-# CHECK-NEXT: lw      a0, -1941(gp)
-# CHECK-NEXT: lw      a1, -1937(gp)
-# CHECK-NEXT: lui     a1, 1
-# CHECK-NEXT: lw      a0, 2027(gp)
-# CHECK-NEXT: lw      a1, 124(a1)
-
-#--- a.s
-.global _start
-_start:
-        lui     a1, %hi(Var0)
-        lw      a0, %lo(Var0)(a1)
-        lw      a1, %lo(Var0+4)(a1)
-        lui     a1, %hi(Var1)
-        lw      a0, %lo(Var1)(a1)      # First part is reachable from gp
-        lw      a1, %lo(Var1+124)(a1)  # The second part is not reachable
-
-.section .rodata
-foo:
-  .space 1
-.section .sdata,"aw"
-  .space 1
-.section .data,"aw"
-  .p2align 3
-Var0:
-  .quad 0
-  .size   Var0, 8
-  .space 3960
-  .p2align 7
-Var1:
-  .quad 0
-  .zero 120
-  .size   Var1, 128
-
-#--- lds
-SECTIONS {
-  .text : { }
-  .rodata : { }
-  .sdata : { }
-  .sbss : { }
-  .data : { }
-}



More information about the llvm-commits mailing list