https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127704

            Bug ID: 127704
           Summary: [AArch64][SVE] Missed vectorization of long-to-float
                    reduction
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bug_hunters at yeah dot net
  Target Milestone: ---

## [AArch64][SVE] Missed vectorization of long-to-float reduction

GCC fails to vectorize a simple floating-point reduction involving a
`long`-to-`float` conversion on AArch64 SVE, while Clang successfully
vectorizes the same loop.

### Test case

```c
float foo(const long *__restrict__ a, int n)
{
    float sum = 0;
    for (int i = 0; i < n; i++)
        sum += (float)a[i];
    return sum;
}
```

### GCC version

```text
aarch64-unknown-linux-gnu-g++ (GCC) 16.1.0
```

### GCC options

```text
-O3 -march=armv9-a+sve -ftree-vectorize -fvect-cost-model=unlimited -ffast-math
-fopt-info-vec-all
```

### GCC output

```text
<source>:4:23: missed: couldn't vectorize loop
<source>:4:23: missed: unsupported SLP instances
<source>:1:7: note: vectorized 0 loops in function.
<source>:5:13: note: ***** Analysis failed with vector mode VNx2DI
<source>:5:13: note: ***** The result for vector mode VNx16QI would be the same
<source>:5:13: note: ***** The result for vector mode VNx8QI would be the same
<source>:5:13: note: ***** The result for vector mode VNx4QI would be the same
<source>:5:13: note: ***** Re-trying analysis with vector mode VNx2QI
<source>:5:13: note: ***** Analysis failed with vector mode VNx2QI
<source>:5:13: note: ***** Re-trying analysis with vector mode V16QI
<source>:5:13: note: ***** Analysis failed with vector mode V16QI
<source>:5:13: note: ***** The result for vector mode V8QI would be the same
<source>:5:13: note: ***** The result for vector mode V4HI would be the same
<source>:5:13: note: ***** Re-trying analysis with vector mode V2SI
<source>:5:13: note: ***** Analysis failed with vector mode V2SI
```

The failure also occurs with `-ffast-math`, so relaxing floating-point
semantics does not enable vectorization.

### Clang result

Clang 22.1.0 successfully vectorizes the same loop for AArch64 SVE:

```text
<source>:4:5: remark: vectorized loop (vectorization width: vscale x 2,
interleaved count: 2) [-Rpass=loop-vectorize]
```

The generated SVE code contains the required vector conversion and reduction:

```asm
ldr     z1, [x10]
scvtf   z1.s, p0/m, z1.d
fadda   s0, p0, s0, z1.s
```

Thus, the target provides instructions for performing the signed 64-bit
integer-to-single-precision floating-point conversion and the floating-point
reduction.

### Additional observation

The failure is type-sensitive. Changing the input element type from `long` to
`int` allows GCC to vectorize the otherwise equivalent loop.

The minimized test case also removes the structure access, reverse iteration,
and complicated indexing from the original test case, while the failure
remains.

The relevant operation pattern is:

```text
load i64
   |
   v
signed i64 -> float
   |
   v
floating-point reduction
```

GCC reports `unsupported SLP instances` for this pattern, whereas Clang can
vectorize it using SVE `scvtf` and `fadda`. This case may be related to FP
Math.

### Actual behavior

GCC fails to vectorize the loop and reports:

```text
missed: couldn't vectorize loop
missed: unsupported SLP instances
```

This occurs even with `-fvect-cost-model=unlimited` and `-ffast-math`.
Live examples reproducing the behavior are available on Compiler Explorer:
GCC: https://godbolt.org/z/3PsTqsqe3
Clang: https://godbolt.org/z/sGbTdj44a

Reply via email to