diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2015-10-01 02:21:34 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2015-10-01 02:21:34 +0000 |
commit | 9143378db0ec22c92a0af0c51fcfbcbfd24c359d (patch) | |
tree | 45cb9f2409d47dda6eecdab1e368a3831fbc9c87 /clang/lib | |
parent | f7ed23f744650b7c1bf21c4f8686d618ba415a93 (diff) | |
download | bcm5719-llvm-9143378db0ec22c92a0af0c51fcfbcbfd24c359d.tar.gz bcm5719-llvm-9143378db0ec22c92a0af0c51fcfbcbfd24c359d.zip |
Patch over a really horrible bug in our vector builtins that showed up
recently when we started using direct conversion to model sign
extension. The __v16qi type we use for SSE v16i8 vectors is defined in
terms of 'char' which may or may not be signed! This causes us to
generate pmovsx and pmovzx depending on the setting of -funsigned-char.
This patch just forms an explicitly signed type and uses that to
formulate the sign extension. While this gets the correct behavior
(which we now verify with the enhanced test) this is just the tip of the
ice berg. Now that I know what to look for, I have found errors of this
sort *throughout* our vector code. Fortunately, this is the only
specific place where I know of users actively having their code
miscompiled by Clang due to this, so I'm keeping the fix for those users
minimal and targeted.
I'll be sending a proper email for discussion of how to fix these
systematically, what the implications are, and just how widely broken
this is... From what I can tell, we have never shipped a correct set of
builtin headers for x86 when users rely on -funsigned-char. Oops.
llvm-svn: 248980
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Headers/smmintrin.h | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/clang/lib/Headers/smmintrin.h b/clang/lib/Headers/smmintrin.h index 4745b1c5831..7a18201eced 100644 --- a/clang/lib/Headers/smmintrin.h +++ b/clang/lib/Headers/smmintrin.h @@ -286,19 +286,34 @@ _mm_cmpeq_epi64(__m128i __V1, __m128i __V2) static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_cvtepi8_epi16(__m128i __V) { - return (__m128i)__builtin_convertvector(__builtin_shufflevector((__v16qi)__V, (__v16qi)__V, 0, 1, 2, 3, 4, 5, 6, 7), __v8hi); + /* We need a local definitively signed typedef similar to __v16qi even in the + * presence of __UNSIGNED_CHAR__. + * FIXME: __v16qi should almost certainly be definitively signed. + */ + typedef signed char __signed_v16qi __attribute__((__vector_size__(16))); + return (__m128i)__builtin_convertvector(__builtin_shufflevector((__signed_v16qi)__V, (__signed_v16qi)__V, 0, 1, 2, 3, 4, 5, 6, 7), __v8hi); } static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_cvtepi8_epi32(__m128i __V) { - return (__m128i)__builtin_convertvector(__builtin_shufflevector((__v16qi)__V, (__v16qi)__V, 0, 1, 2, 3), __v4si); + /* We need a local definitively signed typedef similar to __v16qi even in the + * presence of __UNSIGNED_CHAR__. + * FIXME: __v16qi should almost certainly be definitively signed. + */ + typedef signed char __signed_v16qi __attribute__((__vector_size__(16))); + return (__m128i)__builtin_convertvector(__builtin_shufflevector((__signed_v16qi)__V, (__signed_v16qi)__V, 0, 1, 2, 3), __v4si); } static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_cvtepi8_epi64(__m128i __V) { - return (__m128i)__builtin_convertvector(__builtin_shufflevector((__v16qi)__V, (__v16qi)__V, 0, 1), __v2di); + /* We need a local definitively signed typedef similar to __v16qi even in the + * presence of __UNSIGNED_CHAR__. + * FIXME: __v16qi should almost certainly be definitively signed. + */ + typedef signed char __signed_v16qi __attribute__((__vector_size__(16))); + return (__m128i)__builtin_convertvector(__builtin_shufflevector((__signed_v16qi)__V, (__signed_v16qi)__V, 0, 1), __v2di); } static __inline__ __m128i __DEFAULT_FN_ATTRS |