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?
  • [Bug target/109332] New: B... wumingchuan1992 at foxmail dot com via Gcc-bugs

Reply via email to