AVX: "to 1 if not zero"

Viewed 201

How can I turn the values of array of float32 numbers to 1 if they are not zero, using AVX?

For example: -0.2134f, -1.23f, -0.0f, 12.0f ...

becomes 1.0f, 1.0f, 0.0f, 1.0f ...

I assume, we should combine _mm256_or_ps with some other instruction, but how?

2 Answers

The first idea I would come up with is comparing the values to 0 and then ANDing that with a register full of 1s:

y = _mm256_and_ps(_mm256_cmp_ps(_mm256_setzero_ps(), x, _CMP_NEQ_OQ), _mm256_set1_ps(1.f));

This will AND all the 1s in the places where x is 0 with a bunch of 0s and fortunately an IEEE 754 zero is also an integer zero. The other values will get a floating point 1 ANDed with a bunch of 1s and thus an identity operation.

Probably vcmpps with a NE predicate, then _mm256_and_ps with the bit-pattern for 1.0f is your best bet.

A false compare predicate gives you an all-zero bit-pattern which also conveniently represents 0.0f.

all-ones & 1.0f = 1.0f.

Total of 2 single-uop instructions. Using the compare result for a variable-blend would only be better if you wanted something other than 0.0f for the false case.

Related