https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126351
Bug ID: 126351
Summary: Suboptimal aarch64 expansion for crc8 with +aes
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: ktkachov at gcc dot gnu.org
Target Milestone: ---
For input C:
#include <stdint.h>
uint16_t
crc_u8 (uint8_t data, uint16_t crc)
{
uint8_t i, x16, carry = 0;
for (i = 0; i < 8; i++)
{
x16 = (uint8_t)((data & 1) ^ ((uint8_t)crc & 1));
data >>= 1;
if (x16)
{
crc ^= 0x4002;
carry = 1;
}
else
carry = 0;
crc >>= 1;
if (carry)
crc |= 0x8000;
else
crc &= 0x7fff;
}
return crc;
}
aarch64 GCC with -O3 -march=armv9-a+aes generates:
crc_u8:
and x0, x0, 255
and x2, x1, 65535
mov w3, 49151
eor w2, w2, w0
movk x3, 0x1, lsl 16
fmov d31, x2
fmov d30, x3
mov w0, 512
movk x0, 0x140, lsl 16
ubfx w1, w1, 8, 8
pmull v30.1q, v31.1d, v30.1d
fmov d31, x0
and z30.d, z30.d, #255
pmull v30.1q, v30.1d, v31.1d
umov w0, v30.h[1]
eor w0, w1, w0
ret
but without aes we get a simpler, faster sequence for all aarch64 processors
(IMO). -O3 -march=armv9-a (no +aes):
crc_u8:
and w1, w1, 65535
adrp x3, .LC0
eor w2, w1, w0
add x3, x3, :lo12:.LC0
ubfiz x2, x2, 1, 8
ldrh w0, [x3, x2]
eor w0, w0, w1, lsr 8
ret
.LC0:
.hword 0
.hword -16191
.hword -15999
....
Arguably for -Os optimisation the pmull sequence is better as the lookup table
for no-aes is quite large, but for speed optimisation I don't see how the
scalar version could be worse