Expose none() in the ISPC standard library.

On KNC: all(), any() and none() do not generate a redundant movmsk instruction.
This commit is contained in:
Jean-Luc Duprat
2012-11-27 13:38:28 -08:00
parent 6827001c1d
commit 24087ff3cc
3 changed files with 25 additions and 11 deletions

View File

@@ -3701,15 +3701,18 @@ where the ``i`` th element of ``x`` has been replaced with the value ``v``
Reductions Reductions
---------- ----------
A number routines are available to evaluate conditions across the running A number routines are available to evaluate conditions across the
program instances. For example, ``any()`` returns ``true`` if the given running program instances. For example, ``any()`` returns ``true`` if
value ``v`` is ``true`` for any of the SPMD program instances currently the given value ``v`` is ``true`` for any of the SPMD program
running, and ``all()`` returns ``true`` if it true for all of them. instances currently running, ``all()`` returns ``true`` if it true
for all of them, and ``none()`` returns ``true`` if ``v`` is always
``false``.
:: ::
uniform bool any(bool v) uniform bool any(bool v)
uniform bool all(bool v) uniform bool all(bool v)
uniform bool none(bool v)
You can also compute a variety of reductions across the program instances. You can also compute a variety of reductions across the program instances.
For example, the values of the given value in each of the active program For example, the values of the given value in each of the active program

View File

@@ -482,7 +482,7 @@ static FORCEINLINE bool __all(__vec16_i1 mask) {
} }
static FORCEINLINE bool __none(__vec16_i1 mask) { static FORCEINLINE bool __none(__vec16_i1 mask) {
return !__any(mask); return _mm512_kortestz(mask, mask);
} }
static FORCEINLINE __vec16_i1 __equal_i1(__vec16_i1 a, __vec16_i1 b) { static FORCEINLINE __vec16_i1 __equal_i1(__vec16_i1 a, __vec16_i1 b) {

View File

@@ -340,9 +340,9 @@ static inline uniform bool any(bool v) {
// We only care about whether "any" is true for the active program instances, // We only care about whether "any" is true for the active program instances,
// so we have to make v with the current program mask. // so we have to make v with the current program mask.
#ifdef ISPC_TARGET_GENERIC #ifdef ISPC_TARGET_GENERIC
return __movmsk(v & __mask) != 0; return __any(v | !__mask);
#else #else
return __movmsk(__sext_varying_bool(v) & __mask) != 0; return __any(__sext_varying_bool(v) | !__mask);
#endif #endif
} }
@@ -350,13 +350,24 @@ __declspec(safe)
static inline uniform bool all(bool v) { static inline uniform bool all(bool v) {
// As with any(), we need to explicitly mask v with the current program mask // As with any(), we need to explicitly mask v with the current program mask
// so we're only looking at the current lanes // so we're only looking at the current lanes
#ifdef ISPC_TARGET_GENERIC #ifdef ISPC_TARGET_GENERIC
bool match = ((v & __mask) == __mask); return __all(v | !__mask);
#else #else
int32 match = __sext_varying_bool((__sext_varying_bool(v) & __mask) == __mask); return __all(__sext_varying_bool(v) | !__mask);
#endif
}
__declspec(safe)
static inline uniform bool none(bool v) {
// As with any(), we need to explicitly mask v with the current program mask
// so we're only looking at the current lanes
#ifdef ISPC_TARGET_GENERIC
return __none(v | !__mask);
#else
return __none(__sext_varying_bool(v) | !__mask);
#endif #endif
return __movmsk(match) == ((programCount == 64) ? ~0ull :
((1ull << programCount) - 1));
} }
__declspec(safe) __declspec(safe)