Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
Announcements
The Intel sign-in experience has changed to support enhanced security controls. If you sign in, click here for more information.
7782 Discussions

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

nemequ
New Contributor I
681 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
681 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.

RahulV_intel
Moderator
681 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

Viet_H_Intel
Moderator
681 Views

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

Viet_H_Intel
Moderator
591 Views

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


Thanks,



Viet_H_Intel
Moderator
586 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,


Reply