[llvm] [BOLT][AArch64] Fix crash for conditional tail calls (PR #140669)

Maksim Panchenko via llvm-commits llvm-commits at lists.llvm.org
Mon May 19 20:32:55 PDT 2025


https://github.com/maksfb created https://github.com/llvm/llvm-project/pull/140669

When conditional tail call is located in old code while BOLT is operating in lite mode, the call will require optional pending relocation with a type that is currently not supported resulting in a build-time crash.

Before a proper fix is implemented, ignore conditional tail calls for relocation purposes and mark their target functions to be patched, i.e. to be served as veneers/thunks.

>From 76bee3609155a3fa3a5a1507bc09597b5d78a3ef Mon Sep 17 00:00:00 2001
From: Maksim Panchenko <maks at fb.com>
Date: Mon, 19 May 2025 20:23:40 -0700
Subject: [PATCH] [BOLT][AArch64] Fix crash for conditional tail calls

When conditional tail call is located in old code while BOLT is
operating in lite mode, the call will require optional pending
relocation with a type that is currently not supported resulting in a
build-time crash.

Before a proper fix is implemented, ignore conditional tail calls for
relocation purposes and mark their target functions to be patched, i.e.
to be served as veneers/thunks.
---
 bolt/lib/Core/BinaryFunction.cpp | 20 ++++++++++++++++----
 bolt/test/AArch64/lite-mode.s    |  9 +++++++++
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index 851fa36a6b4b7..1f9f023a10811 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -1783,10 +1783,22 @@ bool BinaryFunction::scanExternalRefs() {
     // On AArch64, we use instruction patches for fixing references. We make an
     // exception for branch instructions since they require optional
     // relocations.
-    if (BC.isAArch64() && !BranchTargetSymbol) {
-      LLVM_DEBUG(BC.printInstruction(dbgs(), Instruction, AbsoluteInstrAddr));
-      InstructionPatches.push_back({AbsoluteInstrAddr, Instruction});
-      continue;
+    if (BC.isAArch64()) {
+      if (!BranchTargetSymbol) {
+        LLVM_DEBUG(BC.printInstruction(dbgs(), Instruction, AbsoluteInstrAddr));
+        InstructionPatches.push_back({AbsoluteInstrAddr, Instruction});
+        continue;
+      }
+
+      // Conditional tail calls require new relocation types that are currently
+      // not supported. https://github.com/llvm/llvm-project/issues/138264
+      if (BC.MIB->isConditionalBranch(Instruction)) {
+        if (BinaryFunction *TargetBF =
+                BC.getFunctionForSymbol(BranchTargetSymbol)) {
+          TargetBF->setNeedsPatch(true);
+          continue;
+        }
+      }
     }
 
     // Emit the instruction using temp emitter and generate relocations.
diff --git a/bolt/test/AArch64/lite-mode.s b/bolt/test/AArch64/lite-mode.s
index d1e35ef75de46..f2d06219f7a2d 100644
--- a/bolt/test/AArch64/lite-mode.s
+++ b/bolt/test/AArch64/lite-mode.s
@@ -129,6 +129,15 @@ cold_function:
 # CHECK-INPUT-NEXT: b {{.*}} <_start>
 # CHECK-NEXT:       b {{.*}} <_start.org.0>
 
+## Quick test for conditional tail calls. A proper test is being added in:
+## https://github.com/llvm/llvm-project/pull/139565
+## For now check that llvm-bolt doesn't choke on CTCs.
+.ifndef COMPACT
+  b.eq _start
+  cbz x0, _start
+  tbz x0, 42, _start
+.endif
+
   .cfi_endproc
   .size cold_function, .-cold_function
 



More information about the llvm-commits mailing list