llvm / llvm/llvm-project

[AArch64] manual deinterleaving `ld2` not recognized

Open
#181,514 3 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

A manual 16-bit ld4 (so normal load, then deinterleave with a shuffle) is recognized, and lowered as `ld4`. The same is for some odd reason not true for `ld2`, where more instructions are used.

https://godbolt.org/z/danjGfMb9

```asm
manual2:
ldr q1, [x0]
ext v2.16b, v1.16b, v1.16b, #8
uzp1 v0.4h, v1.4h, v2.4h
uzp2 v1.4h, v1.4h, v2.4h
ret

intrin2:
ld2 { v0.4h, v1.4h }, [x0]
ret

manual4:
ld4 { v0.4h, v1.4h, v2.4h, v3.4h }, [x0]
stp d0, d1, [x8]
stp d2, d3, [x8, #16]
ret

intrin4:
ld4 { v0.4h, v1.4h, v2.4h, v3.4h }, [x0]
stp d0, d1, [x8]
stp d2, d3, [x8, #16]
ret
```

The issue is that the `VectorCombinePass` turns

```llvm
%0 = shufflevector <8 x i16> %tmp.sroa.0.0.copyload.i, <8 x i16> poison, <4 x i32>
%1 = shufflevector <8 x i16> %tmp.sroa.0.0.copyload.i, <8 x i16> poison, <4 x i32>
%2 = bitcast <4 x i16> %0 to <8 x i8>
%3 = bitcast <4 x i16> %1 to <8 x i8>
```

into

```llvm
%0 = bitcast <8 x i16> %tmp.sroa.0.0.copyload.i to <16 x i8>
%1 = shufflevector <16 x i8> %0, <16 x i8> poison, <8 x i32>
%2 = bitcast <8 x i16> %tmp.sroa.0.0.copyload.i to <16 x i8>
%3 = shufflevector <16 x i8> %2, <16 x i8> poison, <8 x i32>
```

that presumably breaks the `ld2` pattern recognition.

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.