Reland "refactor any()/all(), ptest for all()"

This is a reland of e24f7f3de7
... with fix for ~0 constants for the pedantic MSVC.

Original change's description:
> refactor any()/all(), ptest for all()
>
> Part of this is a simple refactor, adapting any() and all() to the new
> style of specialization.
>
> And with that refactor in place, add AVX2/SSE4.1 for all() using ptest.
> This isn't terribly important, but it does help make Op::asserts run
> faster in the SkVM interpreter.  I like to run with asserts enabled, and
> this makes passing asserts much cheaper---failing asserts are expensive
> still of course, printing to SkDebugf(), etc.
>
> Change-Id: Iebdeee701fab7c50cce8e457674b565f7dd2ec21
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/317422
> Reviewed-by: Herb Derby <herb@google.com>
> Commit-Queue: Mike Klein <mtklein@google.com>

Cq-Include-Trybots: luci.skia.skia.primary:Build-Win-MSVC-x86_64-Debug
Change-Id: I93f08177ef3439e65e4383cc517dba60c0c4ef3e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/317638
Commit-Queue: Mike Klein <mtklein@google.com>
Reviewed-by: Herb Derby <herb@google.com>
This commit is contained in:
Mike Klein 2020-09-16 15:50:00 -05:00 committed by Skia Commit-Bot
parent 27f189fa4f
commit 7e129b8b89

View File

@ -324,9 +324,6 @@ SIT Vec<1,T> if_then_else(const Vec<1,M<T>>& cond, const Vec<1,T>& t, const Vec<
(~cond & bit_pun<Vec<1, M<T>>>(e)) );
}
SIT bool any(const Vec<1,T>& x) { return x.val != 0; }
SIT bool all(const Vec<1,T>& x) { return x.val != 0; }
SIT Vec<1,T> pow(const Vec<1,T>& x, const Vec<1,T>& y) { return std::pow(x.val, y.val); }
// All default N != 1 implementations just recurse on lo and hi halves.
@ -372,8 +369,39 @@ SINT Vec<N,T> if_then_else(const Vec<N,M<T>>& cond, const Vec<N,T>& t, const Vec
return naive_if_then_else(cond, t, e);
}
SINT bool any(const Vec<N,T>& x) { return any(x.lo) || any(x.hi); }
SINT bool all(const Vec<N,T>& x) { return all(x.lo) && all(x.hi); }
SIT bool any(const Vec<1,T>& x) { return x.val != 0; }
SINT bool any(const Vec<N,T>& x) {
#if defined(__wasm_simd128__)
if constexpr (N == 4 && sizeof(T) == 4) {
return wasm_i32x4_any_true(unchecked_bit_pun<VExt<4,int>>(x));
}
#endif
return any(x.lo)
|| any(x.hi);
}
SIT bool all(const Vec<1,T>& x) { return x.val != 0; }
SINT bool all(const Vec<N,T>& x) {
#if defined(__AVX2__)
if /*constexpr*/ (N*sizeof(T) == 32) {
return _mm256_testc_si256(unchecked_bit_pun<__m256i>(x),
_mm256_set1_epi32(-1));
}
#endif
#if defined(__SSE4_1__)
if /*constexpr*/ (N*sizeof(T) == 16) {
return _mm_testc_si128(unchecked_bit_pun<__m128i>(x),
_mm_set1_epi32(-1));
}
#endif
#if defined(__wasm_simd128__)
if /*constexpr*/ (N == 4 && sizeof(T) == 4) {
return wasm_i32x4_all_true(unchecked_bit_pun<VExt<4,int>>(x));
}
#endif
return all(x.lo)
&& all(x.hi);
}
SINT Vec<N,T> pow(const Vec<N,T>& x, const Vec<N,T>& y) {
return join(pow(x.lo, y.lo), pow(x.hi, y.hi));
@ -697,13 +725,6 @@ SIN Vec<N,uint8_t> approx_scale(const Vec<N,uint8_t>& x, const Vec<N,uint8_t>& y
}
#endif
#if defined __wasm_simd128__
SI bool any(const Vec<4, int32_t>& x) { return wasm_i32x4_any_true(to_vext(x)); }
SI bool any(const Vec<4,uint32_t>& x) { return wasm_i32x4_any_true(to_vext(x)); }
SI bool all(const Vec<4, int32_t>& x) { return wasm_i32x4_all_true(to_vext(x)); }
SI bool all(const Vec<4,uint32_t>& x) { return wasm_i32x4_all_true(to_vext(x)); }
#endif
#endif // !defined(SKNX_NO_SIMD)
} // namespace skvx