Bug 26621

Summary: ICC Error when including tgmath.h on Ubuntu 20.04
Product: glibc Reporter: Ahmet <ahmet.akkas>
Component: mathAssignee: H.J. Lu <hjl.tools>
Status: RESOLVED INVALID    
Severity: normal    
Priority: P2    
Version: 2.33   
Target Milestone: 2.33   
Host: Target:
Build: Last reconfirmed: 2020-09-15 00:00:00
Attachments: A patch

Description Ahmet 2020-09-15 21:27:11 UTC
A simple code including tgmath.h cannot be compiled with icc (Intel C/C++ compiler) with Ubuntu 20.04 OS. To re-produce it, please compile the following code by running “icc -c test.c”
$ cat test.c
#include <tgmath.h>

$ icc -c test.c

Produces the following error:

/usr/include/tgmath.h(54): error: #error directive: "Unsupported combination of types for <tgmath.h>."
  #  error "Unsupported combination of types for <tgmath.h>."


I believe that the fix requires an update in floatn.h system file. Currently, __HAVE_FLOAT128 is set to zero for ICC with the following #if-defined:

#if (defined __x86_64__ \
     ? __GNUC_PREREQ (4, 3) \
     : (defined __GNU__ ? __GNUC_PREREQ (4, 5) : __GNUC_PREREQ (4, 4))) \
     && !defined(__CUDACC__) && !defined(__ICC)
# define __HAVE_FLOAT128 1
#else
# define __HAVE_FLOAT128 0
#endif

And then the "Unsupported combination of types for <tgmath.h>." error is produced from the following code in tgmath.h system header file (note that __HAVE_FLOAT64X is already set to 1 for ICC):

# if ((__HAVE_FLOAT64X && !__HAVE_FLOAT128) \
      || (__HAVE_FLOAT128 && !__HAVE_FLOAT64X))
# error "Unsupported combination of types for <tgmath.h>."
# endif


ICC compiler supports the __float128 type if the reference compiler is more recent than GNU version 4.4. Therefore, __HAVE_FLOAT128 should be set to 1 when ICC compiler is used with GNU version higher than 4.4. Based on this, I believe that the "&& !defined(__ICC)" part in the above #if-defined should be removed/updated.
Comment 1 H.J. Lu 2020-09-15 21:54:49 UTC
Created attachment 12843 [details]
A patch

Does ICC define __HAVE_FLOAT128?
Comment 2 H.J. Lu 2020-09-15 21:55:32 UTC
Does ICC define __SIZEOF_FLOAT128__?
Comment 3 H.J. Lu 2020-09-15 21:59:04 UTC
Both GCC and clang define __SIZEOF_FLOAT128__ to 16:

[hjl@gnu-cfl-1 glibc]$ echo __SIZEOF_FLOAT128__ | gcc -E -
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "<stdin>"
16
[hjl@gnu-cfl-1 glibc]$ echo __SIZEOF_FLOAT128__ | clang -E -
# 1 "<stdin>"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 341 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "<stdin>" 2
16
[hjl@gnu-cfl-1 glibc]$
Comment 4 jsm-csl@polyomino.org.uk 2020-09-15 22:05:39 UTC
The real question here is whether ICC supports any of the approaches used 
in glibc's tgmath.h to implement the type-generic macros, which involve 
various GCC extensions.  If it doesn't support them, the "#if 
__GNUC_PREREQ (2, 7)" would need to change to disallow ICC, or else a new 
implementation approach would need to be added.  If it does support them, 
then we get into ensuring the other macros regarding supported types are 
defined appropriately for the ICC case.
Comment 5 Ahmet 2020-09-15 23:02:34 UTC
(In reply to H.J. Lu from comment #2)
> Does ICC define __SIZEOF_FLOAT128__?

Yes.
# 1 "-"
# 1 "/usr/include/stdc-predef.h" 1 3

# 1 "-" 2
16
Comment 6 H.J. Lu 2020-09-15 23:15:48 UTC
(In reply to Ahmet from comment #5)
> (In reply to H.J. Lu from comment #2)
> > Does ICC define __SIZEOF_FLOAT128__?
> 
> Yes.
> # 1 "-"
> # 1 "/usr/include/stdc-predef.h" 1 3
> 
> # 1 "-" 2
> 16

Please apply my patch on /usr/include/bits/floatn.h to check if it
fixes your ICC problem.
Comment 7 Ahmet 2020-09-16 16:28:06 UTC
(In reply to joseph@codesourcery.com from comment #4)
> The real question here is whether ICC supports any of the approaches used 
> in glibc's tgmath.h to implement the type-generic macros, which involve 
> various GCC extensions.  If it doesn't support them, the "#if 
> __GNUC_PREREQ (2, 7)" would need to change to disallow ICC, or else a new 
> implementation approach would need to be added.  If it does support them, 
> then we get into ensuring the other macros regarding supported types are 
> defined appropriately for the ICC case.

We just found that Ubuntu's modified glibc header file caused the problem. In the (latest) glibc sources the following line does not exist

    &&  !defined(__CUDACC__) && !defined(__ICC)

so the code in glibc's header file looks like this:

#if (defined __x86_64__   \
    ? __GNUC_PREREQ (4, 3)\
    : (defined __GNU__ ? __GNUC_PREREQ (4, 5) : __GNUC_PREREQ (4, 4)))
# define __HAVE_FLOAT128 1
#else
# define __HAVE_FLOAT128 0
#endif
Comment 8 H.J. Lu 2020-09-16 16:35:25 UTC
Since the unmodified header file works with ICC, please report this bug
to Ubuntu.