Check whether __m128i is zero?

2.6k views Asked by At

I found this question:

Is an __m128i variable zero?

Which I used to create the below example:

int main(){

    __m128i intrinreg;
    intrinreg.m128i_i64[0] = 0;
    intrinreg.m128i_i64[1] = 6;

    __m128i zero = _mm_setzero_si128();

    if (0 == _mm_movemask_epi8(_mm_cmpeq_epi32(intrinreg, zero)))
    {
        std::cout << "true" << std::endl;
    }
    else{
        std::cout << "false" << std::endl;
    }
}

but whether I set the two 64-bit int components to 0 or a non-zero, I always get "false" print out?

1

There are 1 answers

0
Z boson On

Since you have tagged AVX I assume that you have SSE4.1 in which case the instruction you want is ptest which you can get from _mm_testz_si128 or _mm_test_all_zeros().

bool test1, test2;
__m128i r1 = _mm_setzero_si128();
__m128i r2 = _mm_set1_epi64x(42);
test1 = _mm_testz_si128(r1,r1);
test2 = _mm_testz_si128(r2,r2);
printf("%d %d\n", test1, test2); //prints 1 0

If you don't have SSE4.1 then use _mm_movemask_epi8(_mm_cmpeq_epi32(x,_mm_setzero_si128())) == 0xFFFF. This requires pcmpeqd, pmovmskb, and test.

However, ptest sets the zero flag (ZF) so it only needs one instruction. See checking-if-two-sse-registers-are-not-both-zero-without-destroying-them for more details.