Bug 109504 - [12/13/14 Regression] Compilation fails with pragma GCC target sse4.1 and immintrin.h
Summary: [12/13/14 Regression] Compilation fails with pragma GCC target sse4.1 and imm...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 12.2.0
: P3 normal
Target Milestone: 12.4
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2023-04-13 18:58 UTC by GKraats
Modified: 2023-11-30 10:52 UTC (History)
3 users (show)

See Also:
Host:
Target: i686-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description GKraats 2023-04-13 18:58:00 UTC
Problem occurs at Debian Bookworm (Testing) i686 (32 bit).
debian:~$ cat test.c
#pragma GCC target("sse4.1")
#include <immintrin.h>
int main(){return 0;}

debian:~$ gcc -v test.c 2>&1 | head -100
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/12/lto-wrapper
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-pkgversion=&apos;Debian 12.2.0-14&apos; --with-bugurl=<span style="color:#C01C28">file:///usr/share/doc/gcc-12/README.Bugs</span> --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-12 --program-prefix=i686-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-targets=all --enable-multiarch --disable-werror --with-arch-32=i686 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.2.0 (Debian 12.2.0-14)
COLLECT_GCC_OPTIONS=&apos;-v&apos; &apos;-mtune=generic&apos; &apos;-march=i686&apos; &apos;-dumpdir&apos; &apos;a-&apos;
 /usr/lib/gcc/i686-linux-gnu/12/cc1 -quiet -v -imultiarch i386-linux-gnu test.c -quiet -dumpdir a- -dumpbase test.c -dumpbase-ext .c -mtune=generic -march=i686 -version -fasynchronous-unwind-tables -o /tmp/ccvTqsb4.s
GNU C17 (Debian 12.2.0-14) version 12.2.0 (i686-linux-gnu)
        compiled by GNU C version 12.2.0, GMP version 6.2.1, MPFR version 4.1.1-p1, MPC version 1.3.1, isl version isl-0.25-GMP

warning: MPFR header version 4.1.1-p1 differs from library version 4.2.0.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory &quot;/usr/local/include/i386-linux-gnu&quot;
ignoring nonexistent directory &quot;/usr/lib/gcc/i686-linux-gnu/12/include-fixed&quot;
ignoring nonexistent directory &quot;/usr/lib/gcc/i686-linux-gnu/12/../../../../i686-linux-gnu/include&quot;
#include &quot;...&quot; search starts here:
#include &lt;...&gt; search starts here:
 /usr/lib/gcc/i686-linux-gnu/12/include
 /usr/local/include
 /usr/include/i386-linux-gnu
 /usr/include
End of search list.
GNU C17 (Debian 12.2.0-14) version 12.2.0 (i686-linux-gnu)
        compiled by GNU C version 12.2.0, GMP version 6.2.1, MPFR version 4.1.1-p1, MPC version 1.3.1, isl version isl-0.25-GMP

warning: MPFR header version 4.1.1-p1 differs from library version 4.2.0.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: e1e0efc2c04a9ab28e35cf4254d1a7fe
In file included from /usr/lib/gcc/i686-linux-gnu/12/include/immintrin.h:98,
                 from test.c:2:
/usr/lib/gcc/i686-linux-gnu/12/include/avx512fp16intrin.h:38:9: error: ‘_Float16’ is not supported on this target
   38 | typedef _Float16 __v8hf __attribute__ ((__vector_size__ (16)));

This error should not be given.The current target  should be sse4.1,
because of the pragma. The error makes cross-compiling with a low target
machine (i686 in this case) not workable.

The  error only occurs at gcc-12, not at gcc-11. So this seeems to be
regression. The error disappears if compiling with option -msse2.

This error caused filezilla not being delivered anymore at latest upgrade of
Debian Bookworm.
I wrote bug-request https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1034195 .

This problem was noticed before at Debian. But Debian blaimed Filezilla,
and Filezila blaimed Debian/GCC, because nothing was changed in this
area since previous release.
See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1020327 and
https://trac.filezilla-project.org/ticket/12777 .
Comment 1 Andrew Pinski 2023-04-13 21:30:58 UTC
testcae:
```
#pragma GCC target("sse4.1")
#include <immintrin.h>
int main(){return 0;}
```

Works on x86_64-linux-gnu with `-m32 -march=i686  -mno-sse`
Comment 2 Hongtao.liu 2023-04-14 06:32:04 UTC
_Float16 is supportted with target sse2, that's why it report an error.
It looks like you want to use just gpr intrinsics, for that case, x86gprintrin.h can be used.
Comment 3 Hongtao.liu 2023-04-14 07:32:52 UTC
From pr108883, maybe we shouldnot restrict _Float16 under TARGET_SSE2.

Jakub Jelinek 2023-02-22 12:21:24 UTC
Created attachment 54506 [details]
gcc13-pr108883.patch

Untested fix on the compiler side of emit_support_tinfos.

That said, these fundamental types whose presence/absence depends on ISA flags
are quite problematic IMHO, as they are incompatible with the target attribute/pragmas.  Whether they are available or not available depends on whether in this case SSE2 is enabled during compiler initialization (aka after
parsing command line options) and then they are available or unavailable to
everything else based on that.
Comment 4 Jakub Jelinek 2023-04-14 08:01:32 UTC
Yeah.  Enable all the time and have say the
targetm.invalid_conversion, targetm.invalid_unary_op, targetm.invalid_binary_op
and something in argument/return value passing reject _Float16/__bf16 in functions without SSE2.
That will not be enough though, we'll need to arrange e.g. for the spot where we #undef/#define target  macros based on currently active ISA in pragmas to also
do that for __STDCPP_FLOAT16_T__ and __STDCPP_BFLOAT16_T__ for C++, and change libstdc++
such that for x86 it adds similarly to x86 intrin headers something like
#ifndef __SSE2__
#pragma GCC push_options
#pragma GCC target("sse2")
#define __DISABLE_SSE2__
#endif /* __SSE2__ */
...
#ifdef __DISABLE_SSE2__
#undef __DISABLE_SSE2__
#pragma GCC pop_options
#endif /* __DISABLE_SSE2__ */
around std::float16_t/std::bfloat16_t stuff.
Definitely not stage4 material I'm afraid.
Comment 5 Jakub Jelinek 2023-04-14 08:17:40 UTC
Note, until then we could perhaps do something like:
--- gcc/config/i386/avx512fp16intrin.h.jj	2023-01-16 11:52:15.946736083 +0100
+++ gcc/config/i386/avx512fp16intrin.h	2023-04-14 10:13:30.054297659 +0200
@@ -28,6 +28,8 @@
 #ifndef __AVX512FP16INTRIN_H_INCLUDED
 #define __AVX512FP16INTRIN_H_INCLUDED
 
+#ifdef __FLT16_DIG__
+
 #ifndef __AVX512FP16__
 #pragma GCC push_options
 #pragma GCC target("avx512fp16")
@@ -7216,4 +7218,6 @@ _mm512_set1_pch (_Float16 _Complex __A)
 #pragma GCC pop_options
 #endif /* __DISABLE_AVX512FP16__ */
 
+#endif
+
 #endif /* __AVX512FP16INTRIN_H_INCLUDED */
--- gcc/config/i386/avx512fp16vlintrin.h.jj	2023-01-16 11:52:15.946736083 +0100
+++ gcc/config/i386/avx512fp16vlintrin.h	2023-04-14 10:13:54.152946427 +0200
@@ -28,6 +28,8 @@
 #ifndef __AVX512FP16VLINTRIN_H_INCLUDED
 #define __AVX512FP16VLINTRIN_H_INCLUDED
 
+#ifdef __FLT16_DIG__
+
 #if !defined(__AVX512VL__) || !defined(__AVX512FP16__)
 #pragma GCC push_options
 #pragma GCC target("avx512fp16,avx512vl")
@@ -3359,4 +3361,6 @@ _mm_set1_pch (_Float16 _Complex __A)
 #pragma GCC pop_options
 #endif /* __DISABLE_AVX512FP16VL__ */
 
+#endif
+
 #endif /* __AVX512FP16VLINTRIN_H_INCLUDED */
--- gcc/config/i386/avxneconvertintrin.h.jj	2023-01-16 11:52:15.949736039 +0100
+++ gcc/config/i386/avxneconvertintrin.h	2023-04-14 10:14:51.280113813 +0200
@@ -48,6 +48,7 @@ _mm256_bcstnebf16_ps (const void *__P)
   return (__m256) __builtin_ia32_vbcstnebf162ps256 ((const __bf16 *) __P);
 }
 
+#ifdef __FLT16_DIG__
 extern __inline __m128
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
 _mm_bcstnesh_ps (const void *__P)
@@ -61,6 +62,7 @@ _mm256_bcstnesh_ps (const void *__P)
 {
   return (__m256) __builtin_ia32_vbcstnesh2ps256 ((const _Float16 *) __P);
 }
+#endif
 
 extern __inline __m128
 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))

i.e. if _Float16 type isn't usable, just hide all the _Float16 related stuff from the headers.
But don't we need the same thing for __bf16 too?  There I'm afraid aren't macros for that.
Comment 6 Hongtao.liu 2023-04-17 06:37:41 UTC
(In reply to Jakub Jelinek from comment #4)
> Yeah.  Enable all the time and have say the
> targetm.invalid_conversion, targetm.invalid_unary_op,
> targetm.invalid_binary_op
> and something in argument/return value passing reject _Float16/__bf16 in
> functions without SSE2.
> That will not be enough though, we'll need to arrange e.g. for the spot
> where we #undef/#define target  macros based on currently active ISA in
> pragmas to also
> do that for __STDCPP_FLOAT16_T__ and __STDCPP_BFLOAT16_T__ for C++, and
> change libstdc++
> such that for x86 it adds similarly to x86 intrin headers something like
Can we just cpp_undef _STDCPP_FLOAT16_T__ and __STDCPP_BFLOAT16_T__ for C++ in ix86_target_macros when !TARGET_SSE2 so that no need to change libstdc++ part.
Comment 7 Hongtao.liu 2023-04-18 06:39:31 UTC
(In reply to Hongtao.liu from comment #6)
> (In reply to Jakub Jelinek from comment #4)
> > Yeah.  Enable all the time and have say the
> > targetm.invalid_conversion, targetm.invalid_unary_op,
> > targetm.invalid_binary_op
> > and something in argument/return value passing reject _Float16/__bf16 in
> > functions without SSE2.
> > That will not be enough though, we'll need to arrange e.g. for the spot
> > where we #undef/#define target  macros based on currently active ISA in
> > pragmas to also
> > do that for __STDCPP_FLOAT16_T__ and __STDCPP_BFLOAT16_T__ for C++, and
> > change libstdc++
> > such that for x86 it adds similarly to x86 intrin headers something like
> Can we just cpp_undef _STDCPP_FLOAT16_T__ and __STDCPP_BFLOAT16_T__ for C++
> in ix86_target_macros when !TARGET_SSE2 so that no need to change libstdc++
> part.

Also need to undef
__LIBGCC_HAS_%d_MODE__, __LIBGCC_%d_FUNC_EXT__,__LIBGCC_%d_MANT_DIG__, __LIBGCC_%d_EXCESS_PRECISION__, __LIBGCC_%d_EPSILON__, __LIBGCC_%d_MAX__, __LIBGCC_%d_MIN__

Which are used for building libgcc(found in libbid)

And then ix86_emit_support_tinfos is not needed any more since type is always supported?

Or just adjust to

-      gcc_checking_assert (!float16_type_node && !bfloat16_type_node);
-      float16_type_node = ix86_float16_type_node;
-      bfloat16_type_node = ix86_bf16_type_node;
+      float16_type_node
+       = float16_type_node ? float16_type_node : ix86_float16_type_node;
+      bfloat16_type_node
+       = bfloat16_type_node ? bfloat16_type_node : ix86_bf16_type_node;
Comment 8 Richard Biener 2023-05-08 12:26:59 UTC
GCC 12.3 is being released, retargeting bugs to GCC 12.4.
Comment 9 GCC Commits 2023-07-19 01:36:11 UTC
The master branch has been updated by hongtao Liu <liuhongt@gcc.gnu.org>:

https://gcc.gnu.org/g:9a19fa8b616f83474c35cc5b34a3865073ced829

commit r14-2628-g9a19fa8b616f83474c35cc5b34a3865073ced829
Author: liuhongt <hongtao.liu@intel.com>
Date:   Tue Apr 18 14:53:04 2023 +0800

    Support type _Float16/__bf16 independent of SSE2.
    
    Enable _Float16 and __bf16 all the time but issue errors when the
    types are used in conversion, unary operation, binary operation,
    parameter passing or value return when TARGET_SSE2 is not available.
    
    Also undef macros which are used by libgcc/libstdc++ to check the
    backend support of the _Float16/__bf16 types when TARGET_SSE2 is not
    available.
    
    gcc/ChangeLog:
    
            PR target/109504
            * config/i386/i386-builtins.cc
            (ix86_register_float16_builtin_type): Remove TARGET_SSE2.
            (ix86_register_bf16_builtin_type): Ditto.
            * config/i386/i386-c.cc (ix86_target_macros): When TARGET_SSE2
            isn't available, undef the macros which are used to check the
            backend support of the _Float16/__bf16 types when building
            libstdc++ and libgcc.
            * config/i386/i386.cc (construct_container): Issue errors for
            HFmode/BFmode when TARGET_SSE2 is not available.
            (function_value_32): Ditto.
            (ix86_scalar_mode_supported_p): Remove TARGET_SSE2 for HFmode/BFmode.
            (ix86_libgcc_floating_mode_supported_p): Ditto.
            (ix86_emit_support_tinfos): Adjust codes.
            (ix86_invalid_conversion): Return diagnostic message string
            when there's conversion from/to BF/HFmode w/o TARGET_SSE2.
            (ix86_invalid_unary_op): New function.
            (ix86_invalid_binary_op): Ditto.
            (TARGET_INVALID_UNARY_OP): Define.
            (TARGET_INVALID_BINARY_OP): Define.
            * config/i386/immintrin.h [__SSE2__]: Remove for fp16/bf16
            related instrinsics header files.
            * config/i386/i386.h (VALID_SSE2_TYPE_MODE): New macro.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/i386/pr109504.c: New test.
            * gcc.target/i386/sse2-bfloat16-1.c: Adjust error info.
            * gcc.target/i386/sse2-float16-1.c: Ditto.
            * gcc.target/i386/sse2-float16-4.c: New test.
            * gcc.target/i386/sse2-float16-5.c: New test.
            * g++.target/i386/float16-1.C: Adjust error info.
    
    libgcc/ChangeLog:
    
            * config/i386/t-softfp: Add -msse2 to libbid HFtype related
            files.
Comment 10 Hongtao.liu 2023-07-19 06:48:30 UTC
Fixed in GCC14.
Comment 11 liuhongt 2023-11-30 10:52:33 UTC
.