[llvm] [BOLT][RISCV] Mark newly created tail calls (PR #221672)

via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 7 01:22:18 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-risc-v

Author: wangjue (WangJee)

<details>
<summary>Changes</summary>

Tail calls created during CFG normalization lack the tail-call annotation, so FixRISCVCallsPass rewrites them as regular calls that clobber ra.

Set the annotation in createTailCall(). Clear builder annotations before moving the originals when rebuilding calls to avoid duplicate annotation markers.

Add a relocation-mode regression test for a conditional tail call.

---
Full diff: https://github.com/llvm/llvm-project/pull/221672.diff


3 Files Affected:

- (modified) bolt/lib/Passes/FixRISCVCallsPass.cpp (+4) 
- (modified) bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp (+2-1) 
- (added) bolt/test/RISCV/conditional-tail-call-relocs.s (+48) 


``````````diff
diff --git a/bolt/lib/Passes/FixRISCVCallsPass.cpp b/bolt/lib/Passes/FixRISCVCallsPass.cpp
index 6b73bd6854c9d..3b4a75c840389 100644
--- a/bolt/lib/Passes/FixRISCVCallsPass.cpp
+++ b/bolt/lib/Passes/FixRISCVCallsPass.cpp
@@ -35,6 +35,8 @@ void FixRISCVCallsPass::runOnFunction(BinaryFunction &BF) {
         else
           MIB->createCall(*II, Target, Ctx);
 
+        // Discard annotations added by the builder before moving the originals.
+        MIB->stripAnnotations(*II);
         MIB->moveAnnotations(std::move(OldCall), *II);
         ++II;
         continue;
@@ -59,6 +61,8 @@ void FixRISCVCallsPass::runOnFunction(BinaryFunction &BF) {
         else
           MIB->createCall(*NextII, Target, Ctx);
 
+        // Discard annotations added by the builder before moving the originals.
+        MIB->stripAnnotations(*NextII);
         MIB->moveAnnotations(std::move(OldCall), *NextII);
 
         II = std::next(NextII);
diff --git a/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp b/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp
index 349f38cb11b26..228b51088d79d 100644
--- a/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp
+++ b/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp
@@ -307,7 +307,8 @@ class RISCVMCPlusBuilder : public MCPlusBuilder {
 
   void createTailCall(MCInst &Inst, const MCSymbol *Target,
                       MCContext *Ctx) override {
-    return createCall(RISCV::PseudoTAIL, Inst, Target, Ctx);
+    createCall(RISCV::PseudoTAIL, Inst, Target, Ctx);
+    setTailCall(Inst);
   }
 
   InstructionListType createIndirectPLTCall(MCInst &&DirectCall,
diff --git a/bolt/test/RISCV/conditional-tail-call-relocs.s b/bolt/test/RISCV/conditional-tail-call-relocs.s
new file mode 100644
index 0000000000000..eb70f5d7ce2a2
--- /dev/null
+++ b/bolt/test/RISCV/conditional-tail-call-relocs.s
@@ -0,0 +1,48 @@
+// A conditional branch from f to g is a tail call: g must return to _start
+// without overwriting ra. CFG normalization creates a new tail instruction,
+// which must be marked as a tail call before FixRISCVCallsPass rewrites it.
+
+// RUN: llvm-mc -triple=riscv64 -filetype=obj %s -o %t.o
+// RUN: ld.lld --emit-relocs --no-relax %t.o -o %t
+// RUN: llvm-bolt %t -o %t.bolt --enable-bat --print-cfg \
+// RUN:   --print-fix-riscv-calls --print-only=f \
+// RUN:   --simplify-conditional-tail-calls=false | FileCheck %s
+// RUN: llvm-objdump -d -M no-aliases --disassemble-symbols=f %t.bolt \
+// RUN:   | FileCheck %s --check-prefix=DISASM
+
+// --enable-bat keeps Offset annotations so their preservation is also checked.
+// CHECK-LABEL: Binary Function "f" after building cfg {
+// CHECK: tail g # TAILCALL # Offset: 0
+// CHECK-LABEL: Binary Function "f" after fix-riscv-calls {
+// CHECK: tail g # TAILCALL # Offset: 0
+
+// DISASM-LABEL: <f>:
+// DISASM-NOT: jal ra,
+// DISASM: jal zero, {{.*}}<g>
+// DISASM-NOT: jal ra,
+
+  .text
+  .option norvc
+  .globl _start, f, g
+
+  .type _start, @function
+_start:
+  li a0, 0
+  call f
+  li a7, 93
+  ecall
+  .size _start, .-_start
+
+  .type f, @function
+f:
+  .option push
+  .option exact
+  beq a0, zero, g
+  .option pop
+  ret
+  .size f, .-f
+
+  .type g, @function
+g:
+  ret
+  .size g, .-g

``````````

</details>


https://github.com/llvm/llvm-project/pull/221672


More information about the llvm-commits mailing list