Skip to content

Conversation

zengdage
Copy link
Contributor

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

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
```
@llvmbot
Copy link
Member

llvmbot commented Sep 22, 2025

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

@llvm/pr-subscribers-bolt

Author: Zhijin Zeng (zengdage)

Changes

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

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

1 Files Affected:

  • (modified) bolt/lib/Target/RISCV/RISCVMCPlusBuilder.cpp (+18)
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:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants