Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

__builtin_shuffle, GCC compatibility, and __has_builtin

nemequ
New Contributor I
2,931 Views

I recently tried to build one of my projects (SIMDe) with ICC, and it failed due to __builtin_shuffle not being supported. There are ifdefs around the code in question which use __GNUC__ and __GNUC_MINOR__ to check for GCC ≥ 4.7 before using __builtin_shuffle, but ICC 18.0 masquerades as GCC 7 so the code was enabled.

I don't have any objection to ICC not supporting every feature GCC does, but masquerading as a version of GCC which supports something then not supporting it is quite frustrating. Clang has resolved this by simply only claiming to support the extensions provided by GCC 4.2, and added __has_builtin (among others) to check for support for specific builtins. Is there any hope of ICC adopting this method? Is there some other way to identify which features are actually present?

0 Kudos
8 Replies
nemequ
New Contributor I
2,931 Views

To further illustrate the problem, I just found another unimplemented feature: the fallthrough attribute:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

int main(int argc, char** argv) {
  assert(argc >= 2);

  switch (atoi(argv[1])) {
  case 0:
    printf("zero\n");
    __attribute__((__fallthrough__));
  case 1:
    printf("one\n");
    break;
  default:
    printf("default\n");
    break;
  }

  return 0;
}

Also, for C++, [[gnu::fallthrough]], which is like [[fallthrough]] but supported by GCC for C++11 and C++14 in addition to C++17.

0 Kudos
JenniferJ
Moderator
2,931 Views

The original post seems like a bug to me, but not able to duplicate. ICC set GCC 6.4 correctly for me. are you sure the gcc on the path is gcc 7? 

As for the attribute, not sure how commonly it is used.  

Could you submit tickets at Online Service Center linked from top of this forum? 

thanks,

Jennifer 

0 Kudos
nemequ
New Contributor I
2,931 Views

Jennifer J. (Intel) wrote:
The original post seems like a bug to me, but not able to duplicate. ICC set GCC 6.4 correctly for me. are you sure the gcc on the path is gcc 7?

It's a Fedora 27 system with GCC 7.3.1, ICC 18.0.1. GIven this shuffle.c:

#include <stdio.h>

typedef int v4si __attribute__ ((vector_size (16)));

int main(void) {
     v4si a = {1,2,3,4};
     v4si b = {5,6,7,8};
     v4si mask1 = {0,1,1,3};
     v4si mask2 = {0,4,2,5};
     v4si res;

#if defined(__GNUC__) && (__GNUC__ >= 7)
     res = __builtin_shuffle (a, mask1);       /* res is {1,2,2,4}  */
     res = __builtin_shuffle (a, b, mask2);    /* res is {1,5,3,6}  */

     printf("%d %d %d %d\n", res[0], res[1], res[2], res[3]);
#endif

     return 0;
}

Here is what I see:

nemequ@peltast:~/t$ gcc --version
gcc (GCC) 7.3.1 20180130 (Red Hat 7.3.1-2)
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

nemequ@peltast:~/t$ icc --version
icc (ICC) 18.0.1 20171018
Copyright (C) 1985-2017 Intel Corporation.  All rights reserved.

nemequ@peltast:~/t$ gcc -o shuffle shuffle.c && ./shuffle
1 5 3 6
nemequ@peltast:~/t$ icc -o shuffle shuffle.c && ./shuffle
shuffle.c(13): error: "__builtin_shuffle" is not supported
       res = __builtin_shuffle (a, mask1);       /* res is {1,2,2,4}  */
             ^

shuffle.c(14): error: "__builtin_shuffle" is not supported
       res = __builtin_shuffle (a, b, mask2);    /* res is {1,5,3,6}  */
             ^

compilation aborted for shuffle.c (code 2)

Note that it says __builtin_shuffle is not supported, *not* that it was declared implicitly; in other words, it seems like ICC has made a conscious decision not to support it, which is perfectly reasonable. Clang doesn't support it, either (though they do have a very similar __builtin_shufflevector), but they're not masquerading as GCC ≥ 4.7

Jennifer J. (Intel) wrote:
As for the attribute, not sure how commonly it is used.

The fallthrough attribute was just added with GCC 7, so it's probably not very common yet. Still, if ICC sets __GNUC__ to 7 it should be supported.

Could you submit tickets at Online Service Center linked from top of this forum?

I don't mind, but I don't see the link.. can you be a little more specific? Maybe it's missing because I have a free license (open source contributor)?

Anyways, this is more about asking about __has_* macros like clang has (and preferably not bumping __GNUC__/__GNUC_MINOR__/__GNUC_PATCHLEVEL__ beyond what ICC fully supports)… the fallthrough attribute seems like a bug, but not __builtin_shuffle. Should I submit both?

0 Kudos
JenniferJ
Moderator
2,931 Views

i know why now. gcc7 is not supported in 18.0 yet. although icc might work with it. 

this info is in the ReleaseNotes.

Link for submitting issue:  Priority Support

Jennifer 

0 Kudos
nemequ
New Contributor I
2,931 Views

Jennifer J. (Intel) wrote:
i know why now. gcc7 is not supported in 18.0 yet. although icc might work with it.

Okay, so that sort of answers the __attribute__((__fallthrough__)) issue, though the original __builtin_shuffle problem remains. To replace it, the target_clones attribute was added in GCC 6, but ICC doesn't support it. Here is a quick test case:

#include <stdlib.h>
#include <stdio.h>

#if defined(__GNUC__) && (__GNUC__ >= 6)
__attribute__((target_clones("sse4.1,avx,default")))
#endif
int foo (int x, int y) {
  return (x * x * x) + (y * y * y);
}

int main (void) {
  printf("%d\n", foo(9, 10));

  return EXIT_SUCCESS;
}

If I understand you correctly, ICC just defines __GNUC__/__GNUC_MINOR__/__GNUC_PATCHLEVEL__ to whatever is installed on the system, even if it doesn't actually support all the features from that release? That makes some sense, but it still presents a huge problem for portable code; we can't trust __GNUC__ etc. when __INTEL_COMPILER is defined.

If we can't trust __GNUC__ etc. I'm not sure how to determine which features are supported by different ICC versions. AFAICT Intel doesn't document which GNU extensions are supported for a particular version (I'd love to be corrected on that if I'm wrong). Barring that, perhaps there is a way to tell which versions of GCC are supported by different ICC versions (which should *mostly* correspond with which extensions are supported, though obviously there are exceptions like __builtin_shuffle and target_clones)? The release notes don't seem to be helpful for minor versions, and only 16 and 17 seem to mention which GCC versions are compatible…

I think it would be much more stable for ICC to take a page from clang, and just set __GNUC__ to an old version (clang currently uses 4.2.1) which the compiler really does fully support, then let people use __has_* to determine whether a feature is available. This is actually pretty convenient for the user, too, since they don't have to search through different versions of the manual to figure out when support was added for a feature. FWIW, suncc has adopted __has_attribute as well.

Jennifer J. (Intel) wrote:
Link for submitting issue:  Priority Support

Thanks. Should I submit issues about __builtin_shuffle and target_clones, but not fallthrough? Or the whole __GNUC__ etc. being untrustworthy thing? Or implementing __has_attribute/builtin/cpp_attribute/etc.?

0 Kudos
Bertagna__Luca
Beginner
2,932 Views

I stumbled on this page while looking for `fallthrough` support in the intel compilers. I am currently using intel 18.1 and 19.3, and in both cases I get the error

warning #1292: unknown attribute "fallthrough"

The page https://software.intel.com/en-us/articles/c17-features-supported-by-intel-c-compiler seems to suggest that it is supported in versions 18.0 and on though.

0 Kudos
dpeterc
Beginner
2,932 Views

I am on version icc (ICC) 19.1.0.166 20191121

and fallthrough attribute is still not supported, in spite of being supported according to this page (P0188R1)
https://software.intel.com/en-us/articles/c17-features-supported-by-intel-c-compiler

I am using C, not C++. Are there any special compile switches to enable this functionality? I use -std=c99.

The fallthrough attribute is supported in both gcc and clang, without any special compile switches.

0 Kudos
nemequ
New Contributor I
2,932 Views

That document is for C++17.  As of C17 C doesn't support the [[attribute]] syntax (though there is talk of adding it to the next version of the standard), so I'm guessing you're referring to __attribute__((__fallthrough__)), which GCC does support as an extension since 7.0.  Clang actually doesn't support that attribute, though it does support [[fallthrough]] in C++ mode.

ICC's GCC emulation is buggy, you shouldn't rely on it.  Unfortunately there isn't a great way to do that other than just making sure !defined(__INTEL_COMPILER) whenever you check __GNUC__/__GNUC_MINOR__/__GNUC_PATCHLEVEL__ (or create a macro which does it for you).  You can also make people pass -no-gcc to ICC, but that puts a burden on people using your code and can cause other problems.

IMHO the best thing to do here would be to just use Hedley, which handles all this stuff for you.  In this case, the HEDLEY_FALL_THROUGH macro should do the right thing.  It's a single public-domain header, should be trivial to add to any project.  That said, I'm heavily biased since I'm the one who wrote Hedley.

Barring that, you can try to reproduce what Hedley does in your code.  Specifically, if the compiler provides the __has_attribute macro then assume it is correct.  ICC does actually support __has_attribute, so all you need is something like:

#if defined(__has_attribute)
#  if __has_attribute(fallthrough)
#    define MY_FALLTHROUGH __attribute__((__fallthrough__))
#  else
#    define MY_FALLTHROUGH
#  endif
#else
#  define MY_FALLTHROUGH
#endif

Of course that doesn't also support C++ or SAL like Hedley does, but I don't feel like rewriting it here.

0 Kudos
Reply