[lld] [lld][ELF] Sort thunks by their destination to allow quicker convergence (PR #209962)

Pranav Kant via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 16 13:58:36 PDT 2026


https://github.com/pranavk updated https://github.com/llvm/llvm-project/pull/209962

>From 99cd5d26fdc9ca82a95525b7c21ef2385bfcf88e Mon Sep 17 00:00:00 2001
From: Pranav Kant <prka at google.com>
Date: Wed, 15 Jul 2026 13:26:34 -0700
Subject: [PATCH 1/4] [lld][ELF] Sort thunks by their destination to allow
 quicker convergence

When thunks in a thunk section are not ordered, we end up upgrading short
thunks to long thunks in separate passes. Depending on the number of thunks,
address assignment may take too long to converge or not converge at all.

By sorting the thunks by their destination address, we make sure upgrading
one thunk to long doesn't have ripple effect of following thunks going long
in subsequent passes.
---
 lld/ELF/Relocations.cpp                  |   9 +-
 lld/ELF/SyntheticSections.cpp            |  16 +-
 lld/ELF/SyntheticSections.h              |   2 +-
 lld/ELF/Thunks.cpp                       |   5 +
 lld/ELF/Thunks.h                         |   2 +
 lld/test/ELF/aarch64-thunk-many-passes.s | 206 +++++++++++++++++++++++
 6 files changed, 236 insertions(+), 4 deletions(-)
 create mode 100644 lld/test/ELF/aarch64-thunk-many-passes.s

diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 4702d941d28ca..e29e6ba0dbc03 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -38,6 +38,7 @@
 #include "Thunks.h"
 #include "lld/Common/ErrorHandler.h"
 #include "lld/Common/Memory.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/BinaryFormat/ELF.h"
 #include "llvm/Demangle/Demangle.h"
@@ -1966,8 +1967,12 @@ bool ThunkCreator::createThunks(uint32_t pass,
               rel.addend = -getPCBias(ctx, *isec, rel);
           }
 
-        for (auto &p : isd->thunkSections)
-          addressesChanged |= p.first->assignOffsets();
+        for (auto &p : isd->thunkSections) {
+          // Ordering thunks by their destination allows for quicker
+          // convergence. Bulk of thunks are created in pass 0. So sorting them
+          // then has most impact and should be sufficient in most cases.
+          addressesChanged |= p.first->assignOffsets(pass == 0);
+        }
       });
 
   for (auto &p : thunkedSections)
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 06d5129844e5c..e0becb988f885 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -4084,7 +4084,21 @@ InputSection *ThunkSection::getTargetInputSection() const {
   return t->getTargetInputSection();
 }
 
-bool ThunkSection::assignOffsets() {
+bool ThunkSection::assignOffsets(bool sort) {
+  if (sort) {
+    // We ignore branches that are in different directions.
+    // For branches in same direction, we want to order them by their
+    // destination VA such that upgrading a short thunk to long doesn't make
+    // following thunks out of reach in subsequent passes. This helps with
+    // quicker convergence.
+    uint64_t sectionVA = getVA();
+    llvm::stable_sort(thunks, [sectionVA](const Thunk *a, const Thunk *b) {
+      bool aFwd = a->getDestVA() > sectionVA;
+      bool bFwd = b->getDestVA() > sectionVA;
+      return aFwd != bFwd ? bFwd : a->getDestVA() > b->getDestVA();
+    });
+  }
+
   uint64_t off = 0;
   bool changed = false;
   for (Thunk *t : thunks) {
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 523f6587899fe..b0ecc1c013afb 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -1225,7 +1225,7 @@ class ThunkSection final : public SyntheticSection {
   size_t getSize() const override;
   void writeTo(uint8_t *buf) override;
   InputSection *getTargetInputSection() const;
-  bool assignOffsets();
+  bool assignOffsets(bool sort = false);
 
   // When true, round up reported size of section to 4 KiB. See comment
   // in addThunkSection() for more details.
diff --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp
index 1f161685f178d..c8f01b0e004d0 100644
--- a/lld/ELF/Thunks.cpp
+++ b/lld/ELF/Thunks.cpp
@@ -629,6 +629,11 @@ void Thunk::setOffset(uint64_t newOffset) {
   offset = newOffset;
 }
 
+uint64_t Thunk::getDestVA() const {
+  return destination.isInPlt(ctx) ? destination.getPltVA(ctx)
+                                  : destination.getVA(ctx, addend);
+}
+
 // AArch64 Thunk base class.
 static uint64_t getAArch64ThunkDestVA(Ctx &ctx, const Symbol &s, int64_t a) {
   uint64_t v = s.isInPlt(ctx) ? s.getPltVA(ctx) : s.getVA(ctx, a);
diff --git a/lld/ELF/Thunks.h b/lld/ELF/Thunks.h
index 446345b8517f9..d9ac156e1c914 100644
--- a/lld/ELF/Thunks.h
+++ b/lld/ELF/Thunks.h
@@ -60,6 +60,8 @@ class Thunk {
   // enabled.
   virtual bool needsSyntheticLandingPad() { return false; }
 
+  virtual uint64_t getDestVA() const;
+
   Defined *getThunkTargetSym() const { return syms[0]; }
 
   Ctx &ctx;
diff --git a/lld/test/ELF/aarch64-thunk-many-passes.s b/lld/test/ELF/aarch64-thunk-many-passes.s
new file mode 100644
index 0000000000000..a17e2236150b2
--- /dev/null
+++ b/lld/test/ELF/aarch64-thunk-many-passes.s
@@ -0,0 +1,206 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t
+// RUN: ld.lld %t -o %t1 2>&1 | FileCheck %s
+
+// CHECK-NOT: error: address assignment did not converge
+
+.section .text.call1, "ax", %progbits
+.balign 8
+.global _start
+_start:
+  bl fn1
+  .space 16
+.section .text.call2, "ax", %progbits
+  bl fn2
+  .space 16
+.section .text.call3, "ax", %progbits
+  bl fn3
+  .space 16
+.section .text.call4, "ax", %progbits
+  bl fn4
+  .space 16
+.section .text.call5, "ax", %progbits
+  bl fn5
+  .space 16
+.section .text.call6, "ax", %progbits
+  bl fn6
+  .space 16
+.section .text.call7, "ax", %progbits
+  bl fn7
+  .space 16
+.section .text.call8, "ax", %progbits
+  bl fn8
+  .space 16
+.section .text.call9, "ax", %progbits
+  bl fn9
+  .space 16
+.section .text.call10, "ax", %progbits
+  bl fn10
+  .space 16
+.section .text.call11, "ax", %progbits
+  bl fn11
+  .space 16
+.section .text.call12, "ax", %progbits
+  bl fn12
+  .space 16
+.section .text.call13, "ax", %progbits
+  bl fn13
+  .space 16
+.section .text.call14, "ax", %progbits
+  bl fn14
+  .space 16
+.section .text.call15, "ax", %progbits
+  bl fn15
+  .space 16
+.section .text.call16, "ax", %progbits
+  bl fn16
+  .space 16
+.section .text.call17, "ax", %progbits
+  bl fn17
+  .space 16
+.section .text.call18, "ax", %progbits
+  bl fn18
+  .space 16
+.section .text.call19, "ax", %progbits
+  bl fn19
+  .space 16
+.section .text.call20, "ax", %progbits
+  bl fn20
+  .space 16
+.section .text.call21, "ax", %progbits
+  bl fn21
+  .space 16
+.section .text.call22, "ax", %progbits
+  bl fn22
+  .space 16
+.section .text.call23, "ax", %progbits
+  bl fn23
+  .space 16
+.section .text.call24, "ax", %progbits
+  bl fn24
+  .space 16
+.section .text.call25, "ax", %progbits
+  bl fn25
+  .space 16
+.section .text.call26, "ax", %progbits
+  bl fn26
+  .space 16
+.section .text.call27, "ax", %progbits
+  bl fn27
+  .space 16
+.section .text.call28, "ax", %progbits
+  bl fn28
+  .space 16
+.section .text.call29, "ax", %progbits
+  bl fn29
+  .space 16
+.section .text.call30, "ax", %progbits
+  bl fn30
+  .space 16
+.section .text.call31, "ax", %progbits
+  bl fn31
+  .space 16
+.section .text.call32, "ax", %progbits
+  bl fn32
+
+.section .text.space, "ax", %progbits
+.space 134217232
+
+.section .text.targets, "ax", %progbits
+.balign 4
+.global fn1, fn2, fn3, fn4, fn5, fn6, fn7, fn8, fn9, fn10, fn11, fn12, fn13, fn14, fn15, fn16, fn17, fn18, fn19, fn20, fn21, fn22, fn23, fn24, fn25, fn26, fn27, fn28, fn29, fn30, fn31, fn32
+fn1:
+  ret
+.space 12
+fn2:
+  ret
+.space 12
+fn3:
+  ret
+.space 12
+fn4:
+  ret
+.space 12
+fn5:
+  ret
+.space 12
+fn6:
+  ret
+.space 12
+fn7:
+  ret
+.space 12
+fn8:
+  ret
+.space 12
+fn9:
+  ret
+.space 12
+fn10:
+  ret
+.space 12
+fn11:
+  ret
+.space 12
+fn12:
+  ret
+.space 12
+fn13:
+  ret
+.space 12
+fn14:
+  ret
+.space 12
+fn15:
+  ret
+.space 12
+fn16:
+  ret
+.space 12
+fn17:
+  ret
+.space 12
+fn18:
+  ret
+.space 12
+fn19:
+  ret
+.space 12
+fn20:
+  ret
+.space 12
+fn21:
+  ret
+.space 12
+fn22:
+  ret
+.space 12
+fn23:
+  ret
+.space 12
+fn24:
+  ret
+.space 12
+fn25:
+  ret
+.space 12
+fn26:
+  ret
+.space 12
+fn27:
+  ret
+.space 12
+fn28:
+  ret
+.space 12
+fn29:
+  ret
+.space 12
+fn30:
+  ret
+.space 12
+fn31:
+  ret
+.space 12
+fn32:
+  ret

>From a3eb6b6b4fb8cb6736e7204f56ac7957e8c11ac3 Mon Sep 17 00:00:00 2001
From: Pranav Kant <prka at google.com>
Date: Thu, 16 Jul 2026 09:53:06 -0700
Subject: [PATCH 2/4] Test simpliciation + address reviewer comments

---
 lld/ELF/SyntheticSections.cpp            |  34 +++-
 lld/ELF/Thunks.h                         |   2 +-
 lld/test/ELF/aarch64-thunk-many-passes.s | 228 ++++-------------------
 3 files changed, 64 insertions(+), 200 deletions(-)

diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index e0becb988f885..17048dd62f5a8 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -4086,11 +4086,35 @@ InputSection *ThunkSection::getTargetInputSection() const {
 
 bool ThunkSection::assignOffsets(bool sort) {
   if (sort) {
-    // We ignore branches that are in different directions.
-    // For branches in same direction, we want to order them by their
-    // destination VA such that upgrading a short thunk to long doesn't make
-    // following thunks out of reach in subsequent passes. This helps with
-    // quicker convergence.
+    // For thunk section before sorting:
+    //    destA
+    //    destB
+    //    ...
+    //    backwards A
+    //    backwards B
+    //    forward C
+    //    forward D
+    //    ...
+    //    destC
+    //    destD
+    // 
+    // Sorting will rearrange thunks as follows:
+    // 
+    //    destA
+    //    destB
+    //    ...
+    //    backwards B 
+    //    backwards A
+    //    ...
+    //    forwards D
+    //    forwards C
+    //    ...
+    //    destC
+    //    destD
+    // 
+    // Since we iterate on thunks from first to last in a thunk section while doing upgradation,
+    // any thunk that is found to be out of range is guarranted to not invalidate thunks
+    // that we have already iterated on. This allows quicker convergence.
     uint64_t sectionVA = getVA();
     llvm::stable_sort(thunks, [sectionVA](const Thunk *a, const Thunk *b) {
       bool aFwd = a->getDestVA() > sectionVA;
diff --git a/lld/ELF/Thunks.h b/lld/ELF/Thunks.h
index d9ac156e1c914..e99e21783b317 100644
--- a/lld/ELF/Thunks.h
+++ b/lld/ELF/Thunks.h
@@ -60,7 +60,7 @@ class Thunk {
   // enabled.
   virtual bool needsSyntheticLandingPad() { return false; }
 
-  virtual uint64_t getDestVA() const;
+  uint64_t getDestVA() const;
 
   Defined *getThunkTargetSym() const { return syms[0]; }
 
diff --git a/lld/test/ELF/aarch64-thunk-many-passes.s b/lld/test/ELF/aarch64-thunk-many-passes.s
index a17e2236150b2..dbfb2c49e9134 100644
--- a/lld/test/ELF/aarch64-thunk-many-passes.s
+++ b/lld/test/ELF/aarch64-thunk-many-passes.s
@@ -1,206 +1,46 @@
 // REQUIRES: aarch64
 // RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t
 // RUN: ld.lld %t -o %t1 2>&1 | FileCheck %s
+// RUN: rm %t %t1
 
 // CHECK-NOT: error: address assignment did not converge
 
-.section .text.call1, "ax", %progbits
-.balign 8
+// This test assumes pass limit of 30. Initially, only last thunk is out of range
+// but as out of range thunks get promoted to long thunks, they force previous
+// thunks to go out of range in the next pass. Without sorting the thunks,
+// linker wouldn't converge. We only test absolute thunks which are the default
+// thunks in the absence of --pic-thunks.
+
+.macro gen_call i
+  bl fn\i
+  .space 12
+.endm
+
+.macro gen_target i
+.global fn\i
+fn\i:
+  ret
+  .space 12
+.endm
+
+.section .text, "ax", %progbits
 .global _start
 _start:
-  bl fn1
-  .space 16
-.section .text.call2, "ax", %progbits
-  bl fn2
-  .space 16
-.section .text.call3, "ax", %progbits
-  bl fn3
-  .space 16
-.section .text.call4, "ax", %progbits
-  bl fn4
-  .space 16
-.section .text.call5, "ax", %progbits
-  bl fn5
-  .space 16
-.section .text.call6, "ax", %progbits
-  bl fn6
-  .space 16
-.section .text.call7, "ax", %progbits
-  bl fn7
-  .space 16
-.section .text.call8, "ax", %progbits
-  bl fn8
-  .space 16
-.section .text.call9, "ax", %progbits
-  bl fn9
-  .space 16
-.section .text.call10, "ax", %progbits
-  bl fn10
-  .space 16
-.section .text.call11, "ax", %progbits
-  bl fn11
-  .space 16
-.section .text.call12, "ax", %progbits
-  bl fn12
-  .space 16
-.section .text.call13, "ax", %progbits
-  bl fn13
-  .space 16
-.section .text.call14, "ax", %progbits
-  bl fn14
-  .space 16
-.section .text.call15, "ax", %progbits
-  bl fn15
-  .space 16
-.section .text.call16, "ax", %progbits
-  bl fn16
-  .space 16
-.section .text.call17, "ax", %progbits
-  bl fn17
-  .space 16
-.section .text.call18, "ax", %progbits
-  bl fn18
-  .space 16
-.section .text.call19, "ax", %progbits
-  bl fn19
-  .space 16
-.section .text.call20, "ax", %progbits
-  bl fn20
-  .space 16
-.section .text.call21, "ax", %progbits
-  bl fn21
-  .space 16
-.section .text.call22, "ax", %progbits
-  bl fn22
-  .space 16
-.section .text.call23, "ax", %progbits
-  bl fn23
-  .space 16
-.section .text.call24, "ax", %progbits
-  bl fn24
-  .space 16
-.section .text.call25, "ax", %progbits
-  bl fn25
-  .space 16
-.section .text.call26, "ax", %progbits
-  bl fn26
-  .space 16
-.section .text.call27, "ax", %progbits
-  bl fn27
-  .space 16
-.section .text.call28, "ax", %progbits
-  bl fn28
-  .space 16
-.section .text.call29, "ax", %progbits
-  bl fn29
-  .space 16
-.section .text.call30, "ax", %progbits
-  bl fn30
-  .space 16
-.section .text.call31, "ax", %progbits
-  bl fn31
-  .space 16
-.section .text.call32, "ax", %progbits
-  bl fn32
+
+.irp i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30
+  gen_call \i
+.endr
+
+// <Linker will create thunk section here>
 
 .section .text.space, "ax", %progbits
-.space 134217232
+// Position fn30 just past the 128 MiB (0x8000000) limit from created short thunk
+// while all other functions are within 128MiB from their respective short thunks
+// Absolute thunks are 16 bytes long.
+.space 0x8000000 - 29 * 16
 
 .section .text.targets, "ax", %progbits
-.balign 4
-.global fn1, fn2, fn3, fn4, fn5, fn6, fn7, fn8, fn9, fn10, fn11, fn12, fn13, fn14, fn15, fn16, fn17, fn18, fn19, fn20, fn21, fn22, fn23, fn24, fn25, fn26, fn27, fn28, fn29, fn30, fn31, fn32
-fn1:
-  ret
-.space 12
-fn2:
-  ret
-.space 12
-fn3:
-  ret
-.space 12
-fn4:
-  ret
-.space 12
-fn5:
-  ret
-.space 12
-fn6:
-  ret
-.space 12
-fn7:
-  ret
-.space 12
-fn8:
-  ret
-.space 12
-fn9:
-  ret
-.space 12
-fn10:
-  ret
-.space 12
-fn11:
-  ret
-.space 12
-fn12:
-  ret
-.space 12
-fn13:
-  ret
-.space 12
-fn14:
-  ret
-.space 12
-fn15:
-  ret
-.space 12
-fn16:
-  ret
-.space 12
-fn17:
-  ret
-.space 12
-fn18:
-  ret
-.space 12
-fn19:
-  ret
-.space 12
-fn20:
-  ret
-.space 12
-fn21:
-  ret
-.space 12
-fn22:
-  ret
-.space 12
-fn23:
-  ret
-.space 12
-fn24:
-  ret
-.space 12
-fn25:
-  ret
-.space 12
-fn26:
-  ret
-.space 12
-fn27:
-  ret
-.space 12
-fn28:
-  ret
-.space 12
-fn29:
-  ret
-.space 12
-fn30:
-  ret
-.space 12
-fn31:
-  ret
-.space 12
-fn32:
-  ret
+
+.irp i, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30
+  gen_target \i
+.endr

>From 051e317e1c2ae53b0aa584912aa7c447cec7bf77 Mon Sep 17 00:00:00 2001
From: Pranav Kant <prka at google.com>
Date: Thu, 16 Jul 2026 13:40:16 -0700
Subject: [PATCH 3/4] Adapt existing tests

---
 lld/test/ELF/aarch64-thunk-align.s            |  29 ++-
 lld/test/ELF/aarch64-thunk-bti-execute-only.s |  14 +-
 lld/test/ELF/aarch64-thunk-bti-multipass.s    |  16 +-
 lld/test/ELF/aarch64-thunk-bti.s              | 235 +++++++++---------
 lld/test/ELF/aarch64-thunk-script.s           |  10 +-
 5 files changed, 151 insertions(+), 153 deletions(-)

diff --git a/lld/test/ELF/aarch64-thunk-align.s b/lld/test/ELF/aarch64-thunk-align.s
index 584c02fb8f7fc..0bc941cb293e0 100644
--- a/lld/test/ELF/aarch64-thunk-align.s
+++ b/lld/test/ELF/aarch64-thunk-align.s
@@ -18,25 +18,24 @@ _start:
  nop
 
 // CHECK-LABEL: <_start>:
-// CHECK-NEXT: 12000: b       0x12018 <__AArch64AbsLongThunk_short>
-// CHECK-NEXT:        b       0x1201c <__AArch64AbsLongThunk_short2>
-// CHECK-NEXT:        b       0x12020 <__AArch64AbsLongThunk_short3>
-// CHECK-NEXT:        b       0x12028 <__AArch64AbsLongThunk_long>
+// CHECK-NEXT: 12000: b       0x12030 <__AArch64AbsLongThunk_short>
+// CHECK-NEXT:        b       0x1202c <__AArch64AbsLongThunk_short2>
+// CHECK-NEXT:        b       0x12028 <__AArch64AbsLongThunk_short3>
+// CHECK-NEXT:        b       0x12018 <__AArch64AbsLongThunk_long>
 // CHECK-NEXT:        nop
 // CHECK-NEXT:        udf     #0x0
 // CHECK-EMPTY:
-// CHECK-LABEL: <__AArch64AbsLongThunk_short>:
-// CHECK-NEXT: 12018: b       0x8012004 <__AArch64AbsLongThunk_long+0x7ffffdc>
-// CHECK-EMPY:
-// CHECK-LABEL: <__AArch64AbsLongThunk_short2>:
-// CHECK-NEXT: 1201c: b       0x8012008 <__AArch64AbsLongThunk_long+0x7ffffe0>
-// CHECK-EMPTY:
-// CHECK-LABEL: <__AArch64AbsLongThunk_short3>:
-// CHECK-NEXT: 12020: b       0x801200c <__AArch64AbsLongThunk_long+0x7ffffe4>
-// CHECK-NEXT:        udf     #0x0
-// CHECK-EMPTY:
 // CHECK-LABEL: <__AArch64AbsLongThunk_long>:
-// CHECK-NEXT: 12028: ldr     x16, 0x12030 <__AArch64AbsLongThunk_long+0x8>
+// CHECK-NEXT: 12018: ldr     x16, 0x12020 <__AArch64AbsLongThunk_long+0x8>
 // CHECK-NEXT:        br      x16
 // CHECK-NEXT: 00 00 00 10   .word   0x10000000
 // CHECK-NEXT: 00 00 00 00   .word   0x00000000
+// CHECK-EMPTY:
+// CHECK-LABEL: <__AArch64AbsLongThunk_short3>:
+// CHECK-NEXT: 12028: b       0x801200c <__AArch64AbsLongThunk_short+0x7ffffdc>
+// CHECK-EMPTY:
+// CHECK-LABEL: <__AArch64AbsLongThunk_short2>:
+// CHECK-NEXT: 1202c: b       0x8012008 <__AArch64AbsLongThunk_short+0x7ffffd8>
+// CHECK-EMPTY:
+// CHECK-LABEL: <__AArch64AbsLongThunk_short>:
+// CHECK-NEXT: 12030: b       0x8012004 <__AArch64AbsLongThunk_short+0x7ffffd4>
diff --git a/lld/test/ELF/aarch64-thunk-bti-execute-only.s b/lld/test/ELF/aarch64-thunk-bti-execute-only.s
index 4c5bb2ae84365..0e69d29017ee7 100644
--- a/lld/test/ELF/aarch64-thunk-bti-execute-only.s
+++ b/lld/test/ELF/aarch64-thunk-bti-execute-only.s
@@ -38,20 +38,20 @@ fn1:
   ret
 
 // CHECK-LABEL: <_start>:
-// CHECK-NEXT:  18001000: bl      0x1800100c <__AArch64AbsXOLongThunk_>
-// CHECK-NEXT:            b       0x1800100c <__AArch64AbsXOLongThunk_>
-// CHECK-NEXT:            bl      0x18001020 <__AArch64AbsXOLongThunk_absolute>
+// CHECK-NEXT:  18001000: bl      0x18001020 <__AArch64AbsXOLongThunk_>
+// CHECK-NEXT:            b       0x18001020 <__AArch64AbsXOLongThunk_>
+// CHECK-NEXT:            bl      0x1800100c <__AArch64AbsXOLongThunk_absolute>
 
-// CHECK-LABEL: <__AArch64AbsXOLongThunk_>:
+// CHECK-LABEL: <__AArch64AbsXOLongThunk_absolute>:
 // CHECK-NEXT:  1800100c: mov     x16, #0x0
-// CHECK-NEXT:            movk    x16, #0x3000, lsl #16
+// CHECK-NEXT:            movk    x16, #0xf000, lsl #16
 // CHECK-NEXT:            movk    x16, #0x0, lsl #32
 // CHECK-NEXT:            movk    x16, #0x0, lsl #48
 // CHECK-NEXT:            br      x16
 
-// CHECK-LABEL: <__AArch64AbsXOLongThunk_absolute>:
+// CHECK-LABEL: <__AArch64AbsXOLongThunk_>:
 // CHECK-NEXT:  18001020: mov     x16, #0x0
-// CHECK-NEXT:            movk    x16, #0xf000, lsl #16
+// CHECK-NEXT:            movk    x16, #0x3000, lsl #16
 // CHECK-NEXT:            movk    x16, #0x0, lsl #32
 // CHECK-NEXT:            movk    x16, #0x0, lsl #48
 // CHECK-NEXT:            br      x16
diff --git a/lld/test/ELF/aarch64-thunk-bti-multipass.s b/lld/test/ELF/aarch64-thunk-bti-multipass.s
index f470d832843b8..f2fe9ca0c68a3 100644
--- a/lld/test/ELF/aarch64-thunk-bti-multipass.s
+++ b/lld/test/ELF/aarch64-thunk-bti-multipass.s
@@ -39,19 +39,19 @@ _start:
 /// and will need a long branch thunk, which in turn needs a BTI landing pad.
 
 // CHECK-LABEL: <_start>:
-// CHECK-NEXT: 10001000: bl  0x10002008 <__AArch64AbsLongThunk_fn1>
-// CHECK-NEXT:           bl  0x10002018 <__AArch64AbsLongThunk_fn2>
+// CHECK-NEXT: 10001000: bl  0x10002018 <__AArch64AbsLongThunk_fn1>
+// CHECK-NEXT:           bl  0x10002008 <__AArch64AbsLongThunk_fn2>
 
-// CHECK-LABEL: <__AArch64AbsLongThunk_fn1>:
-// CHECK-NEXT: 10002008: ldr     x16, 0x10002010 <__AArch64AbsLongThunk_fn1+0x8>
+// CHECK-LABEL: <__AArch64AbsLongThunk_fn2>:
+// CHECK-NEXT: 10002008: ldr     x16, 0x10002010 <__AArch64AbsLongThunk_fn2+0x8>
 // CHECK-NEXT:           br      x16
-// CHECK-NEXT:           00 30 00 18    .word   0x18003000
+// CHECK-NEXT:           04 40 00 18    .word   0x18004004
 // CHECK-NEXT:           00 00 00 00    .word   0x00000000
 
-// CHECK-LABEL: <__AArch64AbsLongThunk_fn2>:
-// CHECK-NEXT: 10002018: ldr     x16, 0x10002020 <__AArch64AbsLongThunk_fn2+0x8>
+// CHECK-LABEL: <__AArch64AbsLongThunk_fn1>:
+// CHECK-NEXT: 10002018: ldr     x16, 0x10002020 <__AArch64AbsLongThunk_fn1+0x8>
 // CHECK-NEXT:           br      x16
-// CHECK-NEXT:           04 40 00 18    .word   0x18004004
+// CHECK-NEXT:           00 30 00 18    .word   0x18003000
 // CHECK-NEXT:           00 00 00 00    .word   0x00000000
 
 .section .text.1, "ax", %progbits
diff --git a/lld/test/ELF/aarch64-thunk-bti.s b/lld/test/ELF/aarch64-thunk-bti.s
index 5689a0bb6a55b..57b2403e383e7 100644
--- a/lld/test/ELF/aarch64-thunk-bti.s
+++ b/lld/test/ELF/aarch64-thunk-bti.s
@@ -58,90 +58,90 @@ _start:
  .space 0x1000
 
 // CHECK-PADS-LABEL: <_start>:
-// CHECK-PADS-NEXT: 10001000: bl      0x10002040
-// CHECK-PADS-NEXT:           bl      0x10002044
-// CHECK-PADS-NEXT:           bl      0x10002048
-// CHECK-PADS-NEXT:           bl      0x1000204c
-// CHECK-PADS-NEXT:           bl      0x10002050
-// CHECK-PADS-NEXT:           bl      0x10002054
-// CHECK-PADS-NEXT:           b       0x10002054
-// CHECK-PADS-NEXT:           bl      0x10002058
-// CHECK-PADS-NEXT:           b       0x10002058
-// CHECK-PADS-NEXT:           bl      0x1000205c
-// CHECK-PADS-NEXT:           b       0x1000205c
-// CHECK-PADS-NEXT:           bl      0x10002060
-// CHECK-PADS-NEXT:           b       0x10002060
-// CHECK-PADS-NEXT:           bl      0x10002064
-// CHECK-PADS-NEXT:           bl      0x10002068
+// CHECK-PADS-NEXT: 10001000: bl      0x100020{{[0-9a-f]+}}
+// CHECK-PADS-NEXT:           bl      0x100020{{[0-9a-f]+}}
+// CHECK-PADS-NEXT:           bl      0x100020{{[0-9a-f]+}}
+// CHECK-PADS-NEXT:           bl      0x100020{{[0-9a-f]+}}
+// CHECK-PADS-NEXT:           bl      0x100020{{[0-9a-f]+}}
+// CHECK-PADS-NEXT:           bl      0x100020{{[0-9a-f]+}}
+// CHECK-PADS-NEXT:           b       0x100020{{[0-9a-f]+}}
+// CHECK-PADS-NEXT:           bl      0x100020{{[0-9a-f]+}}
+// CHECK-PADS-NEXT:           b       0x100020{{[0-9a-f]+}}
+// CHECK-PADS-NEXT:           bl      0x100020{{[0-9a-f]+}}
+// CHECK-PADS-NEXT:           b       0x100020{{[0-9a-f]+}}
+// CHECK-PADS-NEXT:           bl      0x100020{{[0-9a-f]+}}
+// CHECK-PADS-NEXT:           b       0x100020{{[0-9a-f]+}}
+// CHECK-PADS-NEXT:           bl      0x100020{{[0-9a-f]+}}
+// CHECK-PADS-NEXT:           bl      0x10002040
+
+// CHECK-LABEL: <__AArch64ADRPThunk_absolute>:
+// CHECK-NEXT: 10002040: b       0x18001098 <absolute at plt>
+
+// CHECK-LABEL: <__AArch64ADRPThunk_via_plt>:
+// CHECK-NEXT: 10002044: b       0x18001080 <via_plt at plt>
 
 // CHECK-LABEL: <__AArch64ADRPThunk_>:
-// CHECK-NEXT: 10002040: b       0x18001000 <bti_c_target>
+// CHECK-NEXT: 10002048: b       0x18001050 <fn4>
 
 // CHECK-LABEL: <__AArch64ADRPThunk_>:
-// CHECK-NEXT: 10002044: b       0x18001008 <bti_j_target>
+// CHECK-NEXT: 1000204c: b       0x18001040 <fn3>
 
 // CHECK-LABEL: <__AArch64ADRPThunk_>:
-// CHECK-NEXT: 10002048: b       0x18001010 <bti_jc_target>
+// CHECK-NEXT: 10002050: b       0x18001038 <fn2>
 
 // CHECK-LABEL: <__AArch64ADRPThunk_>:
-// CHECK-NEXT: 1000204c: b       0x18001018 <paciasp_target>
+// CHECK-NEXT: 10002054: b       0x18001034 <fn1>
 
 // CHECK-LABEL: <__AArch64ADRPThunk_>:
-// CHECK-NEXT: 10002050: b       0x18001020 <pacibsp_target>
+// CHECK-NEXT: 10002058: b       0x18001020 <pacibsp_target>
 
 // CHECK-LABEL: <__AArch64ADRPThunk_>:
-// CHECK-NEXT: 10002054: b       0x18001038 <fn2>
+// CHECK-NEXT: 1000205c: b       0x18001018 <paciasp_target>
 
 // CHECK-LABEL: <__AArch64ADRPThunk_>:
-// CHECK-NEXT: 10002058:       b       0x18001034 <fn1>
+// CHECK-NEXT: 10002060: b       0x18001010 <bti_jc_target>
 
 // CHECK-LABEL: <__AArch64ADRPThunk_>:
-// CHECK-NEXT: 1000205c:       b       0x18001040 <fn3>
+// CHECK-NEXT: 10002064: b       0x18001008 <bti_j_target>
 
 // CHECK-LABEL: <__AArch64ADRPThunk_>:
-// CHECK-NEXT: 10002060:       b       0x18001050 <fn4>
+// CHECK-NEXT: 10002068: b       0x18001000 <bti_c_target>
 
-// CHECK-LABEL: <__AArch64ADRPThunk_via_plt>:
-// CHECK-NEXT: 10002064:       b       0x18001080 <via_plt at plt>
+// CHECK-EXE-LABEL: <__AArch64AbsLongThunk_absolute>:
+// CHECK-EXE-NEXT: 10002040:   ldr     x16, 0x10002048 <__AArch64AbsLongThunk_absolute+0x8>
+// CHECK-EXE-NEXT:             br      x16
+// CHECK-EXE-NEXT: 00 00 00 f0 .word   0xf0000000
+// CHECK-EXE-NEXT: 00 00 00 00 .word   0x00000000
 
-// CHECK-LABEL: <__AArch64ADRPThunk_absolute>:
-// CHECK-NEXT: 10002068:       b       0x18001098 <absolute at plt>
+// CHECK-EXE-LABEL: <__AArch64AbsLongThunk_via_plt>:
+// CHECK-EXE-NEXT: 10002050: b       0x18001080 <via_plt at plt>
 
 // CHECK-EXE-LABEL: <__AArch64AbsLongThunk_>:
-// CHECK-EXE-NEXT: 10002040: b       0x18001000 <bti_c_target>
+// CHECK-EXE-NEXT: 10002054: b       0x18001050 <fn4>
 
 // CHECK-EXE-LABEL: <__AArch64AbsLongThunk_>:
-// CHECK-EXE-NEXT: 10002044: b       0x18001008 <bti_j_target>
+// CHECK-EXE-NEXT: 10002058: b       0x18001040 <fn3>
 
 // CHECK-EXE-LABEL: <__AArch64AbsLongThunk_>:
-// CHECK-EXE-NEXT: 10002048: b       0x18001010 <bti_jc_target>
+// CHECK-EXE-NEXT: 1000205c: b       0x18001038 <fn2>
 
 // CHECK-EXE-LABEL: <__AArch64AbsLongThunk_>:
-// CHECK-EXE-NEXT: 1000204c: b       0x18001018 <paciasp_target>
+// CHECK-EXE-NEXT: 10002060: b       0x18001034 <fn1>
 
 // CHECK-EXE-LABEL: <__AArch64AbsLongThunk_>:
-// CHECK-EXE-NEXT: 10002050: b       0x18001020 <pacibsp_target>
+// CHECK-EXE-NEXT: 10002064: b       0x18001020 <pacibsp_target>
 
 // CHECK-EXE-LABEL: <__AArch64AbsLongThunk_>:
-// CHECK-EXE-NEXT: 10002054: b       0x18001038 <fn2>
+// CHECK-EXE-NEXT: 10002068: b       0x18001018 <paciasp_target>
 
 // CHECK-EXE-LABEL: <__AArch64AbsLongThunk_>:
-// CHECK-EXE-NEXT: 10002058: b       0x18001034 <fn1>
+// CHECK-EXE-NEXT: 1000206c: b       0x18001010 <bti_jc_target>
 
 // CHECK-EXE-LABEL: <__AArch64AbsLongThunk_>:
-// CHECK-EXE-NEXT: 1000205c: b       0x18001040 <fn3>
+// CHECK-EXE-NEXT: 10002070: b       0x18001008 <bti_j_target>
 
 // CHECK-EXE-LABEL: <__AArch64AbsLongThunk_>:
-// CHECK-EXE-NEXT: 10002060: b       0x18001050 <fn4>
-
-// CHECK-EXE-LABEL: <__AArch64AbsLongThunk_via_plt>:
-// CHECK-EXE-NEXT: 10002064: b       0x18001080 <via_plt at plt>
-
-// CHECK-EXE-LABEL: <__AArch64AbsLongThunk_absolute>:
-// CHECK-EXE-NEXT: 10002068:   ldr     x16, 0x10002070 <__AArch64AbsLongThunk_absolute+0x8>
-// CHECK-EXE-NEXT:             br      x16
-// CHECK-EXE-NEXT: 00 00 00 f0 .word   0xf0000000
-// CHECK-EXE-NEXT: 00 00 00 00 .word   0x00000000
+// CHECK-EXE-NEXT: 10002074: b       0x18001000 <bti_c_target>
 
 .section .text.1, "ax", %progbits
 /// These indirect branch targets already have a BTI compatible landing pad,
@@ -305,153 +305,152 @@ long_calls:
 // CHECK-EXE-NEXT:           nop
 
 // CHECK-LABEL: <long_calls>:
-// CHECK-NEXT: 30000000: bl      0x30000040 <__AArch64ADRPThunk_>
-// CHECK-NEXT:           bl      0x3000004c <__AArch64ADRPThunk_>
-// CHECK-NEXT:           bl      0x30000058 <__AArch64ADRPThunk_>
-// CHECK-NEXT:           bl      0x30000064 <__AArch64ADRPThunk_>
+// CHECK-NEXT: 30000000: bl      0x300000b8 <__AArch64ADRPThunk_>
+// CHECK-NEXT:           bl      0x300000ac <__AArch64ADRPThunk_>
+// CHECK-NEXT:           bl      0x300000a0 <__AArch64ADRPThunk_>
+// CHECK-NEXT:           bl      0x30000094 <__AArch64ADRPThunk_>
+// CHECK-NEXT:           bl      0x30000088 <__AArch64ADRPThunk_>
 // CHECK-NEXT:           bl      0x30000070 <__AArch64ADRPThunk_>
+// CHECK-NEXT:           b       0x30000070 <__AArch64ADRPThunk_>
 // CHECK-NEXT:           bl      0x3000007c <__AArch64ADRPThunk_>
 // CHECK-NEXT:           b       0x3000007c <__AArch64ADRPThunk_>
-// CHECK-NEXT:           bl      0x30000088 <__AArch64ADRPThunk_>
-// CHECK-NEXT:           b       0x30000088 <__AArch64ADRPThunk_>
-// CHECK-NEXT:           bl      0x30000094 <__AArch64ADRPThunk_>
-// CHECK-NEXT:           b       0x30000094 <__AArch64ADRPThunk_>
-// CHECK-NEXT:           bl      0x300000a0 <__AArch64ADRPThunk_>
-// CHECK-NEXT:           b       0x300000a0 <__AArch64ADRPThunk_>
-// CHECK-NEXT:           bl      0x300000ac <__AArch64ADRPThunk_via_plt>
-// CHECK-NEXT:           bl      0x300000b8 <__AArch64ADRPThunk_absolute>
+// CHECK-NEXT:           bl      0x30000064 <__AArch64ADRPThunk_>
+// CHECK-NEXT:           b       0x30000064 <__AArch64ADRPThunk_>
+// CHECK-NEXT:           bl      0x30000058 <__AArch64ADRPThunk_>
+// CHECK-NEXT:           b       0x30000058 <__AArch64ADRPThunk_>
+// CHECK-NEXT:           bl      0x3000004c <__AArch64ADRPThunk_via_plt>
+// CHECK-NEXT:           bl      0x30000040 <__AArch64ADRPThunk_absolute>
 
-/// bti_c_target.
-// CHECK-LABEL: <__AArch64ADRPThunk_>:
+// CHECK-LABEL: <__AArch64ADRPThunk_absolute>:
 // CHECK-NEXT: 30000040: adrp    x16, 0x18001000 <bti_c_target>
-// CHECK-NEXT:           add     x16, x16, #0x0
-// CHECK-NEXT:           br      x16
-/// bti_j_target.
-// CHECK-LABEL: <__AArch64ADRPThunk_>:
-// CHECK-NEXT:           adrp    x16, 0x18001000 <bti_c_target>
-// CHECK-NEXT:           add     x16, x16, #0x8
+// CHECK-NEXT:           add     x16, x16, #0x98
 // CHECK-NEXT:           br      x16
-/// bti_jc_target.
-// CHECK-LABEL: <__AArch64ADRPThunk_>:
-// CHECK-NEXT:           adrp    x16, 0x18001000 <bti_c_target>
-// CHECK-NEXT:           add     x16, x16, #0x10
+
+// CHECK-LABEL: <__AArch64ADRPThunk_via_plt>:
+// CHECK-NEXT: 3000004c: adrp    x16, 0x18001000 <bti_c_target>
+// CHECK-NEXT:           add     x16, x16, #0x80
 // CHECK-NEXT:           br      x16
-/// paciasp_target.
+
 // CHECK-LABEL: <__AArch64ADRPThunk_>:
-// CHECK-NEXT:           adrp    x16, 0x18001000 <bti_c_target>
-// CHECK-NEXT:           add     x16, x16, #0x18
+// CHECK-NEXT: 30000058: adrp    x16, 0x18001000 <bti_c_target>
+// CHECK-NEXT:           add     x16, x16, #0x44
 // CHECK-NEXT:           br      x16
-/// pacibsp_target.
+
 // CHECK-LABEL: <__AArch64ADRPThunk_>:
-// CHECK-NEXT:           adrp    x16, 0x18001000 <bti_c_target>
-// CHECK-NEXT:           add     x16, x16, #0x20
+// CHECK-NEXT: 30000064: adrp    x16, 0x18001000 <bti_c_target>
+// CHECK-NEXT:           add     x16, x16, #0x3c
 // CHECK-NEXT:           br      x16
-/// Landing pad for fn2.
+
 // CHECK-LABEL: <__AArch64ADRPThunk_>:
-// CHECK-NEXT:           adrp    x16, 0x18001000 <bti_c_target>
+// CHECK-NEXT: 30000070: adrp    x16, 0x18001000 <bti_c_target>
 // CHECK-NEXT:           add     x16, x16, #0x28
 // CHECK-NEXT:           br      x16
-/// Landing pad for fn1.
+
 // CHECK-LABEL: <__AArch64ADRPThunk_>:
-// CHECK-NEXT:           adrp    x16, 0x18001000 <bti_c_target>
+// CHECK-NEXT: 3000007c: adrp    x16, 0x18001000 <bti_c_target>
 // CHECK-NEXT:           add     x16, x16, #0x30
 // CHECK-NEXT:           br      x16
-/// Landing pad for fn3.
+
 // CHECK-LABEL: <__AArch64ADRPThunk_>:
-// CHECK-NEXT:           adrp    x16, 0x18001000 <bti_c_target>
-// CHECK-NEXT:           add     x16, x16, #0x3c
+// CHECK-NEXT: 30000088: adrp    x16, 0x18001000 <bti_c_target>
+// CHECK-NEXT:           add     x16, x16, #0x20
 // CHECK-NEXT:           br      x16
-/// Landing pad for fn4.
+
 // CHECK-LABEL: <__AArch64ADRPThunk_>:
-// CHECK-NEXT:           adrp    x16, 0x18001000 <bti_c_target>
-// CHECK-NEXT:           add     x16, x16, #0x44
+// CHECK-NEXT: 30000094: adrp    x16, 0x18001000 <bti_c_target>
+// CHECK-NEXT:           add     x16, x16, #0x18
 // CHECK-NEXT:           br      x16
 
-// CHECK-LABEL: <__AArch64ADRPThunk_via_plt>:
-// CHECK-NEXT:           adrp    x16, 0x18001000 <bti_c_target>
-// CHECK-NEXT:           add     x16, x16, #0x80
+// CHECK-LABEL: <__AArch64ADRPThunk_>:
+// CHECK-NEXT: 300000a0: adrp    x16, 0x18001000 <bti_c_target>
+// CHECK-NEXT:           add     x16, x16, #0x10
 // CHECK-NEXT:           br      x16
 
-// CHECK-LABEL: <__AArch64ADRPThunk_absolute>:
-// CHECK-NEXT:           adrp    x16, 0x18001000 <bti_c_target>
-// CHECK-NEXT:           add     x16, x16, #0x98
+// CHECK-LABEL: <__AArch64ADRPThunk_>:
+// CHECK-NEXT: 300000ac: adrp    x16, 0x18001000 <bti_c_target>
+// CHECK-NEXT:           add     x16, x16, #0x8
+// CHECK-NEXT:           br      x16
+
+// CHECK-LABEL: <__AArch64ADRPThunk_>:
+// CHECK-NEXT: 300000b8: adrp    x16, 0x18001000 <bti_c_target>
+// CHECK-NEXT:           add     x16, x16, #0x0
 // CHECK-NEXT:           br      x16
 
 // CHECK-EXE-LABEL: <long_calls>:
-// CHECK-EXE-NEXT: 30000000: bl      0x30000040 <__AArch64AbsLongThunk_>
-// CHECK-EXE-NEXT:           bl      0x30000050 <__AArch64AbsLongThunk_>
-// CHECK-EXE-NEXT:           bl      0x30000060 <__AArch64AbsLongThunk_>
+// CHECK-EXE-NEXT: 30000000: bl      0x300000d0 <__AArch64AbsLongThunk_>
+// CHECK-EXE-NEXT:           bl      0x300000c0 <__AArch64AbsLongThunk_>
+// CHECK-EXE-NEXT:           bl      0x300000b0 <__AArch64AbsLongThunk_>
+// CHECK-EXE-NEXT:           bl      0x300000a0 <__AArch64AbsLongThunk_>
+// CHECK-EXE-NEXT:           bl      0x30000090 <__AArch64AbsLongThunk_>
 // CHECK-EXE-NEXT:           bl      0x30000070 <__AArch64AbsLongThunk_>
+// CHECK-EXE-NEXT:           b       0x30000070 <__AArch64AbsLongThunk_>
 // CHECK-EXE-NEXT:           bl      0x30000080 <__AArch64AbsLongThunk_>
-// CHECK-EXE-NEXT:           bl      0x30000090 <__AArch64AbsLongThunk_>
-// CHECK-EXE-NEXT:           b       0x30000090 <__AArch64AbsLongThunk_>
-// CHECK-EXE-NEXT:           bl      0x300000a0 <__AArch64AbsLongThunk_>
-// CHECK-EXE-NEXT:           b       0x300000a0 <__AArch64AbsLongThunk_>
-// CHECK-EXE-NEXT:           bl      0x300000b0 <__AArch64AbsLongThunk_>
-// CHECK-EXE-NEXT:           b       0x300000b0 <__AArch64AbsLongThunk_>
-// CHECK-EXE-NEXT:           bl      0x300000c0 <__AArch64AbsLongThunk_>
-// CHECK-EXE-NEXT:           b       0x300000c0 <__AArch64AbsLongThunk_>
-// CHECK-EXE-NEXT:           bl      0x300000d0 <__AArch64AbsLongThunk_via_plt>
+// CHECK-EXE-NEXT:           b       0x30000080 <__AArch64AbsLongThunk_>
+// CHECK-EXE-NEXT:           bl      0x30000060 <__AArch64AbsLongThunk_>
+// CHECK-EXE-NEXT:           b       0x30000060 <__AArch64AbsLongThunk_>
+// CHECK-EXE-NEXT:           bl      0x30000050 <__AArch64AbsLongThunk_>
+// CHECK-EXE-NEXT:           b       0x30000050 <__AArch64AbsLongThunk_>
+// CHECK-EXE-NEXT:           bl      0x30000040 <__AArch64AbsLongThunk_via_plt>
 // CHECK-EXE-NEXT:           bl      0x300000e0 <__AArch64AbsLongThunk_absolute>
 
-// CHECK-EXE-LABEL: 0000000030000040 <__AArch64AbsLongThunk_>:
-// CHECK-EXE-NEXT: 30000040: ldr     x16, 0x30000048 <__AArch64AbsLongThunk_+0x8>
+// CHECK-EXE-LABEL: <__AArch64AbsLongThunk_via_plt>:
+// CHECK-EXE-NEXT: 30000040: ldr     x16, 0x30000048 <__AArch64AbsLongThunk_via_plt+0x8>
 // CHECK-EXE-NEXT:           br      x16
-// CHECK-EXE-NEXT:     00 10 00 18   .word   0x18001000
+// CHECK-EXE-NEXT:     80 10 00 18   .word   0x18001080
 // CHECK-EXE-NEXT:     00 00 00 00   .word   0x00000000
 
 // CHECK-EXE-LABEL: <__AArch64AbsLongThunk_>:
 // CHECK-EXE-NEXT: 30000050: ldr     x16, 0x30000058 <__AArch64AbsLongThunk_+0x8>
 // CHECK-EXE-NEXT:           br      x16
-// CHECK-EXE-NEXT:     08 10 00 18   .word   0x18001008
+// CHECK-EXE-NEXT:     44 10 00 18   .word   0x18001044
 // CHECK-EXE-NEXT:     00 00 00 00   .word   0x00000000
 
 // CHECK-EXE-LABEL: <__AArch64AbsLongThunk_>:
 // CHECK-EXE-NEXT: 30000060: ldr     x16, 0x30000068 <__AArch64AbsLongThunk_+0x8>
 // CHECK-EXE-NEXT:           br      x16
-// CHECK-EXE-NEXT:     10 10 00 18   .word   0x18001010
+// CHECK-EXE-NEXT:     3c 10 00 18   .word   0x1800103c
 // CHECK-EXE-NEXT:     00 00 00 00   .word   0x00000000
 
 // CHECK-EXE-LABEL: <__AArch64AbsLongThunk_>:
 // CHECK-EXE-NEXT: 30000070: ldr     x16, 0x30000078 <__AArch64AbsLongThunk_+0x8>
 // CHECK-EXE-NEXT:           br      x16
-// CHECK-EXE-NEXT:     18 10 00 18   .word   0x18001018
+// CHECK-EXE-NEXT:     28 10 00 18   .word   0x18001028
 // CHECK-EXE-NEXT:     00 00 00 00   .word   0x00000000
 
 // CHECK-EXE-LABEL: <__AArch64AbsLongThunk_>:
 // CHECK-EXE-NEXT: 30000080: ldr     x16, 0x30000088 <__AArch64AbsLongThunk_+0x8>
 // CHECK-EXE-NEXT:           br      x16
-// CHECK-EXE-NEXT:     20 10 00 18   .word   0x18001020
+// CHECK-EXE-NEXT:     30 10 00 18   .word   0x18001030
 // CHECK-EXE-NEXT:     00 00 00 00   .word   0x00000000
 
 // CHECK-EXE-LABEL: <__AArch64AbsLongThunk_>:
 // CHECK-EXE-NEXT: 30000090: ldr     x16, 0x30000098 <__AArch64AbsLongThunk_+0x8>
 // CHECK-EXE-NEXT:           br      x16
-// CHECK-EXE-NEXT:     28 10 00 18   .word   0x18001028
+// CHECK-EXE-NEXT:     20 10 00 18   .word   0x18001020
 // CHECK-EXE-NEXT:     00 00 00 00   .word   0x00000000
 
 // CHECK-EXE-LABEL: <__AArch64AbsLongThunk_>:
 // CHECK-EXE-NEXT: 300000a0: ldr     x16, 0x300000a8 <__AArch64AbsLongThunk_+0x8>
 // CHECK-EXE-NEXT:           br      x16
-// CHECK-EXE-NEXT:     30 10 00 18   .word   0x18001030
+// CHECK-EXE-NEXT:     18 10 00 18   .word   0x18001018
 // CHECK-EXE-NEXT:     00 00 00 00   .word   0x00000000
 
 // CHECK-EXE-LABEL: <__AArch64AbsLongThunk_>:
 // CHECK-EXE-NEXT: 300000b0: ldr     x16, 0x300000b8 <__AArch64AbsLongThunk_+0x8>
 // CHECK-EXE-NEXT:           br      x16
-// CHECK-EXE-NEXT:     3c 10 00 18   .word   0x1800103c
+// CHECK-EXE-NEXT:     10 10 00 18   .word   0x18001010
 // CHECK-EXE-NEXT:     00 00 00 00   .word   0x00000000
 
 // CHECK-EXE-LABEL: <__AArch64AbsLongThunk_>:
 // CHECK-EXE-NEXT: 300000c0: ldr     x16, 0x300000c8 <__AArch64AbsLongThunk_+0x8>
 // CHECK-EXE-NEXT:           br      x16
-// CHECK-EXE-NEXT:     44 10 00 18   .word   0x18001044
+// CHECK-EXE-NEXT:     08 10 00 18   .word   0x18001008
 // CHECK-EXE-NEXT:     00 00 00 00   .word   0x00000000
 
-// CHECK-EXE-LABEL: <__AArch64AbsLongThunk_via_plt>:
-// CHECK-EXE-NEXT: 300000d0: ldr     x16, 0x300000d8 <__AArch64AbsLongThunk_via_plt+0x8>
+// CHECK-EXE-LABEL: <__AArch64AbsLongThunk_>:
+// CHECK-EXE-NEXT: 300000d0: ldr     x16, 0x300000d8 <__AArch64AbsLongThunk_+0x8>
 // CHECK-EXE-NEXT:           br      x16
-// CHECK-EXE-NEXT:     80 10 00 18   .word   0x18001080
+// CHECK-EXE-NEXT:     00 10 00 18   .word   0x18001000
 // CHECK-EXE-NEXT:     00 00 00 00   .word   0x00000000
 
 // CHECK-EXE-LABEL: <__AArch64AbsLongThunk_absolute>:
diff --git a/lld/test/ELF/aarch64-thunk-script.s b/lld/test/ELF/aarch64-thunk-script.s
index a6c524f548288..1a574e7fd3ab5 100644
--- a/lld/test/ELF/aarch64-thunk-script.s
+++ b/lld/test/ELF/aarch64-thunk-script.s
@@ -29,13 +29,13 @@ high_target:
 // CHECK: Disassembly of section .text_low:
 // CHECK-EMPTY:
 // CHECK-NEXT: <_start>:
-// CHECK-NEXT:     2000:       bl      0x200c <__AArch64AbsLongThunk_high_target>
-// CHECK-NEXT:     2004:       bl      0x2010 <__AArch64AbsLongThunk_>
+// CHECK-NEXT:     2000:       bl      0x2010 <__AArch64AbsLongThunk_high_target>
+// CHECK-NEXT:     2004:       bl      0x200c <__AArch64AbsLongThunk_>
 // CHECK-NEXT:                 ret
-// CHECK: <__AArch64AbsLongThunk_high_target>:
-// CHECK-NEXT:     200c:       b       0x8002000 <high_target>
 // CHECK: <__AArch64AbsLongThunk_>:
-// CHECK-NEXT:     2010:       b       0x8002004 <high_target+0x4>
+// CHECK-NEXT:     200c:       b       0x8002004 <high_target+0x4>
+// CHECK: <__AArch64AbsLongThunk_high_target>:
+// CHECK-NEXT:     2010:       b       0x8002000 <high_target>
 // CHECK: Disassembly of section .text_high:
 // CHECK-EMPTY:
 // CHECK-NEXT: <high_target>:

>From 9e44a37153fca93f65466500c8edd9675921c4a7 Mon Sep 17 00:00:00 2001
From: Pranav Kant <prka at google.com>
Date: Thu, 16 Jul 2026 13:44:25 -0700
Subject: [PATCH 4/4] clang-format

---
 lld/ELF/SyntheticSections.cpp | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 17048dd62f5a8..40965cc3b5362 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -4097,13 +4097,13 @@ bool ThunkSection::assignOffsets(bool sort) {
     //    ...
     //    destC
     //    destD
-    // 
+    //
     // Sorting will rearrange thunks as follows:
-    // 
+    //
     //    destA
     //    destB
     //    ...
-    //    backwards B 
+    //    backwards B
     //    backwards A
     //    ...
     //    forwards D
@@ -4111,10 +4111,11 @@ bool ThunkSection::assignOffsets(bool sort) {
     //    ...
     //    destC
     //    destD
-    // 
-    // Since we iterate on thunks from first to last in a thunk section while doing upgradation,
-    // any thunk that is found to be out of range is guarranted to not invalidate thunks
-    // that we have already iterated on. This allows quicker convergence.
+    //
+    // Since we iterate on thunks from first to last in a thunk section while
+    // doing upgradation, any thunk that is found to be out of range is
+    // guarranted to not invalidate thunks that we have already iterated on.
+    // This allows quicker convergence.
     uint64_t sectionVA = getVA();
     llvm::stable_sort(thunks, [sectionVA](const Thunk *a, const Thunk *b) {
       bool aFwd = a->getDestVA() > sectionVA;



More information about the llvm-commits mailing list