[llvm] [BOLT][RISCV] Fix conditional tail call (PR #209474)
Pengcheng Wang via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 13 00:09:36 PDT 2026
https://github.com/wangpc-pp updated https://github.com/llvm/llvm-project/pull/209474
>From 4dbe13695d2b2471e33b76c064bd359738d37055 Mon Sep 17 00:00:00 2001
From: Thrrreeeee <1379998393 at qq.com>
Date: Wed, 15 Jul 2026 11:30:49 +0800
Subject: [PATCH 1/2] [BOLT][RISCV] Fix conditional tail call
---
bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp | 12 +++-
bolt/test/RISCV/conditional-tail-call.s | 65 ++++++++++++++++++++
2 files changed, 76 insertions(+), 1 deletion(-)
create mode 100644 bolt/test/RISCV/conditional-tail-call.s
diff --git a/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp b/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp
index d1a0572277874..a1461645409a3 100644
--- a/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp
+++ b/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp
@@ -215,7 +215,7 @@ class RISCVMCPlusBuilder : public MCPlusBuilder {
switch (Inst.getOpcode()) {
default:
- llvm_unreachable("unsupported tail call opcode");
+ return false;
case RISCV::JAL:
case RISCV::JALR:
case RISCV::C_J:
@@ -227,6 +227,14 @@ class RISCVMCPlusBuilder : public MCPlusBuilder {
return true;
}
+ bool convertTailCallToJmp(MCInst &Inst) override {
+ removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);
+ clearOffset(Inst);
+ if (getConditionalTailCall(Inst))
+ unsetConditionalTailCall(Inst);
+ return true;
+ }
+
void createReturn(MCInst &Inst) const override {
// TODO "c.jr ra" when RVC is enabled
Inst.setOpcode(RISCV::JALR);
@@ -328,6 +336,8 @@ class RISCVMCPlusBuilder : public MCPlusBuilder {
default:
return false;
case RISCV::C_J:
+ case RISCV::PseudoCALL:
+ case RISCV::PseudoTAIL:
OpNum = 0;
return true;
case RISCV::AUIPC:
diff --git a/bolt/test/RISCV/conditional-tail-call.s b/bolt/test/RISCV/conditional-tail-call.s
new file mode 100644
index 0000000000000..27fda07279266
--- /dev/null
+++ b/bolt/test/RISCV/conditional-tail-call.s
@@ -0,0 +1,65 @@
+// Check that all base and compressed RISC-V conditional branches targeting
+// another function are expanded to tail-call blocks, survive block reordering,
+// and are emitted with the correct target.
+
+// RUN: llvm-mc -triple riscv64 -mattr=+c -filetype=obj -o %t.o %s
+// RUN: ld.lld -o %t %t.o
+// RUN: llvm-bolt %t -o %t.bolt --reorder-blocks=reverse --print-cfg \
+// RUN: --print-only=conditional_tail_calls 2>&1 | FileCheck %s
+// RUN: llvm-objdump -d --disassemble-symbols=conditional_tail_calls %t.bolt \
+// RUN: | FileCheck %s --check-prefix=DISASM
+
+// CHECK: Binary Function "conditional_tail_calls" after building cfg {
+// CHECK: beq a0, a1, .LTC0
+// CHECK: bne a0, a1, .LTC1
+// CHECK: blt a0, a1, .LTC2
+// CHECK: bge a0, a1, .LTC3
+// CHECK: bltu a0, a1, .LTC4
+// CHECK: bgeu a0, a1, .LTC5
+// CHECK: beqz a0, .LTC6
+// CHECK: bnez a0, .LTC7
+// CHECK: BOLT-INFO: basic block reordering modified layout of 1 functions
+
+// DISASM-LABEL: <conditional_tail_calls>:
+// DISASM-NEXT: {{.*}} beq a0, a1, {{.*}} <callee>
+// DISASM-NEXT: {{.*}} bne a0, a1, {{.*}} <callee>
+// DISASM-NEXT: {{.*}} blt a0, a1, {{.*}} <callee>
+// DISASM-NEXT: {{.*}} bge a0, a1, {{.*}} <callee>
+// DISASM-NEXT: {{.*}} bltu a0, a1, {{.*}} <callee>
+// DISASM-NEXT: {{.*}} bgeu a0, a1, {{.*}} <callee>
+// DISASM-NEXT: {{.*}} beqz a0, {{.*}} <callee>
+// DISASM-NEXT: {{.*}} bnez a0, {{.*}} <callee>
+// DISASM-NEXT: {{.*}} ret
+
+ .text
+ .option rvc
+
+ .globl conditional_tail_calls
+ .type conditional_tail_calls, @function
+ .p2align 1
+conditional_tail_calls:
+ beq a0, a1, .Lcallee
+ bne a0, a1, .Lcallee
+ blt a0, a1, .Lcallee
+ bge a0, a1, .Lcallee
+ bltu a0, a1, .Lcallee
+ bgeu a0, a1, .Lcallee
+ c.beqz a0, .Lcallee
+ c.bnez a0, .Lcallee
+ ret
+ .size conditional_tail_calls, .-conditional_tail_calls
+
+ .globl callee
+ .type callee, @function
+ .p2align 1
+callee:
+.Lcallee:
+ ret
+ .size callee, .-callee
+
+ .globl _start
+ .type _start, @function
+ .p2align 1
+_start:
+ ret
+ .size _start, .-_start
>From a0e4fb601493ebafb4ea00023b4f80a09a557382 Mon Sep 17 00:00:00 2001
From: Thrrreeeee <1379998393 at qq.com>
Date: Thu, 13 Aug 2026 14:22:58 +0800
Subject: [PATCH 2/2] fix test with .option
---
bolt/test/RISCV/conditional-tail-call.s | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/bolt/test/RISCV/conditional-tail-call.s b/bolt/test/RISCV/conditional-tail-call.s
index 27fda07279266..65817570406cc 100644
--- a/bolt/test/RISCV/conditional-tail-call.s
+++ b/bolt/test/RISCV/conditional-tail-call.s
@@ -38,14 +38,17 @@
.type conditional_tail_calls, @function
.p2align 1
conditional_tail_calls:
- beq a0, a1, .Lcallee
- bne a0, a1, .Lcallee
- blt a0, a1, .Lcallee
- bge a0, a1, .Lcallee
- bltu a0, a1, .Lcallee
- bgeu a0, a1, .Lcallee
- c.beqz a0, .Lcallee
- c.bnez a0, .Lcallee
+ .option push
+ .option exact
+ beq a0, a1, callee
+ bne a0, a1, callee
+ blt a0, a1, callee
+ bge a0, a1, callee
+ bltu a0, a1, callee
+ bgeu a0, a1, callee
+ c.beqz a0, callee
+ c.bnez a0, callee
+ .option pop
ret
.size conditional_tail_calls, .-conditional_tail_calls
@@ -53,7 +56,6 @@ conditional_tail_calls:
.type callee, @function
.p2align 1
callee:
-.Lcallee:
ret
.size callee, .-callee
More information about the llvm-commits
mailing list