fixed 'INT_MIN' bug in '__gather64_i64'

This commit is contained in:
Anton Mitrokhin
2014-09-18 12:13:55 +04:00
parent 1a2979aa7f
commit 46bd353027

View File

@@ -994,15 +994,14 @@ __gather_base_offsets32_i64(uint8_t *base, uint32_t scale, __vec16_i32 offsets,
is pick one... is pick one...
*/ */
static FORCEINLINE __vec16_i64 static FORCEINLINE __vec16_i64
__gather64_i64(__vec16_i64 addr, __gather64_i64(__vec16_i64 addr, __vec16_i1 mask)
__vec16_i1 mask) {
{//TODO
__vec16_i64 ret; __vec16_i64 ret;
// There is no gather instruction with 64-bit offsets in KNC. // There is no gather instruction with 64-bit offsets in KNC.
// We have to manually iterate over the upper 32 bits ;-) // We have to manually iterate over the upper 32 bits ;-)
__vec16_i1 still_to_do = mask; __vec16_i1 still_to_do = mask;
__m512i offsets = addr.v_lo; const __vec16_i32 signed_offsets = _mm512_add_epi32(addr.v_lo, __smear_i32<__vec16_i32>((int32_t)INT_MIN));
while (still_to_do) { while (still_to_do) {
int first_active_lane = _mm_tzcnt_32((int)still_to_do); int first_active_lane = _mm_tzcnt_32((int)still_to_do);
const uint32_t &hi32 = ((uint*)&addr.v_hi)[first_active_lane]; const uint32_t &hi32 = ((uint*)&addr.v_hi)[first_active_lane];
@@ -1010,11 +1009,11 @@ __gather64_i64(__vec16_i64 addr,
__smear_i32<__vec16_i32>((int32_t)hi32), __smear_i32<__vec16_i32>((int32_t)hi32),
_MM_CMPINT_EQ); _MM_CMPINT_EQ);
const uint8_t * base = (const uint8_t*)((uint64_t)hi32 << 32); void * base = (void*)((((unsigned long)hi32) << 32) + (unsigned long)(-(long)INT_MIN));
ret.v_lo = _mm512_mask_i32extgather_epi32(ret.v_lo, match, offsets, ret.v_lo = _mm512_mask_i32extgather_epi32(ret.v_lo, match, signed_offsets,
base, _MM_UPCONV_EPI32_NONE, 1, base, _MM_UPCONV_EPI32_NONE, 1,
_MM_HINT_NONE); _MM_HINT_NONE);
ret.v_hi = _mm512_mask_i32extgather_epi32(ret.v_hi, match, offsets, ret.v_hi = _mm512_mask_i32extgather_epi32(ret.v_hi, match, signed_offsets,
base+4, _MM_UPCONV_EPI32_NONE, 1, base+4, _MM_UPCONV_EPI32_NONE, 1,
_MM_HINT_NONE); _MM_HINT_NONE);
@@ -1026,8 +1025,6 @@ __gather64_i64(__vec16_i64 addr,
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// float // float
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@@ -1982,7 +1979,6 @@ __gather_base_offsets32_double(uint8_t *base, uint32_t scale, __vec16_i32 offset
return ret; return ret;
} }
// TODO: Test this implementation
static FORCEINLINE __vec16_f static FORCEINLINE __vec16_f
__gather64_float(__vec16_i64 addr, __vec16_i1 mask) __gather64_float(__vec16_i64 addr, __vec16_i1 mask)
{ {