[llvm] [BOLT][RISCV] Mark newly created tail calls (PR #221672)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 7 01:04:18 PDT 2026
https://github.com/WangJee created https://github.com/llvm/llvm-project/pull/221672
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.
>From 907602a58e13df7f3bdb73cd0c66422aa40f48cc Mon Sep 17 00:00:00 2001
From: "wangjue.wangjue" <wangjue.wangjue at alibaba-inc.com>
Date: Mon, 7 Sep 2026 17:01:31 +0900
Subject: [PATCH] [BOLT][RISCV] Mark newly created tail calls
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.
---
bolt/lib/Passes/FixRISCVCallsPass.cpp | 4 ++
bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp | 3 +-
.../test/RISCV/conditional-tail-call-relocs.s | 48 +++++++++++++++++++
3 files changed, 54 insertions(+), 1 deletion(-)
create mode 100644 bolt/test/RISCV/conditional-tail-call-relocs.s
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
More information about the llvm-commits
mailing list