[ARM][NEON] vuzp.16 not emitted for vuzpq_p16 on ARM big-endian
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
## Summary
On the ARM big-endian NEON target, the `vuzp.16` instruction is no longer emitted for the `vuzpq_p16` NEON intrinsic. It degenerates into a long sequence of element-by-element `vmov` moves between NEON lanes and GPRs. The little-endian target lowers the same source to a single `vuzp.16`, so this is a big-endian-specific code-quality regression.
## Environment
- LLVM/clang version: clang(trunk)
- Target: ARM big-endian
## Reproducer
https://godbolt.org/z/M3TE6csoh
```c
// vuzpqp16.c
#include "arm_neon.h"
poly16x8x2_t test_vuzpqp16(poly16x8_t _a, poly16x8_t _b)
{
return vuzpq_p16(_a, _b);
}
```
Compile
```bash
clang vuzpqp16.c -O1 -mfpu=neon -mfloat-abi=softfp -S -o vuzp_le.s
clang vuzpqp16.c -O1 -mfpu=neon -mfloat-abi=softfp -mbig-endian -S -o vuzp_be.s
```
## Actual behavior
### Little-endian
```asm
test_vuzpqp16:
vmov d16, r2, r3
vldr d17, [sp]
add r1, sp, #8
vld1.64 {d18, d19}, [r1]
vuzp.16 q8, q9
vst1.16 {d16, d17}, [r0]!
vst1.64 {d18, d19}, [r0]
bx lr
```
### Big-endian
```asm
test_vuzpqp16:
vldr d19, [sp]
add r1, sp, #8
vmov d18, r3, r2
vld1.64 {d16, d17}, [r1]
vrev64.16 q10, q8
vmov.u16 r1, d21[0]
vmov.16 d17[0], r1
vmov.u16 r1, d21[2]
vmov.16 d17[1], r1
vmov.u16 r1, d20[0]
vmov.16 d17[2], r1
vmov.u16 r1, d20[2]
vmov.16 d17[3], r1
vmov.u16 r1, d21[1]
vmov.16 d23[0], r1
vmov.u16 r1, d21[3]
vmov.16 d23[1], r1
vmov.u16 r1, d20[1]
vmov.16 d23[2], r1
vmov.u16 r1, d20[3]
vmov.16 d23[3], r1
vrev64.16 q9, q9
vmov.u16 r1, d19[1]
vmov.16 d22[0], r1
vmov.u16 r1, d19[3]
vmov.16 d22[1], r1
vmov.u16 r1, d18[1]
vmov.16 d22[2], r1
vmov.u16 r1, d18[3]
vmov.16 d22[3], r1
vst1.16 {d22, d23}, [r0]!
vmov.u16 r1, d19[0]
vmov.16 d16[0], r1
vmov.u16 r1, d19[2]
vmov.16 d16[1], r1
vmov.u16 r1, d18[0]
vmov.16 d16[2], r1
vmov.u16 r1, d18[2]
vmov.16 d16[3], r1
vrev64.16 q8, q8
vst1.64 {d16, d17}, [r0]
bx lr
```
Contributor guide
Research direction
Start with the vuzpq_p16 reproducer in vuzpqp16.c and compare the little-endian and big-endian assembly produced by the listed clang commands. Investigate the ARM NEON lowering path for this intrinsic and verify the fix by checking that the big-endian output emits vuzp.16 rather than the shown lane-by-lane vmov sequence.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100