how do i use if-else statement in sse2 intrinsics

how do i use if-else statement in sse2 intrinsics

original codes

if(y < 0)

block[j+8] = (short)(-( (((-y) * n[_q][r]) + _f) >> _a ));


block[j+8] = (short)( ((y * n[_q][r]) + _f) >> _a );

my attempt
if(y < 0) //error C2676: binary '<' : '__m128i' does not define this operator or a conversion to a type acceptable

tmp1= _mm_mulhi_epi16(_mm_sub_epi16(_mm_setzero_si128(), y), n[_q][r]);//error C2676: binary '[' : '__m128i' does not define this operator.
tmp2 =_mm_add_epi16(tmp1,_f);
tmp3=_mm_srli_epi32(tmp2, _a);
block[j+8] =_mm_sub_epi16(_mm_setzero_si128(), tmp3);

tmp4= _mm_mulhi_epi16( y, n[_q][r]);
tmp5 =_mm_add_epi16(tmp4,_f);
block[j+8]=_mm_srli_epi32(tmp5, _a);
note: >> shift right
* multiplication
how can i sort out these errors (see commented error)or is there a better way of writting these original codes

2 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

you can't use if-else with SSE2 intrisics (though you can with regular C++ code and using the auto-vectorizer)

with the intrinsics you have to use mask operations like this(Int128 is a wrapper class for __m128i) :

friend Int128 Select (const Int128 &mask, const Int128 &a, const Int128 &b)
{return _mm_or_si128(_mm_and_si128(mask.m,a.m),_mm_andnot_si128(mask.m,b.m));}

NB masks are computed with _mm_cmplt_epi16 and the like

now your use case looks like no more than |y| so you should find a simplified solution, though AFAIK abs(x) is easier to vectorize with packed floats (single andps/andpd to clear the sign bits) than packed ints

Leave a Comment

Please sign in to add a comment. Not a member? Join today