2

We've got some code that runs on multiple platforms. The code uses BMI/BMI2 intrinsics when available, like a Core i7 5th gen. GCC supplied by Sun on Solaris 11.3 is defining __BMI__ and __BMI2__, but its having trouble locating BMI/BMI2 intrinsics:

$ cat test.cxx
#include <x86intrin.h>
int main(int argc, char* argv[])
{
  unsigned long long t = argc;
#if defined(__BMI__) || defined(__BMI2__)
  t = _blsr_u64(t);
#endif
  return int(t);
}

$ /bin/g++ -march=native test.cxx -o test.exe
test.cxx: In function ‘int main(int, char**)’:
test.cxx:6:18: error: ‘_blsr_u64’ was not declared in this scope
   t = _blsr_u64(t);
                  ^

Including immintrin.h does not make a difference.

Which header do we include for _blsr_u64 when using GCC on Solaris 11.3?


Here are the relevant defines from GCC:

$ /bin/g++ -march=native -dM -E - < /dev/null | sort | \
  /usr/gnu/bin/egrep -i '(sse|aes|rdrnd|rdseed|avx|bmi)'
#define __AES__ 1
#define __AVX__ 1
#define __AVX2__ 1
#define __BMI__ 1
#define __BMI2__ 1
#define __core_avx2 1
#define __core_avx2__ 1
#define __RDRND__ 1
#define __RDSEED__ 1
#define __SSE__ 1
#define __SSE2__ 1
#define __SSE3__ 1
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSSE3__ 1
#define __tune_core_avx2__ 1

And CPU features:

$ isainfo -v
64-bit amd64 applications
        avx xsave pclmulqdq aes movbe sse4.2 sse4.1 ssse3 amd_lzcnt popcnt tscp 
        ahf cx16 sse3 sse2 sse fxsr mmx cmov amd_sysc cx8 tsc fpu prfchw adx 
        rdseed efs rtm hle bmi2 avx2 bmi1 f16c fma rdrand 

And GCC version:

$ /bin/g++ --version
g++ (GCC) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
jww
  • 97,681
  • 90
  • 411
  • 885

1 Answers1

3

Which header do we include for _blsr_u64 when using GCC on Solaris 11.3?

It looks like #include <x86intrin.h> is correct.

The problem was the compiler invocation required both -march=native -m64 even though 64-bit is native for the machine and the kernel is 64-bit:

$ /bin/g++ -march=native -m64 test.cxx -o test.exe
jww
  • 97,681
  • 90
  • 411
  • 885
  • 1
    *even though 64-bit is native for the machine and the kernel is 64-bit:* ["Native mode" on Solaris is 32-bit](https://docs.oracle.com/cd/E60778_01/html/E60745/bjapr.html#OSSCGgewif). – Andrew Henle Jul 20 '16 at 12:21
  • 1
    `-march=native` never affects -m32 vs. -m64 vs. -mx32. That would be really inconvenient if an optimization option could break your 32bit build (e.g. by making a 64bit .o that wouldn't link with your other object files that were 32bit) It just enables instruction-set extensions within the target ISA (and sets `-mtune`) – Peter Cordes Jul 21 '16 at 08:22