https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106763

            Bug ID: 106763
           Summary: Armv8.2 vmov.f16 instruction sometimes causes SIGILL
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: georgepee at gmail dot com
  Target Milestone: ---

First noticed when going from gcc-10 to gcc-12 and a complex function being
compiled with -ftree-vectorize started to emit a vmov.f16 instruction and
sometimes SIGILL on it.

It appears that this commit is when it started to emit that instruction:
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=6390c5047adb75960f86d56582e6322aaa4d9281

Made a small program that also SIGILLs intermittently on vmov.f16 instruction 

Compiled with -g -mcpu=cortex-a55:

#include <vector>
#include <algorithm>
#include <arm_neon.h>
#include <stdio.h>
#include <sys/auxv.h>

float16_t rand_func()
{
    return float16_t(double(rand()) / double(RAND_MAX));
}

int main()
{
    srand( 11 );

    // just to show that vmov.f16 doesn't always SIGILL
    {
        std::vector<float16_t> floats_small(10);
        printf("float_small pre\n");
        std::generate( floats_small.begin() , floats_small.end() , rand_func );
        printf("float_small post\n");
    }

    // sometimes SIGILLS
    {
        std::vector<float16_t> floats_large(500000);
        printf("float_large pre\n");
        std::generate( floats_large.begin() , floats_large.end() , rand_func );
        printf("float_large post\n");
    }
    return 0;
}

Execution:
$ ./a.out
float_small pre
float_small post
float_large pre
float_large post

$ ./a.out
float_small pre
float_small post
float_large pre
Illegal instruction

GDB:
Program terminated with signal SIGILL, Illegal instruction.
#0  0x00010778 in rand_func () at vmov_f16_test.c:9
9           return float16_t(double(rand()) / double(RAND_MAX));
(gdb) disassemble 0x00010770,+32
Dump of assembler code from 0x10770 to 0x10790:
   0x00010770 <rand_func()+24>: vdiv.f64        d16, d17, d18
   0x00010774 <rand_func()+28>: vcvtb.f16.f64   s15, d16
=> 0x00010778 <rand_func()+32>: vmov.f16        r3, s15
   0x0001077c <rand_func()+36>: mov     r0, r3
   0x00010780 <rand_func()+40>: pop     {r11, pc}
   0x00010784 <rand_func()+44>: nop     {0}
   0x00010788 <rand_func()+48>:                 ; <UNDEFINED> instruction:
0xffc00000
   0x0001078c <rand_func()+52>: ldrshmi pc, [pc, #255]  ; 0x10893 <main()+258> 
; <UNPREDICTABLE>


I have been able to run the compiled program on multiple Cortex-A55 devices. 
Initially, I though that since FP16 is optional on armv8.2-a that it was truly
an illegal instruction, but if that is the case, then why would it only fail
intermittently?

Reply via email to