https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109332
Bug ID: 109332
Summary: Bug in gcc (13.0.1) support for ARM SVE, which
randomly ignore the predict register
Product: gcc
Version: 13.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: wumingchuan1992 at foxmail dot com
Target Milestone: ---
func_demo.c
#include <stdio.h>
#include <arm_sve.h>
#define VML_SVE_DOUBLE_SIGN_BIT svdup_n_u64(0x8000000000000000ULL)
svfloat64_t func_demo(svbool_t pg, svfloat64_t x, svbool_t cmpBig)
{
svuint64_t ux = svreinterpret_u64_f64(x);
svuint64_t sn = svand_u64_x(pg, ux, VML_SVE_DOUBLE_SIGN_BIT);
svint64_t isn = svreinterpret_s64_u64(sn);
svfloat64_t res = svcvt_f64_s64_x(pg, svsub_n_s64_x(cmpBig, isn, 0x4LL));
return res;
}
Run gcc(10.3.0 and 13.0.1 20230327) with the following command:
$ gcc -std=c99 -O2 -funroll-loops -march=armv8.3-a+fp+sve -o func_demo.o -c
func_demo.c
After objdump, the result is as follows:
0000000000000000 <func_demo>:
0: 05820800 and z0.d, z0.d, #0x8000000000000000
4: 25e1c080 sub z0.d, z0.d, #4
8: 65d6a000 scvtf z0.d, p0/m, z0.d
c: d65f03c0 ret
It can be seen that the predict register is ignored during the sub operation,
and the action similar to svptrue_b64() is used.
For comparison, use llvm for compilation:
$ clang -std=c99 -O2 -funroll-loops -march=armv8.3-a+fp+sve -o func_demo.o -c
func_demo.c
the result is as follows:
0000000000000000 <func_demo>:
0: 05c20801 mov z1.d, #0x8000000000000000
4: 04da0020 and z0.d, p0/m, z0.d, z1.d
8: 25f8c081 mov z1.d, #4
c: 04c10420 sub z0.d, p1/m, z0.d, z1.d
10: 65d6a000 scvtf z0.d, p0/m, z0.d
14: d65f03c0 ret
The sub operation is correct.
Any suggestions to proceed?