llvm / llvm/llvm-project

[AArch64] Failure to convert `x * y + z` into `fmadd` for `float16_t`

Open
#218,133 4 comments 0 reactions 0 assignees View on GitHub
backend:AArch64 missed-optimization
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

https://godbolt.org/z/voo9as94o
```c++
#include
#include

auto f16(float16_t x, float16_t y, float16_t z) -> float16_t {
// Intermediate results must be stored in variables to avoid conversions to
// float32_t
float16_t t = x * y;
return t + z;
}

auto f32(float32_t x, float32_t y, float32_t z) -> float32_t {
return x * y + z;
}

auto f64(float64_t x, float64_t y, float64_t z) -> float64_t {
return x * y + z;
}
```

```asm
f16(half, half, half, half):
fmul h0, h0, h1
fadd h0, h0, h2
ret

f32(float, float, float, float):
fmadd s0, s0, s1, s2
ret

f64(double, double, double, double):
fmadd d0, d0, d1, d2
ret
```

[Alive timed out](https://alive2.llvm.org/ce/z/2egtKJ), but since LLVM is happy to do the same transformation for float32 and float64, I assume it is valid.

Contributor guide

Open the contributing guide

Research direction

Start by running the C++ reproducer in the linked Godbolt example and compare the AArch64 output for float16_t with float32_t and float64_t. Inspect the AArch64 compiler optimization path for floating-point multiply-add fusion; done means the float16_t sequence emits an fmadd instruction, subject to confirming legality because the linked Alive2 check timed out.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.