From 7e129b8b891398a0c14b9c913f1c1f156fe94037 Mon Sep 17 00:00:00 2001 From: Mike Klein Date: Wed, 16 Sep 2020 15:50:00 -0500 Subject: [PATCH] Reland "refactor any()/all(), ptest for all()" This is a reland of e24f7f3de730fd21240a37f8b1d9eb602af25d27 ... 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 > Commit-Queue: Mike Klein 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 Reviewed-by: Herb Derby --- include/private/SkVx.h | 45 +++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/include/private/SkVx.h b/include/private/SkVx.h index abe577dba6..b5673dedb5 100644 --- a/include/private/SkVx.h +++ b/include/private/SkVx.h @@ -324,9 +324,6 @@ SIT Vec<1,T> if_then_else(const Vec<1,M>& cond, const Vec<1,T>& t, const Vec< (~cond & bit_pun>>(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 if_then_else(const Vec>& cond, const Vec& t, const Vec return naive_if_then_else(cond, t, e); } -SINT bool any(const Vec& x) { return any(x.lo) || any(x.hi); } -SINT bool all(const Vec& 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& x) { +#if defined(__wasm_simd128__) + if constexpr (N == 4 && sizeof(T) == 4) { + return wasm_i32x4_any_true(unchecked_bit_pun>(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& 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>(x)); + } +#endif + return all(x.lo) + && all(x.hi); +} SINT Vec pow(const Vec& x, const Vec& y) { return join(pow(x.lo, y.lo), pow(x.hi, y.hi)); @@ -697,13 +725,6 @@ SIN Vec approx_scale(const Vec& x, const Vec& 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