llvm / llvm/llvm-project

LLVM fails to tail call when `ret void` is replaced with `unreachable`

Open
#186,942 5 comments 0 reactions 0 assignees View on GitHub
llvm:optimizations
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

The following llvm ir tail calls twice. The only difference is that one return known to be `unreachable`, which should only improve optimizations
```llvm
define void @base(ptr noundef nonnull readonly captures(none) %ptr) unnamed_addr {
start:
tail call void %ptr()
ret void
}

define void @worse(ptr noundef nonnull readonly captures(none) %ptr) unnamed_addr {
start:
tail call void %ptr() #2
unreachable
}
```
On `LLVM version: 22.1.0` produces the following for `x86_64-unknown-linux-gnu` (and also seemingly equivalent assembly for other targets)
```asm
base: # @base
jmp rdi # TAILCALL
worse: # @worse
push rax
call rdi
```
I think that it is perfectly safe and correct to just produce the `base` code in both cases?

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the two LLVM IR functions on the x86_64-unknown-linux-gnu target and compare their generated assembly. Trace the tail-call decision for the `ret void` and `unreachable` cases; done means both cases produce equivalent tail-call assembly without changing correctness.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.