problem _Float16 na i686

Jan Palus atler at pld-linux.org
Tue Sep 20 13:11:29 CEST 2022


On 20.09.2022 09:27, Krzysztof Mrozowicz via pld-devel-pl wrote:
> Cześć,
> próbuję skompilować FileZillę i na th-i686 dostaję następujący błąd:
> 
> /usr/lib/gcc/i686-pld-linux/12.2.0/include/avx512fp16vlintrin.h:3194:17: error: '_Float16' is not supported on this target
>  3194 | extern __inline _Float16
>       |                 ^~~~~~~~
> /usr/lib/gcc/i686-pld-linux/12.2.0/include/avx512fp16vlintrin.h: In function '_mm256_reduce_max_ph':
> /usr/lib/gcc/i686-pld-linux/12.2.0/include/avx512fp16vlintrin.h:3198:3: error: '__builtin_shuffle' number of elements of the argument vector(s) and the mask vector should be the same
> 
> Google podpowiedziało mi podobny problem w Mageii, zgłoszony do
> FileZilli, ale wątek zamknięto wskazując na problem z kompilatorem.
> 
> https://trac.filezilla-project.org/ticket/12740
> 
> Czy ktoś mógłby rzucić okiem?

Z góry zaznaczam że o wektorowych instrukcjach wiem w zasadzie prawie
nic, więc jeżeli ktoś lepiej obeznany ma inną opinię to zapewne ma
rację.

Błąd pochodzi z pliku sshsh256.c, który oprócz programowej obsługi
SHA256 zawiera również implementacje zoptymalizowane pod konkretne
architektury i ich rozszerzenia. W przypadku x86 takim rozszerzeniem
zdaje się być SSE4.1/SHA, które nie jest dostępne w standardowym zbiorze
instrukcji z jakim kompilujemy pakiety i686. FileZilla, czy konkretniej
putty bo stąd pochodzi ten plik źródłowy, używa mechanizmów kompilatora,
żeby pomimo kompilacji dla i686 użyć rozszerzeń SSE4.1/SHA, ale wykrywa
ich dostępność w czasie wykonania.

Wspomniane wyżej "mechanizmy kompilatora" zdają się być przyczyną
problemu. putty używa do tego atrybutów funkcji, które dodają możliwość
użycia wyżej wymienionych rozszerzeń w konkretnej funkcji:

    #    define FUNC_ISA __attribute__ ((target("sse4.1,sha")))
    
    ...
    
    FUNC_ISA
    static inline void sha256_ni_block(__m128i *core, const uint8_t *p)

To jest jak najbardziej ok i w zasadzie powinno wystarczyć. Natomiast z
niewiadomych powodów (historycznych? wsparcie starszych wersji gcc?)
robi dodatkowo to:

    #    pragma GCC target("sha")
    #    pragma GCC target("sse4.1")

Co oznacza, że każda funkcja zdefiniowana po tych dyrektywach będzie
oznaczona wyżej wymienionymi atrybutami. Nie byłoby może w tym nic złego
gdyby nie było to zdefiniowane przed dołączaniem nagłówków *intrin.h,
które ewidentnie nie są z tego faktu zadowolone.

Najlepiej byłoby gdyby implementacje używające rozszerzeń były
przeniesione do osobnych plików, np w przypadku x86 do sshsh256-ni.c i
były kompilowane z dodatkowymi flagami typu -msse4.1 -msha. Na to raczej
liczyć nie można.

Najłatwiej byłoby usunąć te pragmy skoro funkcje które używają
rozszerzeń są odpowiednio oznaczone przez FUNC_ISA. Przy czym najlepiej
zrobić to we wszystkich plikach które używają tego mechanizmu (sshaes.c
sshsh256.c sshsha.c).

Ostatnim rozwiązaniem jest wymuszenie obsługi programowej dla i686 i
ominięcie całego problemu, w tym konkretnym wypadku należałoby dopisać
do CFLAGS: -D_FORCE_SOFTWARE_SHA. Wielkiej straty nie będzie --
najstarsze procesory wspierające SHA zdają się być z 2016 roku. Raczej
wątpliwe, że ktoś nadal używa 32-bitowych buildów na takich maszynach,
ale nie jest to niemożliwe.


More information about the pld-devel-pl mailing list