[Bug target/87853] New: _mm_cmpgt_epi8 broken with -funsigned-char
derek.mauro at gmail dot com
gcc-bugzilla@gcc.gnu.org
Thu Nov 1 15:08:00 GMT 2018
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87853
Bug ID: 87853
Summary: _mm_cmpgt_epi8 broken with -funsigned-char
Product: gcc
Version: 7.3.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: derek.mauro at gmail dot com
Target Milestone: ---
_mm_cmpgt_epi8 (and probably some related methods) are broken with
-funsigned-char
https://software.intel.com/en-us/node/524239 says specifically that it
"compares the 16 *signed* 8-bit integers in a and the 16 *signed* 8-bit
integers in b for greater than."
GCC's implementation of _mm_cmpgt_epi8:
https://github.com/gcc-mirror/gcc/blob/913b81c4d40ca6e1b157ea5785376d8de58b42fc/gcc/config/i386/emmintrin.h#L1331-L1335
and __v16qi:
https://github.com/gcc-mirror/gcc/blob/913b81c4d40ca6e1b157ea5785376d8de58b42fc/gcc/config/i386/emmintrin.h#L47
So I think a type with "signed char" instead of just "char" is needed to
implement _mm_cmpgt_epi8 correctly
Clang seems to get this right:
https://github.com/llvm-mirror/clang/blob/5fd1ab66bf97297c2b71ce3ec2bb33d579bca06e/lib/Headers/emmintrin.h#L3247-L3253
Here is a small repro program that you can compile with and without
-funsigned-char to see the difference:
#include <stdio.h>
#include <x86intrin.h>
int main() {
int i;
signed char a[16] = {-1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1};
signed char b[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
__m128i c = _mm_cmpgt_epi8(_mm_load_si128((const __m128i*)a),
_mm_load_si128((const __m128i*)b));
for (i = 0; i < 16; ++i) {
unsigned char* result = (unsigned char*)&c;
printf("result[%d]=%d\n", i, (int)result[i]);
}
};
More information about the Gcc-bugs
mailing list