llvm / llvm/llvm-project

[AArch64] Fusion of floating-point round+convert to integer is not always performed

Open
#170,010 2 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

AArch64 has instructions for converting a float to an int using a variety of different rounding modes (`fcvtn`, `fcvta`, `fcvtp`, `fcvtm`, etc). When a call to a floating-point rounding intrinsic (`floor`, `ceil`, `round`, `rint`, `trunc`) is followed by `fptoui` or `fptosi`, that sequence should be combined into a single rounding conversion instruction.

From my testing, LLVM currently performs this optimization for scalar `floor`, `ceil`, `round`, and `trunc`. The optimization is missing for `rint`, and for vector operations (including autovectorized ones).

[Here's a Compiler Explorer demo.](https://godbolt.org/z/nKjjEsqGh) The `round_to_int`, `floor_to_int`, `ceil_to_int`, and `trunc_to_int` functions compile down to a single `fcvt[mode]u`. However, the `round_to_int_ties_even` function compiles down to a `frintx`+`fcvtzu`. All the four-at-a-time functions are autovectorized, and likewise compile down to a vector `frint[mode]`+`fcvtzu` instead of a vector `fcvt[mode]u`.

Contributor guide

Open the contributing guide

Research direction

Start with the linked Compiler Explorer demo and compare the scalar and four-at-a-time functions for rint and the other rounding modes. Investigate why rint and vector operations produce separate rounding and conversion instructions. Done means the missing scalar and vector cases, including autovectorized operations, use a single appropriate AArch64 rounding-conversion instruction.

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.