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

Vector extensions not handled correctly for >>=, <<= operators

nemequ
New Contributor I
1,076 Views

I noticed a small issue with icc's support for GCC vector extensions: the >>= and <<= operators seem to be broken.

Here is a quick example (or, on Compiler Explorer if you prefer):

#include <stdint.h>

typedef int32_t vec __attribute__((__vector_size__(16)));

vec se(vec a) {
#if defined(CONFUSE_ICC)
  a >>= 31;
#else
  a = a >> 31;
#endif

  return a;
}

If you define CONFUSE_ICC, that will result in something like

foo.c(7): error: expression must have integral or unscoped enum type
    a >>= 31;
    ^

compilation aborted for foo.c (code 2)
Compiler returned: 2

As you can see, the workaround is straightforward enough, I just thought I should report the bug.

0 Kudos
5 Replies
nemequ
New Contributor I
1,076 Views

I noticed that ICC actually generates the wrong result for the workaround, too.  It shifts in zeros instead of sign bits.  If you look at the example on Compiler Explorer you'll notice that ICC generates a vpsrld instead of a vpsrad.  That's a bigger problem since there is no easy workaround.

In this case, I'm just trying to extend the sign bit over the entire lane, so my I could just use < 0 instead:

a = (a < 0);

Again, this works in GCC and clang.  Both compilers are actually smart enough to optimize it to a psrad anyways, so I wouldn't even need a special path for ICC.  Unfortunately, if I change the type from int32_t to int16_t ICC starts having problems again.  I can get it to work by shifting by a vector of all zeros instead of a scalar.  Here is an example:

#include <stdint.h>
#include <stddef.h>
#include <inttypes.h>
#include <stdio.h>

typedef int16_t vec __attribute__((__vector_size__(16)));

vec sign_extend(vec a) {
#if MAKE_ICC_WORK
  vec z = { 0, 0, 0, 0, 0, 0, 0, 0 };
  return a < z;
#else
  return a < 0;
#endif
}

#if 1
int main(void) {
  vec mask = {
       1, -2
    ,  3, -4
    ,  5, -6,  7, -8
  };
  vec m = sign_extend(mask);

  for (size_t i = 0 ; i < (sizeof(mask) / sizeof(mask[0])) ; i++) {
    printf("%2zu: %3" PRId16 " -> %3" PRId16 "   %s\n", i, mask, m,
	   (((mask < 0) * -1) != m) ? "<-" : "");
  }

  return 0;
}
#endif

Several of the elements (which ones change from run to run) often don't work correctly unless I define MAKE_ICC_WORK.

This is with ICC 19.1 20200117 on Fedora 31 x86_64.

0 Kudos
RahulV_intel
Moderator
1,076 Views

Hi Evan,

We are able to reproduce this issue. Thanks for reporting this. We will inform this to the concerned team and we'll get back to you at the earliest.

 

--Rahul

0 Kudos
Viet_H_Intel
Moderator
1,076 Views

I've reported these bugs to our Developers. Thanks for providing us these test cases.

0 Kudos
Viet_H_Intel
Moderator
986 Views

Can you try out PSXE2020 update 4 to see if your issue has been resolved?


Thanks,



0 Kudos
Viet_H_Intel
Moderator
981 Views

This issue has been fixed in OneAPI HPC toolkit. We will no longer respond to this thread.  


If you require additional assistance from Intel, please start a new thread. Any further interaction in this thread will be considered community only.


Thanks,


0 Kudos
Reply