https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128550
Bug ID: 128550
Summary: wrong code with svabal and a zero accumulator
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: yuki.tanaka at defaultcase dot de
Target Milestone: ---
#include <arm_sve.h>
#include <stdint.h>
__attribute__((noipa)) svint16_t a(svint8_t b, svint8_t c)
{
return svabal_s16(svdup_s16(0), b, c);
}
__attribute__((noipa)) svuint32_t b(svuint16_t c, svuint16_t d)
{
return svabal_u32(svdup_u32(0), c, d);
}
int main(void)
{
svbool_t pg16 = svptrue_b16();
svint16_t r16 = a(svdup_s8(1), svdup_s8(1));
if (svptest_any(pg16, svcmpne_n_s16(pg16, r16, 0)))
__builtin_abort();
svbool_t pg32 = svptrue_b32();
svuint32_t r32 = b(svdup_u16(1), svdup_u16(1));
if (svptest_any(pg32, svcmpne_n_u32(pg32, r32, 0)))
__builtin_abort();
return 0;
}
Both functions must return 0 in every element, since the accumulator is zero
and both input vectors are equal. Instead GCC uses the first input as the
accumulator, giving 257 (0x0101) in a and 65537 (0x00010001) in b, so main
would abort. This happens at -O1, -O2 and -O3 with -march=armv9-a+sve2p3, -O0
is fine.
Compiler Explorer:
https://godbolt.org/z/Yf3er4szG
GCC 17 at -O1, -O2 and -O3:
a:
sabal z0.h, z0.b, z1.b
ret
b:
uabal z0.s, z0.h, z1.h
ret