使用-mpopcnt进行编译会导致非法指令错误

时间:2015-03-03 01:06:02

标签: c++ linux g++

我编译以下C ++代码

// main.cpp
#include <cstdio>

int main() {
  unsigned char tab[4] = {0};
  printf("%d\n", __builtin_popcount(*((int *)tab)));
}

使用命令行:

g++ -o prog main.cpp -mpopcnt

当我运行程序时,我收到错误:

Illegal instruction

不使用-mpopcnt进行编译不会产生错误(只打印0)。

问题:导致此错误的原因是什么?

我正在同一台机器上编译和运行程序。 Valgrind发现没问题。运行

valgrind --leak-check=full ./prog

给出

==12917== Memcheck, a memory error detector
==12917== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==12917== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==12917== Command: ./prog
==12917== 
0
==12917== 
==12917== HEAP SUMMARY:
==12917==     in use at exit: 0 bytes in 0 blocks
==12917==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==12917== 
==12917== All heap blocks were freed -- no leaks are possible
==12917== 
==12917== For counts of detected and suppressed errors, rerun with: -v
==12917== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

下面我给出了我系统的一些规格。

我使用的是Ubuntu 12.04。正在运行

uname -a

给了我

Linux wtu-82 3.2.0-65-generic #99-Ubuntu SMP Fri Jul 4 21:03:29 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

运行

g++ -v

给出

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.4-1ubuntu1~12.04' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.4 (Ubuntu/Linaro 4.6.4-1ubuntu1~12.04)

的输出
cat /proc/cpuinfo

processor   : 0
vendor_id   : GenuineIntel
cpu family  : 6
model       : 23
model name  : Intel(R) Core(TM)2 Duo CPU     E8500  @ 3.16GHz
stepping    : 10
microcode   : 0xa0c
cpu MHz     : 2000.000
cache size  : 6144 KB
physical id : 0
siblings    : 2
core id     : 0
cpu cores   : 2
apicid      : 0
initial apicid  : 0
fpu     : yes
fpu_exception   : yes
cpuid level : 13
wp      : yes
flags       : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good nopl aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm sse4_1 xsave lahf_lm dtherm tpr_shadow vnmi flexpriority
bogomips    : 6317.48
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:

processor   : 1
vendor_id   : GenuineIntel
cpu family  : 6
model       : 23
model name  : Intel(R) Core(TM)2 Duo CPU     E8500  @ 3.16GHz
stepping    : 10
microcode   : 0xa0c
cpu MHz     : 2000.000
cache size  : 6144 KB
physical id : 0
siblings    : 2
core id     : 1
cpu cores   : 2
apicid      : 1
initial apicid  : 1
fpu     : yes
fpu_exception   : yes
cpuid level : 13
wp      : yes
flags       : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good nopl aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm sse4_1 xsave lahf_lm dtherm tpr_shadow vnmi flexpriority
bogomips    : 6317.38
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:

1 个答案:

答案 0 :(得分:3)

POPCNT中引入了

SSE 4.2。您的处理器为SSE 4.1。因此,指令完全没有了。当您使用-mpopcnt强制编译器使用处理器不知道的指令生成代码时,会出现非法指令错误。