[llvm] [bolt][riscv] Fix conditional tail call (PR #160042)

Zhijin Zeng via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 22 00:48:10 PDT 2025


https://github.com/zengdage created https://github.com/llvm/llvm-project/pull/160042

When using bolt to optimize the conditional tail call, such an error message `unsupported tail call opcode` is encountered. To resolve this issue, we need to enhance convertJmpToTailCall with support for conditional branches, and extend getSymbolRefOperandNum to handle PseudoTAIL.

For example, it will change the following code
```
beq a0, a6, func1
beq a0, a5, func2

ret
```
to
```
beq a0, a6, .L1
beq a0, a6, .L2

.L1
tail func1

.L2
tail func2
```

>From 476c93898a9104909e7328385dc809ec619587b9 Mon Sep 17 00:00:00 2001
From: Zhijin Zeng <zhijin.zeng at spacemit.com>
Date: Mon, 22 Sep 2025 15:03:38 +0800
Subject: [PATCH] [bolt][riscv] Fix conditional tail call

When using bolt to optimize the conditional tail call, such an error message
`unsupported tail call opcode` is encountered. To resolve this issue, we need
to enhance convertJmpToTailCall with support for conditional branches, and
extend getSymbolRefOperandNum to handle PseudoTAIL.

For example, it will change the following code
```
beq a0, a6, func1
beq a0, a5, func2

ret
```
to
```
beq a0, a6, .L1
beq a0, a6, .L2

.L1
tail func1

.L2
tail func2
```
---
 bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp b/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp
index 10b4913b6ab7f..003b2c7835f2a 100644
--- a/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp
+++ b/bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp
@@ -213,12 +213,29 @@ class RISCVMCPlusBuilder : public MCPlusBuilder {
     case RISCV::C_J:
     case RISCV::C_JR:
       break;
+    case RISCV::BEQ:
+    case RISCV::BNE:
+    case RISCV::BGE:
+    case RISCV::BGEU:
+    case RISCV::BLT:
+    case RISCV::BLTU:
+    case RISCV::C_BEQZ:
+    case RISCV::C_BNEZ:
+      break;
     }
 
     setTailCall(Inst);
     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);
@@ -320,6 +337,7 @@ class RISCVMCPlusBuilder : public MCPlusBuilder {
     default:
       return false;
     case RISCV::C_J:
+    case RISCV::PseudoTAIL:
       OpNum = 0;
       return true;
     case RISCV::AUIPC:



More information about the llvm-commits mailing list