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
----------
A number routines are available to evaluate conditions across the running
program instances. For example, ``any()`` returns ``true`` if the given
value ``v`` is ``true`` for any of the SPMD program instances currently
running, and ``all()`` returns ``true`` if it true for all of them.
A number routines are available to evaluate conditions across the
running program instances. For example, ``any()`` returns ``true`` if
the given value ``v`` is ``true`` for any of the SPMD program
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 all(bool v)
uniform bool none(bool v)
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

View File

@@ -482,7 +482,7 @@ static FORCEINLINE bool __all(__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) {

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,
// so we have to make v with the current program mask.
#ifdef ISPC_TARGET_GENERIC
return __movmsk(v & __mask) != 0;
return __any(v | !__mask);
#else
return __movmsk(__sext_varying_bool(v) & __mask) != 0;
return __any(__sext_varying_bool(v) | !__mask);
#endif
}
@@ -350,13 +350,24 @@ __declspec(safe)
static inline uniform bool all(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
bool match = ((v & __mask) == __mask);
return __all(v | !__mask);
#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
return __movmsk(match) == ((programCount == 64) ? ~0ull :
((1ull << programCount) - 1));
}
__declspec(safe)