[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