llvm / llvm/llvm-project

[AArch64] Suboptimal code for movmask of 16/32/64 byte vectors

Open
#192,749 9 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

Currently the AArch64 backend lowers `bitcast to iN` via combinations of `ext`, `zip1` and `addv`. They can be replaced with chains of `addp` instead:

https://godbolt.org/z/qeEGcnqfG
```asm
.LCPI0_0:
.byte 1
.byte 2
.byte 4
.byte 8
.byte 16
.byte 32
.byte 64
.byte 128
.byte 1
.byte 2
.byte 4
.byte 8
.byte 16
.byte 32
.byte 64
.byte 128
example[4d0fb39774ccf68c]::src16:
ldr q0, [x0]
adrp x8, .LCPI0_0
ldr q1, [x8, :lo12:.LCPI0_0]
cmeq v0.16b, v0.16b, #0
and v0.16b, v0.16b, v1.16b
ext v1.16b, v0.16b, v0.16b, #8
zip1 v0.16b, v0.16b, v1.16b
addv h0, v0.8h
umov w0, v0.h[0]
ret

.LCPI1_0:
.byte 1
.byte 2
.byte 4
.byte 8
.byte 16
.byte 32
.byte 64
.byte 128
.byte 1
.byte 2
.byte 4
.byte 8
.byte 16
.byte 32
.byte 64
.byte 128
example[4d0fb39774ccf68c]::src32:
ldp q0, q1, [x0]
adrp x8, .LCPI1_0
ldr q2, [x8, :lo12:.LCPI1_0]
cmeq v1.16b, v1.16b, #0
cmeq v0.16b, v0.16b, #0
and v1.16b, v1.16b, v2.16b
and v0.16b, v0.16b, v2.16b
ext v2.16b, v1.16b, v1.16b, #8
ext v3.16b, v0.16b, v0.16b, #8
zip1 v1.16b, v1.16b, v2.16b
zip1 v0.16b, v0.16b, v3.16b
addv h1, v1.8h
addv h0, v0.8h
fmov w8, s1
fmov w0, s0
bfi w0, w8, #16, #16
ret

.LCPI2_0:
.byte 1
.byte 2
.byte 4
.byte 8
.byte 16
.byte 32
.byte 64
.byte 128
.byte 1
.byte 2
.byte 4
.byte 8
.byte 16
.byte 32
.byte 64
.byte 128
example[4d0fb39774ccf68c]::src64:
ldp q1, q0, [x0, #32]
adrp x8, .LCPI2_0
ldp q2, q3, [x0]
ldr q4, [x8, :lo12:.LCPI2_0]
cmeq v0.16b, v0.16b, #0
cmeq v1.16b, v1.16b, #0
cmeq v3.16b, v3.16b, #0
cmeq v2.16b, v2.16b, #0
and v0.16b, v0.16b, v4.16b
and v1.16b, v1.16b, v4.16b
and v3.16b, v3.16b, v4.16b
and v2.16b, v2.16b, v4.16b
ext v4.16b, v0.16b, v0.16b, #8
ext v5.16b, v1.16b, v1.16b, #8
ext v6.16b, v3.16b, v3.16b, #8
ext v7.16b, v2.16b, v2.16b, #8
zip1 v0.16b, v0.16b, v4.16b
zip1 v1.16b, v1.16b, v5.16b
zip1 v3.16b, v3.16b, v6.16b
zip1 v2.16b, v2.16b, v7.16b
addv h0, v0.8h
addv h1, v1.8h
addv h3, v3.8h
addv h2, v2.8h
fmov w8, s0
fmov w9, s1
fmov w10, s3
fmov w11, s2
bfi w9, w8, #16, #16
bfi w11, w10, #16, #16
orr x0, x11, x9, lsl #32
ret

.LCPI3_0:
.byte 1
.byte 2
.byte 4
.byte 8
.byte 16
.byte 32
.byte 64
.byte 128
.byte 1
.byte 2
.byte 4
.byte 8
.byte 16
.byte 32
.byte 64
.byte 128
example[4d0fb39774ccf68c]::tgt16:
ldr q0, [x0]
adrp x8, .LCPI3_0
ldr q1, [x8, :lo12:.LCPI3_0]
cmeq v0.16b, v0.16b, #0
and v0.16b, v0.16b, v1.16b
addp v0.16b, v0.16b, v0.16b
addp v0.16b, v0.16b, v0.16b
addp v0.16b, v0.16b, v0.16b
umov w0, v0.h[0]
ret

.LCPI4_0:
.byte 1
.byte 2
.byte 4
.byte 8
.byte 16
.byte 32
.byte 64
.byte 128
.byte 1
.byte 2
.byte 4
.byte 8
.byte 16
.byte 32
.byte 64
.byte 128
example[4d0fb39774ccf68c]::tgt32:
ldp q0, q1, [x0]
adrp x8, .LCPI4_0
ldr q2, [x8, :lo12:.LCPI4_0]
cmeq v1.16b, v1.16b, #0
cmeq v0.16b, v0.16b, #0
and v0.16b, v0.16b, v2.16b
and v1.16b, v1.16b, v2.16b
addp v0.16b, v0.16b, v1.16b
addp v0.16b, v0.16b, v0.16b
addp v0.16b, v0.16b, v0.16b
fmov w0, s0
ret

.LCPI5_0:
.byte 1
.byte 2
.byte 4
.byte 8
.byte 16
.byte 32
.byte 64
.byte 128
.byte 1
.byte 2
.byte 4
.byte 8
.byte 16
.byte 32
.byte 64
.byte 128
example[4d0fb39774ccf68c]::tgt64:
ldp q0, q1, [x0]
adrp x8, .LCPI5_0
ldp q2, q3, [x0, #32]
ldr q4, [x8, :lo12:.LCPI5_0]
cmeq v0.16b, v0.16b, #0
cmeq v1.16b, v1.16b, #0
cmeq v3.16b, v3.16b, #0
cmeq v2.16b, v2.16b, #0
and v0.16b, v0.16b, v4.16b
and v1.16b, v1.16b, v4.16b
and v2.16b, v2.16b, v4.16b
and v3.16b, v3.16b, v4.16b
addp v0.16b, v0.16b, v1.16b
addp v1.16b, v2.16b, v3.16b
addp v0.16b, v0.16b, v1.16b
addp v0.16b, v0.16b, v0.16b
fmov x0, d0
ret
```

Contributor guide

Open the contributing guide

Research direction

Start in the AArch64 backend by locating the lowering for bitcast to iN, then compare its current ext/zip1/addv sequences with the addp chains shown in the linked Godbolt example. Done means the 16-, 32-, and 64-byte cases produce the target instruction patterns without the current extra operations.

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
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.