llvm / llvm/llvm-project

[RISC-V] Minor Code Size Regression in embench-iot picojpeg

Open
#190,868 4 comments 0 reactions 0 assignees View on GitHub
backend:RISC-V llvm:codesize
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

In the `picojpeg` benchmark in [embench-iot v1.0](https://github.com/embench/embench-iot/tree/embench-1.0), I'm seeing a lot more `c.slli` instructions since llvm 22. Overall this becomes around a 0.7% code size regression.

My baseline is clang 22.1.0, built using 4434dabb69916856b824f68a64b029c67175e532 (we have one cherry-pick after this, but it's not for RISC-V). I'm comparing this to clang built using 3098b4da81c2 (a recent `main` commit). The configuration for both baseline and the comparison is `--target=riscv32-unknown-unknown-elf -march=rv32imac_zba_zbb -mabi=ilp32 -Os -fno-PIC`.

Looking at the instruction composition of `picojpeg`, I'm seeing:
```
instruction baseline compare diff size
c.slli 28 107 +79 +158b
c.addi 345 347 +2 +4b
andi 113 114 +1 +4b
c.unimp 2 1 -1 -2b
addi 554 553 -1 -4b
lui 66 65 -1 -4b
sext.h 32 22 -10 -40b
```

Looking at a specific example of this, in `upsampleCrV` :

Baseline code:
```
c.srli a0, 0x1f
c.addi a0, -0x1
```

Trunk:
```
c.slli a0, 0x10
c.srli a0, 0x1f
c.addi a0, -0x1
```

The thing I find strange is these are doing different things - the former is setting `a0` to `-1` or `0` based on incoming bit 31 (`0` or `1` respectively). The latter is looking at incoming bit 15 - maybe we knew that it was sign extended before? I'm not seeing exactly how from the previous instructions.

Godbolt Reproducer: https://godbolt.org/z/n6vshno3c

Filing this now as I know we did some work on shifts for the P codegen, I wonder if that's where the issue came from.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.