llvm / llvm/llvm-project

RISC-V Inefficient Codegen with Scoped VLAs

Open
#161,482 5 comments 0 reactions 0 assignees View on GitHub
backend:RISC-V llvm:codesize missed-optimization
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

https://godbolt.org/z/Tfn6s5rrc

The code here has a VLA inside an inner scope, so uses `@llvm.stacksave` and `@llvm.stackrestore` to save/restore the stack inside the code. The variable sized frame object is added during isel (`fi#0`).

At the end of the function, there is this perculiar sequence:

```
mv sp, a0
li a0, 1
addi sp, s0, -16
qc.cm.pop {ra, s0}, 16
```

The `mv` and the `addi` both put the same value back into `sp`. We don't need both from what I can see.

The `mv` comes from a COPY introduced by isel for `@llvm.stackrestore`. The `addi` is introduced by PEI.

---

I have also seen examples where the initial update of `SP` for the vla's dynamic allocation is done inefficiently: https://godbolt.org/z/3f3cec9jx

```
qc.cm.pushfp {ra, s0}, -16
mv a0, sp
mv a3, sp
addi a2, a3, -16
mv sp, a2
...
mv sp, a0
li a0, 1
addi sp, s0, -16
qc.cm.pop {ra, s0}, 16
```

The `mv; addi; mv` sequence could just be `addi sp, sp, -16`. It looks to be happening during ISel as well, rather than in PEI. I hope that can be made more efficient.

Contributor guide

Open the contributing guide

Research direction

Start with the two linked Godbolt examples and trace the @llvm.stackrestore COPY through instruction selection, then compare it with the PEI-generated stack adjustment. Investigate the fi#0 frame object and the RISC-V sequences shown; done means the redundant stack-pointer moves are eliminated without changing VLA allocation or restoration behavior.

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
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.