GCC Code Coverage Report


Directory: avs_core/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 98.8% 2571 / 0 / 2601
Functions: 92.0% 92 / 0 / 100
Branches: 75.5% 409 / 0 / 542

filters/intel/resample_avx512.hpp
Line Branch Exec Source
1 // AviSynth+. Copyright 2026- AviSynth+ Project
2 // https://avs-plus.net
3 // http://avisynth.nl
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
17 // http://www.gnu.org/copyleft/gpl.html .
18 //
19 // Linking Avisynth statically or dynamically with other modules is making a
20 // combined work based on Avisynth. Thus, the terms and conditions of the GNU
21 // General Public License cover the whole combination.
22 //
23 // As a special exception, the copyright holders of Avisynth give you
24 // permission to link Avisynth with independent modules that communicate with
25 // Avisynth solely through the interfaces defined in avisynth.h, regardless of the license
26 // terms of these independent modules, and to copy and distribute the
27 // resulting combined work under terms of your choice, provided that
28 // every copy of the combined work is accompanied by a complete copy of
29 // the source code of Avisynth (the version of Avisynth used to produce the
30 // combined work), being distributed under the terms of the GNU General
31 // Public License plus this exception. An independent module is a module
32 // which is not derived from or based on Avisynth, such as 3rd-party filters,
33 // import and export plugins, or graphical user interfaces.
34
35 /*
36
37 This is a common source cpp include file (not header) for multi-arch AVX512 functions.
38 Functions here are static, they will be compiled into each translation unit including this file.
39
40 */
41
42 // Original function needed avx512vbmi feature flag, but we want to support also base AVX512 without VBMI.
43 // We use _mm512_permutex2var_epi8_SIMUL<UseVBMI> and _mm512_maskz_permutex2var_epi8_SIMUL<UseVBMI>
44 // Thus both Base AVX512 and ICL level arch is supported.
45 // We are using two separated source modules and include this hpp file templated
46 // with UseVBMI/UseVNNI
47
48 // Notes:
49 // As of January 2026, Visual Studio 2026 ships with clang-cl (LLVM 20.1.8).
50 // - This version typically avoids using VNNI vpdpwssd instructions, opting instead for separate madd and add operations.
51 // - Masked permute operations are not optimized: for example, instead of using masked permutex2var_epi8,
52 // it performs a basic permutex2var_epi8 followed by an "and" with a pre-loaded zmm mask.
53 // These behaviors result in slower code compared to MSVC builds, which utilize these instructions more efficiently.
54 // These optimization issues are resolved in LLVM 21 (e.g., Intel C++ Compiler 2025.3).
55
56 // helper function for simulating _mm512_permutex2var_epi8 when VBMI is not available
57 // The MSB bit (128) zeroing effect is _not_ considered here, the indices must be all positive and within 0-127 range.
58 // Helper for _mm512_permutex2var_epi8_SIMUL: gather 32 bytes from [a,b] using precomputed word_idx and shift_amt.
59 // Extracted from lambda to ensure MSVC inlines it (lambdas are not reliably inlined by MSVC).
60 // Accepts precomputed word_idx (target_idx>>1) and shift_amt ((target_idx<<3)&8) so callers outside
61 // the y-loop can hoist these invariants, avoiding recomputation every row.
62 // Returns 32 16-bit words with gathered bytes in low 8 bits (high 8 bits cleared).
63 // Returning __m512i instead of __m256i lets callers feed unpacklo/hi_epi16 directly,
64 // avoiding the cvtepu8_epi16 expansion round-trip that MSVC emits as vpmovwb+vpmovzxbw.
65 AVS_FORCEINLINE static __m512i _permutex2var_epi8_sim_get32(__m512i word_idx, __m512i shift_amt, __m512i a, __m512i b)
66 {
67 1520 __m512i words = _mm512_permutex2var_epi16(a, word_idx, b);
68 // vpsrlvw: avoids k-register RAW dependency; MSVC compiles test_epi16_mask+mask_srli as
69 // vptestmw->k1->vpsrlw{k1}, creating a read-after-write through the mask unit (higher latency)
70 1520 words = _mm512_srlv_epi16(words, shift_amt);
71 // clear high byte so the caller can use unpacklo/hi_epi16 without cvtepu8_epi16
72 3040 return _mm512_and_si512(words, _mm512_set1_epi16(0x00FF));
73 }
74
75 template<bool UseVBMI>
76 AVS_FORCEINLINE static __m512i _mm512_permutex2var_epi8_SIMUL(__m512i a, __m512i idx, __m512i b) {
77 if constexpr (UseVBMI) {
78 return _mm512_permutex2var_epi8(a, idx, b);
79 }
80 else {
81 const __m512i c_8 = _mm512_set1_epi16(8);
82
83 __m512i idx_lo = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(idx));
84 __m512i idx_hi = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(idx, 1));
85
86 __m512i wi_lo = _mm512_srli_epi16(idx_lo, 1);
87 __m512i sa_lo = _mm512_and_si512(_mm512_slli_epi16(idx_lo, 3), c_8);
88 __m512i wi_hi = _mm512_srli_epi16(idx_hi, 1);
89 __m512i sa_hi = _mm512_and_si512(_mm512_slli_epi16(idx_hi, 3), c_8);
90
91 __m256i res_0_31 = _mm512_cvtepi16_epi8(_permutex2var_epi8_sim_get32(wi_lo, sa_lo, a, b));
92 __m256i res_32_63 = _mm512_cvtepi16_epi8(_permutex2var_epi8_sim_get32(wi_hi, sa_hi, a, b));
93
94 return _mm512_inserti64x4(_mm512_castsi256_si512(res_0_31), res_32_63, 1);
95 }
96 }
97
98 template<bool UseVBMI>
99 AVS_FORCEINLINE static __m512i _mm512_maskz_permutex2var_epi8_SIMUL(
100 __mmask64 k,
101 __m512i a,
102 __m512i idx,
103 __m512i b)
104 {
105 if constexpr (UseVBMI) {
106 600 return _mm512_maskz_permutex2var_epi8(k, a, idx, b);
107 }
108 else {
109 // 1. Run the base simulation to get the permuted bytes
110 // Note: Using your existing logic to get the full 512-bit permuted result
111 __m512i res = _mm512_permutex2var_epi8_SIMUL<false>(a, idx, b);
112
113 // 2. Apply the zero-mask using AVX-512BW
114 // _mm512_maskz_mov_epi8(k, src, src) returns 'src' where k[i]==1, and 0 where k[i]==0
115 return _mm512_maskz_mov_epi8(k, res);
116 }
117 }
118
119 // H-Float-Resampler: 16 pixels, filter size 4, transpose 4x (4x_m128) to 4x_m512
120 // Transposes a 4x4 matrix of 4-float vectors (16x16 float matrix effectively).
121 // Input/Output: Four 512-bit vectors (16 floats each) passed by reference.
122 AVS_FORCEINLINE static void _MM_TRANSPOSE16_LANE4_PS(__m512& row0, __m512& row1, __m512& row2, __m512& row3) {
123 // Stage 1: Interleave 32-bit (float) elements within 128-bit chunks (lanes)
124 // t0 = (r0_lo, r1_lo) | t1 = (r0_hi, r1_hi)
125 // t2 = (r2_lo, r3_lo) | t3 = (r2_hi, r3_hi)
126 62 __m512 t0 = _mm512_unpacklo_ps(row0, row1);
127 62 __m512 t1 = _mm512_unpackhi_ps(row0, row1);
128 62 __m512 t2 = _mm512_unpacklo_ps(row2, row3);
129 124 __m512 t3 = _mm512_unpackhi_ps(row2, row3);
130
131 // Stage 2: Shuffle 128-bit chunks (lanes) to complete the transpose
132 // We use _mm512_shuffle_ps which shuffles 64-bit blocks across the 512-bit register.
133 // _MM_SHUFFLE(w, z, y, x) applies to the 64-bit pairs (4 floats) within each 128-bit lane.
134 // Result: row0 = columns 0, 1, 2, 3
135 62 row0 = _mm512_shuffle_ps(t0, t2, _MM_SHUFFLE(1, 0, 1, 0));
136 // Result: row1 = columns 4, 5, 6, 7
137 62 row1 = _mm512_shuffle_ps(t0, t2, _MM_SHUFFLE(3, 2, 3, 2));
138 // Result: row2 = columns 8, 9, 10, 11
139 62 row2 = _mm512_shuffle_ps(t1, t3, _MM_SHUFFLE(1, 0, 1, 0));
140 // Result: row3 = columns 12, 13, 14, 15
141 62 row3 = _mm512_shuffle_ps(t1, t3, _MM_SHUFFLE(3, 2, 3, 2));
142 62 }
143
144 // H-float-resampler: 16 pixels, filter size 8, transpose 8x (2x_m256) to 8x_m512
145 // Transposes an 8x8 matrix of 2-float vectors (16x16 float matrix).
146 // Input/Output: Eight 512-bit vectors (16 floats each) passed by reference.
147 AVS_FORCEINLINE static void _MM_TRANSPOSE8x16_PS(
148 __m512& r0, __m512& r1, __m512& r2, __m512& r3,
149 __m512& r4, __m512& r5, __m512& r6, __m512& r7)
150 {
151 // --- Stage 1: Unpack 32-bit (Pairs of rows) ---
152 24 __m512 t0 = _mm512_unpacklo_ps(r0, r1);
153 24 __m512 t1 = _mm512_unpackhi_ps(r0, r1);
154 24 __m512 t2 = _mm512_unpacklo_ps(r2, r3);
155 24 __m512 t3 = _mm512_unpackhi_ps(r2, r3);
156 24 __m512 t4 = _mm512_unpacklo_ps(r4, r5);
157 24 __m512 t5 = _mm512_unpackhi_ps(r4, r5);
158 24 __m512 t6 = _mm512_unpacklo_ps(r6, r7);
159 48 __m512 t7 = _mm512_unpackhi_ps(r6, r7);
160
161 // --- Stage 2: Unpack 64-bit (Quads of rows) ---
162 // Uses _mm512_unpacklo/hi_pd for 64-bit (double) to interleave pairs of __m512 floats
163 96 __m512 u0 = _mm512_castpd_ps(_mm512_unpacklo_pd(_mm512_castps_pd(t0), _mm512_castps_pd(t2)));
164 96 __m512 u1 = _mm512_castpd_ps(_mm512_unpackhi_pd(_mm512_castps_pd(t0), _mm512_castps_pd(t2)));
165 96 __m512 u2 = _mm512_castpd_ps(_mm512_unpacklo_pd(_mm512_castps_pd(t1), _mm512_castps_pd(t3)));
166 96 __m512 u3 = _mm512_castpd_ps(_mm512_unpackhi_pd(_mm512_castps_pd(t1), _mm512_castps_pd(t3)));
167 96 __m512 u4 = _mm512_castpd_ps(_mm512_unpacklo_pd(_mm512_castps_pd(t4), _mm512_castps_pd(t6)));
168 96 __m512 u5 = _mm512_castpd_ps(_mm512_unpackhi_pd(_mm512_castps_pd(t4), _mm512_castps_pd(t6)));
169 96 __m512 u6 = _mm512_castpd_ps(_mm512_unpacklo_pd(_mm512_castps_pd(t5), _mm512_castps_pd(t7)));
170 96 __m512 u7 = _mm512_castpd_ps(_mm512_unpackhi_pd(_mm512_castps_pd(t5), _mm512_castps_pd(t7)));
171
172 // --- Stage 3: Shuffle 128-bit lanes (Octets of rows) ---
173 // _mm512_shuffle_f32x4 shuffles the 128-bit (f32x4) sub-vectors within and between two __m512 vectors.
174 // 0x88 = (10001000)_2: selects lane 0 from first input and lane 0 from second input for lo/hi 256 bits.
175 // 0xDD = (11011101)_2: selects lane 3 from first input and lane 3 from second input for lo/hi 256 bits.
176 24 __m512 v0 = _mm512_shuffle_f32x4(u0, u4, 0x88); // Col 0, 4 (interleaved)
177 24 __m512 v1 = _mm512_shuffle_f32x4(u0, u4, 0xDD); // Col 1, 5 (interleaved)
178 24 __m512 v2 = _mm512_shuffle_f32x4(u1, u5, 0x88); // Col 2, 6 (interleaved)
179 24 __m512 v3 = _mm512_shuffle_f32x4(u1, u5, 0xDD); // Col 3, 7 (interleaved)
180 24 __m512 v4 = _mm512_shuffle_f32x4(u2, u6, 0x88); // Col 8, 12 (interleaved)
181 24 __m512 v5 = _mm512_shuffle_f32x4(u2, u6, 0xDD); // Col 9, 13 (interleaved)
182 24 __m512 v6 = _mm512_shuffle_f32x4(u3, u7, 0x88); // Col 10, 14 (interleaved)
183 24 __m512 v7 = _mm512_shuffle_f32x4(u3, u7, 0xDD); // Col 11, 15 (interleaved)
184
185 // --- Stage 4: Permute to Linearize Indices ---
186 // Corrects the order of the 128-bit lanes to linearize the columns.
187 // The columns are currently: (0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15)
188 // The required order is: (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
189 24 __m512i idx = _mm512_setr_epi32(
190 0, 4, 1, 5, /* Lane 0: Rows 0, 1, 2, 3 */
191 2, 6, 3, 7, /* Lane 1: Rows 4, 5, 6, 7 */
192 8, 12, 9, 13, /* Lane 2: Rows 8, 9, 10, 11 */
193 10, 14, 11, 15 /* Lane 3: Rows 12, 13, 14, 15 */
194 );
195
196 // --- Final Assignment with Correct Mapping ---
197 // Maps the permuted vector components back to the original row variables (now columns).
198 24 r0 = _mm512_permutexvar_ps(idx, v0); // Col 0
199 24 r1 = _mm512_permutexvar_ps(idx, v2); // Col 1
200 24 r2 = _mm512_permutexvar_ps(idx, v4); // Col 2
201 24 r3 = _mm512_permutexvar_ps(idx, v6); // Col 3
202 24 r4 = _mm512_permutexvar_ps(idx, v1); // Col 4
203 24 r5 = _mm512_permutexvar_ps(idx, v3); // Col 5
204 24 r6 = _mm512_permutexvar_ps(idx, v5); // Col 6
205 24 r7 = _mm512_permutexvar_ps(idx, v7); // Col 7
206 24 }
207
208 // Loads two 256-bit float vectors from registers (__m256) into a single 512-bit register.
209 // Equivalent to _mm512_insertf32x8(_mm512_castps256_ps512(lo), hi, 1)
210 AVS_FORCEINLINE static __m512 _mm512_insert_2_m256(__m256 lo, __m256 hi) {
211 384 return _mm512_insertf32x8(_mm512_castps256_ps512(lo), hi, 1);
212 }
213
214 // Loads four 128-bit float vectors (unaligned) into a single 512-bit register.
215 AVS_FORCEINLINE static __m512 _mm512_loadu_4_m128(
216 /* __m128 const* */ const float* addr1,
217 /* __m128 const* */ const float* addr2,
218 /* __m128 const* */ const float* addr3,
219 /* __m128 const* */ const float* addr4)
220 {
221 // The cast is needed for the first insertion to make the target a 512-bit register
222 160 __m512 v = _mm512_castps128_ps512(_mm_loadu_ps(addr1));
223 80 v = _mm512_insertf32x4(v, _mm_loadu_ps(addr2), 1);
224 80 v = _mm512_insertf32x4(v, _mm_loadu_ps(addr3), 2);
225 80 v = _mm512_insertf32x4(v, _mm_loadu_ps(addr4), 3);
226 80 return v;
227 }
228
229 // Loads four 128-bit float vectors (aligned) into a single 512-bit register.
230 AVS_FORCEINLINE static __m512 _mm512_load_4_m128(
231 /* __m128 const* */ const float* addr1,
232 /* __m128 const* */ const float* addr2,
233 /* __m128 const* */ const float* addr3,
234 /* __m128 const* */ const float* addr4)
235 {
236 // The cast is needed for the first insertion to make the target a 512-bit register
237 336 __m512 v = _mm512_castps128_ps512(_mm_load_ps(addr1));
238 168 v = _mm512_insertf32x4(v, _mm_load_ps(addr2), 1);
239 168 v = _mm512_insertf32x4(v, _mm_load_ps(addr3), 2);
240 168 v = _mm512_insertf32x4(v, _mm_load_ps(addr4), 3);
241 168 return v;
242 }
243
244 // Loads two 256 - bit unaligned integer vectors from registers(__m256i) into a single 512i register.
245 AVS_FORCEINLINE static __m512i _mm512i_loadu_2_m256i(
246 const __m256i* addr1,
247 const __m256i* addr2)
248 {
249 return _mm512_inserti64x4(_mm512_castsi256_si512(_mm256_loadu_si256(addr1)), _mm256_loadu_si256(addr2), 1);
250 }
251
252 // Loads two 256 - bit aligned integer vectors from registers(__m256) into a single 512 - bit register.
253 AVS_FORCEINLINE static __m512i _mm512i_load_2_m256i(
254 const __m256i* addr1,
255 const __m256i* addr2)
256 {
257 return _mm512_inserti64x4(_mm512_castsi256_si512(_mm256_load_si256(addr1)), _mm256_load_si256(addr2), 1);
258 }
259
260 // Integers
261 // Loads four 128-bit integer vectors (unaligned) into a single 512-bit integer register.
262 AVS_FORCEINLINE static __m512i _mm512i_loadu_4_m128i(
263 const __m128i* addr1,
264 const __m128i* addr2,
265 const __m128i* addr3,
266 const __m128i* addr4)
267 {
268 // The cast is needed for the first insertion to make the target a 512-bit register
269 __m512i v = _mm512_castsi128_si512(_mm_loadu_si128(addr1));
270 v = _mm512_inserti32x4(v, _mm_loadu_si128(addr2), 1);
271 v = _mm512_inserti32x4(v, _mm_loadu_si128(addr3), 2);
272 v = _mm512_inserti32x4(v, _mm_loadu_si128(addr4), 3);
273 return v;
274 }
275
276 // filter size up to 4
277 // 64 target uint8_t pixels at a time
278 // 128-byte source loads (128 uint8_t pixels)
279 // maximum permute index is 128 for _mm512_permutex2var_epi8 (uint8_t)
280
281 // filter size up to 8
282 // 64 target uint8_t pixels at a time
283 // 128-byte source loads (128 uint8_t pixels)
284 // maximum permute index is 128 for _mm512_permutex2var_epi8(uint8_t)
285
286 // filter size up to 8
287 // 64 target uint8_t pixels at a time in 2 groups of 32 to support longer source loading to each group to support lower downsample ratios
288 // support /2 downsample ratios for resizers with no-resize kernel size of 4 (or support of 2 ?) (Bicubic, Bilinear, and others, also SinPowResize (?))
289 // 2 groups of 128-byte source loads (128 uint8_t pixels)
290 // maximum permute index is 128 for _mm512_permutex2var_epi8 (uint8_t)
291
292 // filter size up to 16
293 // 32 target uint8_t pixels at a time
294 // 128-byte source loads (128 uint8_t pixels)
295 // maximum permute index is 128 for _mm512_permutex2var_epi8 (uint8_t)
296 // expect to support all upsampling ratios up to filter support of 8 (or 7..6 ?) and some downsampling ratios with filter support up to 3 (with downsample ratios from 0.5 or a bit lower)
297
298 // uint8_t "mp" versions
299
300 // filter size up to 4
301 // 64 target uint8_t pixels at a time
302 // 127-byte source loads (127 uint8_t pixels)
303 // maximum permute index is 127 for _mm512_maskz_permutex2var_epi8 (uint8_t)
304 // more premutex version to create 8->16bit converted and low-hi unpacked registers in single permutex instruction
305
306 // filter size up to 4
307 // 64 target uint8_t pixels at a time
308 // 127-byte source loads (127 uint8_t pixels)
309 // maximum permute index is 127 for _mm512_maskz_permutex2var_epi8 (uint8_t)
310 // more premutex version to create 8->16bit converted and low-hi unpacked registers in single permutex instruction
311 template<bool UseVNNI>
312 76 void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_pretransposed_coeffs_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)
313 {
314 76 constexpr int PIXELS_AT_A_TIME = 64;
315
316 // 'source_overread_beyond_targetx' indicates if the filter kernel can read beyond the target width.
317 // we load 2x64 source bytes at a time, so ensure safe overread if needed.
318 // Our main loop processes calculates for 64 target pixels at a time.
319 // Inside that, we load 128 source bytes (2x64) to be able to permutex from that.
320 // This we have to check at each mod-PIXELS_AT_A_TIME boundary, the allowance of 128-byte source load.
321
2/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 4 not taken.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 2 → 3 taken 75 times.
✗ Branch 2 → 4 not taken.
76 const int width_safe_mod = (program->safelimit_128_pixels_each64th_target.overread_possible ? program->safelimit_128_pixels_each64th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;
322
323 // Preconditions:
324
2/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 75 times.
76 assert(program->filter_size_real <= 4); // We preload all relevant coefficients (up to 4) before the height loop.
325
326 // 'target_size_alignment' ensures we can safely access coefficients using offsets like
327 // 'filter_size * 15' when processing 16 H pixels at a time
328 // 'filter_size * 63' when processing 64 H pixels at a time
329
2/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 75 times.
76 assert(program->target_size_alignment >= 64); // Adjusted for 64 pixels (is it enough for uint8 ?)
330
331 assert(FRAME_ALIGN >= 64); // Good for 64x8 bit pixels
332
333 // Ensure that coefficient loading beyond the valid target size is safe for 4x4 float loads.
334 // We load 4x16bit coeffs at a time
335
2/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 75 times.
76 assert(program->filter_size_alignment >= 4);
336
337 76 const int max_scanlines = program->max_scanlines;
338
339 76 __m512i rounder = _mm512_set1_epi32(1 << (FPScale8bits - 1));
340
341 // Vertical stripe loop for L2 cache optimization
342
4/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 14 taken 1 time.
✓ Branch 24 → 25 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 14 taken 75 times.
✓ Branch 24 → 25 taken 75 times.
152 for (int y_from = 0; y_from < height; y_from += max_scanlines)
343 {
344 76 int y_to = std::min(y_from + max_scanlines, height);
345
346 // Reset current_coeff for the start of the stripe (points to start of row's coeffs)
347 // const short* AVS_RESTRICT current_coeff = program->pixel_coefficient;
348 // Pre-transposed coefficients for AVX512, stored in the program structure, ready for direct use in the main loop without needing to transpose on the fly.
349 76 const __m512i* AVS_RESTRICT current_coeff_SIMD = (__m512i*)program->pixel_coefficient_AVX512_H;
350
351 76 int x = 0;
352
353 // Lambda to handle both safe (fast) and unsafe (masked/partial) loading paths
354 156 auto do_h_integer_core = [&](auto partial_load) {
355
356 // prepare coefs in transposed V-form
357 // TODO: make storage in transposed form, 64 x uint16 transposition looks too slow
358 80 __m512i one_epi16 = _mm512_set1_epi16(1);
359
360 // load coeffs from prepared
361 80 const __m512i coef_r0r1_0_31lo = _mm512_load_si512(current_coeff_SIMD + 0);
362 80 const __m512i coef_r0r1_0_31hi = _mm512_load_si512(current_coeff_SIMD + 1); // in count of __m512i
363
364 80 const __m512i coef_r0r1_32_63lo = _mm512_load_si512(current_coeff_SIMD + 2);
365 80 const __m512i coef_r0r1_32_63hi = _mm512_load_si512(current_coeff_SIMD + 3);
366
367 80 const __m512i coef_r2r3_0_31lo = _mm512_load_si512(current_coeff_SIMD + 4);
368 80 const __m512i coef_r2r3_0_31hi = _mm512_load_si512(current_coeff_SIMD + 5);
369
370 80 const __m512i coef_r2r3_32_63lo = _mm512_load_si512(current_coeff_SIMD + 6);
371 80 const __m512i coef_r2r3_32_63hi = _mm512_load_si512(current_coeff_SIMD + 7);
372
373 // convert resampling program in H-form into permuting indexes for src transposition in V-form
374 80 __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x])); // 16 offsets
375 80 __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16])); // 16 offsets
376 80 __m512i perm_0_32_47 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 32])); // 16 offsets
377 80 __m512i perm_0_48_63 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 48])); // 16 offsets
378
379 80 int iStart = program->pixel_offset[x];
380 80 __m512i m512i_Start = _mm512_set1_epi32(iStart);
381
382 80 perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start);
383 80 perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start);
384 80 perm_0_32_47 = _mm512_sub_epi32(perm_0_32_47, m512i_Start);
385 80 perm_0_48_63 = _mm512_sub_epi32(perm_0_48_63, m512i_Start);
386
387 80 __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);
388 80 __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);
389 80 __m256i m256i_perm_0_32_47 = _mm512_cvtepi32_epi16(perm_0_32_47);
390 80 __m256i m256i_perm_0_48_63 = _mm512_cvtepi32_epi16(perm_0_48_63);
391
392 160 __m512i perm_0_0_31 = _mm512_inserti64x4(_mm512_castsi256_si512(m256i_perm_0_0_15), m256i_perm_0_16_31, 1);
393 160 __m512i perm_0_32_63 = _mm512_inserti64x4(_mm512_castsi256_si512(m256i_perm_0_32_47), m256i_perm_0_48_63, 1);
394
395 // Taps are contiguous (0, 1, 2, 3), so we increment perm indexes by 1.
396 80 __m512i perm_1_0_31 = _mm512_add_epi16(perm_0_0_31, one_epi16);
397 80 __m512i perm_2_0_31 = _mm512_add_epi16(perm_1_0_31, one_epi16);
398 80 __m512i perm_3_0_31 = _mm512_add_epi16(perm_2_0_31, one_epi16);
399
400 80 __m512i perm_1_32_63 = _mm512_add_epi16(perm_0_32_63, one_epi16);
401 80 __m512i perm_2_32_63 = _mm512_add_epi16(perm_1_32_63, one_epi16);
402 80 __m512i perm_3_32_63 = _mm512_add_epi16(perm_2_32_63, one_epi16);
403
404 80 const __m512i perm_r0r1_0_31lo = _mm512_unpacklo_epi16(perm_0_0_31, perm_1_0_31);
405 80 const __m512i perm_r0r1_0_31hi = _mm512_unpackhi_epi16(perm_0_0_31, perm_1_0_31);
406
407 80 const __m512i perm_r0r1_32_63lo = _mm512_unpacklo_epi16(perm_0_32_63, perm_1_32_63);
408 80 const __m512i perm_r0r1_32_63hi = _mm512_unpackhi_epi16(perm_0_32_63, perm_1_32_63);
409
410 80 const __m512i perm_r2r3_0_31lo = _mm512_unpacklo_epi16(perm_2_0_31, perm_3_0_31);
411 80 const __m512i perm_r2r3_0_31hi = _mm512_unpackhi_epi16(perm_2_0_31, perm_3_0_31);
412
413 80 const __m512i perm_r2r3_32_63lo = _mm512_unpacklo_epi16(perm_2_32_63, perm_3_32_63);
414 80 const __m512i perm_r2r3_32_63hi = _mm512_unpackhi_epi16(perm_2_32_63, perm_3_32_63);
415
416 80 __m512i wi_r0r1_0_31lo={},sa_r0r1_0_31lo={},wi_r0r1_0_31hi={},sa_r0r1_0_31hi={};
417 80 __m512i wi_r0r1_32_63lo={},sa_r0r1_32_63lo={},wi_r0r1_32_63hi={},sa_r0r1_32_63hi={};
418 80 __m512i wi_r2r3_0_31lo={},sa_r2r3_0_31lo={},wi_r2r3_0_31hi={},sa_r2r3_0_31hi={};
419 80 __m512i wi_r2r3_32_63lo={},sa_r2r3_32_63lo={},wi_r2r3_32_63hi={},sa_r2r3_32_63hi={};
420 if constexpr (!UseVNNI) {
421 3 const __m512i c_8w = _mm512_set1_epi16(8);
422 27 auto make_wi_sa = [&](__m512i p, __m512i& wi, __m512i& sa) {
423 24 wi = _mm512_srli_epi16(p, 1);
424 48 sa = _mm512_and_si512(_mm512_slli_epi16(p, 3), c_8w);
425 };
426 3 make_wi_sa(perm_r0r1_0_31lo, wi_r0r1_0_31lo, sa_r0r1_0_31lo);
427 3 make_wi_sa(perm_r0r1_0_31hi, wi_r0r1_0_31hi, sa_r0r1_0_31hi);
428 3 make_wi_sa(perm_r0r1_32_63lo, wi_r0r1_32_63lo, sa_r0r1_32_63lo);
429 3 make_wi_sa(perm_r0r1_32_63hi, wi_r0r1_32_63hi, sa_r0r1_32_63hi);
430 3 make_wi_sa(perm_r2r3_0_31lo, wi_r2r3_0_31lo, sa_r2r3_0_31lo);
431 3 make_wi_sa(perm_r2r3_0_31hi, wi_r2r3_0_31hi, sa_r2r3_0_31hi);
432 3 make_wi_sa(perm_r2r3_32_63lo, wi_r2r3_32_63lo, sa_r2r3_32_63lo);
433 3 make_wi_sa(perm_r2r3_32_63hi, wi_r2r3_32_63hi, sa_r2r3_32_63hi);
434 }
435
436 80 uint8_t* AVS_RESTRICT dst_ptr = dst8 + x + y_from * dst_pitch;
437 80 const uint8_t* src_ptr = src8 + iStart + y_from * src_pitch; // all permute offsets relative to this start offset
438
439 // Calculate remaining pixels for bounds checking in partial_load mode. 1..128 remaining pixels possible.
440 80 const int remaining = program->source_size - iStart;
441 80 __mmask64 k1 = _bzhi_u64(~0ULL, remaining); // _bzhi_u64 creates a mask with the lower N bits set. If N >= 64, it returns all ones (~0ULL).
442 80 __mmask64 k2 = _bzhi_u64(~0ULL, std::max(0, remaining - 64));
443
444 // mask is used to zero out every odd byte, so that the result of the permute is a
445 // vector of zero-extended 8-bit values in 16-bit lanes, preparing 8-bit data for 16-bit FMA operations in AVX512.
446 80 const __mmask64 k_zh8 = 0x5555555555555555ULL;
447
448
8/8
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 305 → 127 taken 5 times.
✓ Branch 305 → 306 taken 1 time.
✓ Branch 309 → 127 taken 10 times.
✓ Branch 309 → 310 taken 2 times.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 183 → 117 taken 5 times.
✓ Branch 183 → 184 taken 1 time.
✓ Branch 187 → 117 taken 291 times.
✓ Branch 187 → 188 taken 76 times.
391 for (int y = y_from; y < y_to; y++)
449 {
450 // 8 coeffs + 8 permute_idx + 2 src + 4 temporal + 1 rounder ~= 23 regs (permute2var overwrite first source - really may be more needed)
451 __m512i data_src, data_src2;
452
453 if constexpr (partial_load) {
454 // Safe masked loads for the image edge
455 301 data_src = _mm512_maskz_loadu_epi8(k1, src_ptr);
456 592 data_src2 = _mm512_maskz_loadu_epi8(k2, src_ptr + 64);
457 }
458 else {
459 // Fast unaligned loads for the safe zone
460 10 data_src = _mm512_loadu_si512(src_ptr);
461 15 data_src2 = _mm512_loadu_si512(src_ptr + 64);
462 }
463
464 __m512i src_r0r1_0_31lo, src_r0r1_0_31hi, src_r0r1_32_63lo, src_r0r1_32_63hi;
465 __m512i src_r2r3_0_31lo, src_r2r3_0_31hi, src_r2r3_32_63lo, src_r2r3_32_63hi;
466 if constexpr (UseVNNI) {
467 296 src_r0r1_0_31lo = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_r0r1_0_31lo, data_src2);
468 296 src_r0r1_0_31hi = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_r0r1_0_31hi, data_src2);
469 296 src_r0r1_32_63lo = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_r0r1_32_63lo, data_src2);
470 296 src_r0r1_32_63hi = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_r0r1_32_63hi, data_src2);
471 296 src_r2r3_0_31lo = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_r2r3_0_31lo, data_src2);
472 296 src_r2r3_0_31hi = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_r2r3_0_31hi, data_src2);
473 296 src_r2r3_32_63lo = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_r2r3_32_63lo, data_src2);
474 296 src_r2r3_32_63hi = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_r2r3_32_63hi, data_src2);
475 } else {
476 15 src_r0r1_0_31lo = _permutex2var_epi8_sim_get32(wi_r0r1_0_31lo, sa_r0r1_0_31lo, data_src, data_src2);
477 15 src_r0r1_0_31hi = _permutex2var_epi8_sim_get32(wi_r0r1_0_31hi, sa_r0r1_0_31hi, data_src, data_src2);
478 15 src_r0r1_32_63lo = _permutex2var_epi8_sim_get32(wi_r0r1_32_63lo, sa_r0r1_32_63lo, data_src, data_src2);
479 15 src_r0r1_32_63hi = _permutex2var_epi8_sim_get32(wi_r0r1_32_63hi, sa_r0r1_32_63hi, data_src, data_src2);
480 15 src_r2r3_0_31lo = _permutex2var_epi8_sim_get32(wi_r2r3_0_31lo, sa_r2r3_0_31lo, data_src, data_src2);
481 15 src_r2r3_0_31hi = _permutex2var_epi8_sim_get32(wi_r2r3_0_31hi, sa_r2r3_0_31hi, data_src, data_src2);
482 15 src_r2r3_32_63lo = _permutex2var_epi8_sim_get32(wi_r2r3_32_63lo, sa_r2r3_32_63lo, data_src, data_src2);
483 30 src_r2r3_32_63hi = _permutex2var_epi8_sim_get32(wi_r2r3_32_63hi, sa_r2r3_32_63hi, data_src, data_src2);
484 }
485
486 __m512i result_0_31lo, result_0_31hi;
487 __m512i result_32_63lo, result_32_63hi;
488
489 if constexpr (UseVNNI)
490 {
491 592 result_0_31lo = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31lo, coef_r0r1_0_31lo);
492 296 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r2r3_0_31lo, coef_r2r3_0_31lo);
493
494 592 result_0_31hi = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31hi, coef_r0r1_0_31hi);
495 296 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r2r3_0_31hi, coef_r2r3_0_31hi);
496
497 592 result_32_63lo = _mm512_dpwssd_epi32(rounder, src_r0r1_32_63lo, coef_r0r1_32_63lo);
498 296 result_32_63lo = _mm512_dpwssd_epi32(result_32_63lo, src_r2r3_32_63lo, coef_r2r3_32_63lo);
499
500 592 result_32_63hi = _mm512_dpwssd_epi32(rounder, src_r0r1_32_63hi, coef_r0r1_32_63hi);
501 296 result_32_63hi = _mm512_dpwssd_epi32(result_32_63hi, src_r2r3_32_63hi, coef_r2r3_32_63hi);
502 }
503 else
504 {
505 // making FMA in 32bits accs as in AVX256 V-resize
506 45 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo));
507 45 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi));
508
509 45 result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63lo, coef_r0r1_32_63lo), _mm512_madd_epi16(src_r2r3_32_63lo, coef_r2r3_32_63lo));
510 30 result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63hi, coef_r0r1_32_63hi), _mm512_madd_epi16(src_r2r3_32_63hi, coef_r2r3_32_63hi));
511
512 // rounding
513 15 result_0_31lo = _mm512_add_epi32(result_0_31lo, rounder);
514 15 result_0_31hi = _mm512_add_epi32(result_0_31hi, rounder);
515 15 result_32_63lo = _mm512_add_epi32(result_32_63lo, rounder);
516 30 result_32_63hi = _mm512_add_epi32(result_32_63hi, rounder);
517 }
518
519 // scaling down
520 311 result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale8bits);
521 311 result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale8bits);
522 311 result_32_63lo = _mm512_srai_epi32(result_32_63lo, FPScale8bits);
523 311 result_32_63hi = _mm512_srai_epi32(result_32_63hi, FPScale8bits);
524
525 311 __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);
526 311 __m512i result_32_63_int16 = _mm512_packus_epi32(result_32_63lo, result_32_63hi);
527
528 // cast is enough, no need to _mm512_zextsi256_si512
529 1244 _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr),
530 _mm512_inserti64x4(_mm512_castsi256_si512(_mm512_cvtusepi16_epi8(result_0_31_int16)), _mm512_cvtusepi16_epi8(result_32_63_int16), 1));
531
532 311 dst_ptr += dst_pitch;
533 311 src_ptr += src_pitch;
534 }
535
536 // current_coeff += filter_size * PIXELS_AT_A_TIME;
537 80 current_coeff_SIMD += 8; // in number of __m512i
538
539 };
540
541 // Process the 'safe zone' where direct full unaligned loads are acceptable.
542
4/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 18 → 16 taken 1 time.
✓ Branch 18 → 19 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 18 → 16 taken 1 time.
✓ Branch 18 → 19 taken 75 times.
78 for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)
543 {
544
1/2
✓ Branch 16 → 17 taken 1 time.
✗ Branch 16 → 26 not taken.
2 do_h_integer_core(std::false_type{});
545 }
546
547 // Process the potentially 'unsafe zone' near the image edge, using safe masked loading.
548
4/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 22 → 20 taken 2 times.
✓ Branch 22 → 23 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks4_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 22 → 20 taken 76 times.
✓ Branch 22 → 23 taken 75 times.
154 for (; x < width; x += PIXELS_AT_A_TIME)
549 {
550
1/2
✓ Branch 20 → 21 taken 76 times.
✗ Branch 20 → 26 not taken.
78 do_h_integer_core(std::true_type{});
551 }
552 }
553 76 }
554
555 // filter size up to 8
556 // 64 target uint8_t pixels at a time
557 // 128-byte source loads (128 uint8_t pixels)
558 // maximum permute index is 128 for _mm512_maskz_permutex2var_epi8 (uint8_t)
559 // support VNNI and madd FMA
560
561 // filter size up to 16
562 // 32 target uint8_t pixels at a time
563 // 128-byte source loads (128 uint8_t pixels)
564 // maximum permute index is 128 for _mm512_maskz_permutex2var_epi8 (uint8_t)
565
566 // uint16_t
567
568 // filter size up to 4
569 // 32 target uint16_t pixels at a time
570 // 128-byte source loads (64 uint16_t pixels)
571 // maximum permute index is 64 for _mm512_permutex2var_epi16 (uint16_t)
572 // making lo-hi unpacking with single permutex2var operation and optional VNNI FMA
573
574 // filter size up to 8
575 // 64 target uint16_t pixels at a time in 4 groups of 16
576 // 128-byte source loads (64 uint16_t pixels), 2 groups of 128 byte source loads for each 16 output samples,
577 // expect to support /2 downsize (used in ConvertTo42x with default bicubic too)
578 // maximum permute index is 64 for _mm512_permutex2var_epi16 (uint16_t)
579 // support VNNI and madd FMA
580 // checker: (16/*iSamplesInTheGroup*/, 64/*permutex_index_diff_limit*/, 8/*kernel_size*/))
581
582 template <bool AdvancePerm, bool UseVNNI>
583 AVS_FORCEINLINE static void process_row_pair(
584 // 1. Accumulators (Modified across calls)
585 __m512i& res_lo, __m512i& res_hi,
586 __m512i& res_32_63lo, __m512i& res_32_63hi,
587 // 2. Permutation Vectors (Modified across calls)
588 __m512i& p_lo, __m512i& p_hi,
589 __m512i& p_32_lo, __m512i& p_32_hi,
590 // 3. Coefficients (Read-only)
591 const __m512i& c_lo, const __m512i& c_hi,
592 const __m512i& c_32_63lo, const __m512i& c_32_63hi,
593 // 4. Source Data and Constants
594 const __m512i& d0_15, const __m512i& d16_31,
595 const __m512i& d32_47, const __m512i& d48_63,
596 const __m512i& d2_0_15, const __m512i& d2_16_31,
597 const __m512i& d2_32_47, const __m512i& d2_48_63,
598 const __mmask32 &k_hi, const __m512i &v_two)
599 {
600 // Generate source vectors via permutations
601 auto src_lo = _mm512_mask_blend_epi16(k_hi,
602 _mm512_permutex2var_epi16(d0_15, p_lo, d2_0_15),
603 _mm512_permutex2var_epi16(d16_31, p_lo, d2_16_31));
604
605 auto src_hi = _mm512_mask_blend_epi16(k_hi,
606 _mm512_permutex2var_epi16(d0_15, p_hi, d2_0_15),
607 _mm512_permutex2var_epi16(d16_31, p_hi, d2_16_31));
608
609 auto src_32_63lo = _mm512_mask_blend_epi16(k_hi,
610 _mm512_permutex2var_epi16(d32_47, p_32_lo, d2_32_47),
611 _mm512_permutex2var_epi16(d48_63, p_32_lo, d2_48_63));
612
613 auto src_32_63hi = _mm512_mask_blend_epi16(k_hi,
614 _mm512_permutex2var_epi16(d32_47, p_32_hi, d2_32_47),
615 _mm512_permutex2var_epi16(d48_63, p_32_hi, d2_48_63));
616
617 // Accumulate results
618 if constexpr (UseVNNI) {
619 res_lo = _mm512_dpwssd_epi32(res_lo, src_lo, c_lo);
620 res_hi = _mm512_dpwssd_epi32(res_hi, src_hi, c_hi);
621 res_32_63lo = _mm512_dpwssd_epi32(res_32_63lo, src_32_63lo, c_32_63lo);
622 res_32_63hi = _mm512_dpwssd_epi32(res_32_63hi, src_32_63hi, c_32_63hi);
623 }
624 else {
625 res_lo = _mm512_add_epi32(res_lo, _mm512_madd_epi16(src_lo, c_lo));
626 res_hi = _mm512_add_epi32(res_hi, _mm512_madd_epi16(src_hi, c_hi));
627 res_32_63lo = _mm512_add_epi32(res_32_63lo, _mm512_madd_epi16(src_32_63lo, c_32_63lo));
628 res_32_63hi = _mm512_add_epi32(res_32_63hi, _mm512_madd_epi16(src_32_63hi, c_32_63hi));
629 }
630
631 if constexpr (AdvancePerm) {
632 p_lo = _mm512_add_epi16(p_lo, v_two);
633 p_hi = _mm512_add_epi16(p_hi, v_two);
634 p_32_lo = _mm512_add_epi16(p_32_lo, v_two);
635 p_32_hi = _mm512_add_epi16(p_32_hi, v_two);
636 }
637 }
638
639 // filter size up to 4
640 // 64 target uint16_t pixels at a time in 2 groups of 32
641 // 128-byte source loads (64 uint16_t pixels)
642 // maximum permute index is 64 for _mm512_permutex2var_epi16 (uint16_t)
643 // making lo-hi unpacking with single permutex2var operation and optional VNNI FMA
644
645 // filter size up to 8
646 // 64 target uint16_t pixels at a time in 2 groups of 32
647 // 128-byte source loads (64 uint16_t pixels)
648 // maximum permute index is 64 for _mm512_permutex2var_epi16 (uint16_t)
649 // support VNNI and madd FMA
650
651 // filter size up to 8
652 // 32 target uint16_t pixels at a time
653 // 128-byte source loads (64 uint16_t pixels), 2 groups of 128 byte source loads for each 16 output samples, expect to support /2 downsize (used in ConvertTo42x with default bicubic too)
654 // maximum permute index is 64 for _mm512_permutex2var_epi16 (uint16_t)
655 // support VNNI and madd FMA
656 // checker function is program->resize_h_planar_gather_permutex_vstripe_check(16/*iSamplesInTheGroup*/, 64/*permutex_index_diff_limit*/, 8/*kernel_size*/))
657
658 // filter size up to 8
659 // 32 target uint16_t pixels at a time
660 // 128-byte source loads (64 uint16_t pixels)
661 // maximum permute index is 64 for _mm512_permutex2var_epi16 (uint16_t)
662 // support VNNI and madd FMA
663
664 // filter size up to 16
665 // 32 target uint16_t pixels at a time
666 // 128-byte source loads (64 uint16_t pixels)
667 // maximum permute index is 64 for _mm512_permutex2var_epi16 (uint16_t)
668 // support VNNI and madd FMA
669
670 // filter size up to 8, pretransposed coefficients
671 // 64 target uint8_t pixels at a time
672 // 128-byte source loads (2x64 uint8_t pixels)
673 template<bool UseVNNI>
674 5 void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_pretransposed_coeffs_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)
675 {
676 5 constexpr int PIXELS_AT_A_TIME = 64;
677
678
2/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 4 not taken.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 2 → 3 taken 4 times.
✗ Branch 2 → 4 not taken.
5 const int width_safe_mod = (program->safelimit_128_pixels_each64th_target.overread_possible ? program->safelimit_128_pixels_each64th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;
679
680
2/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 4 times.
5 assert(program->filter_size_real <= 8);
681
2/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 4 times.
5 assert(program->target_size_alignment >= 64);
682 assert(FRAME_ALIGN >= 64);
683
2/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 4 times.
5 assert(program->filter_size_alignment >= 8);
684
685 5 const int max_scanlines = program->max_scanlines;
686
687 5 __m512i rounder = _mm512_set1_epi32(1 << (FPScale8bits - 1));
688
689
4/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 14 taken 1 time.
✓ Branch 24 → 25 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 14 taken 4 times.
✓ Branch 24 → 25 taken 4 times.
10 for (int y_from = 0; y_from < height; y_from += max_scanlines)
690 {
691 5 int y_to = std::min(y_from + max_scanlines, height);
692
693 5 const __m512i* AVS_RESTRICT current_coeff_SIMD = (__m512i*)program->pixel_coefficient_AVX512_H;
694
695 5 int x = 0;
696
697 14 auto do_h_integer_core = [&](auto partial_load) {
698 9 __m512i one_epi16 = _mm512_set1_epi16(1);
699
700 9 const __m512i coef_r0r1_0_31lo = _mm512_load_si512(current_coeff_SIMD + 0);
701 9 const __m512i coef_r0r1_0_31hi = _mm512_load_si512(current_coeff_SIMD + 1);
702 9 const __m512i coef_r0r1_32_63lo = _mm512_load_si512(current_coeff_SIMD + 2);
703 9 const __m512i coef_r0r1_32_63hi = _mm512_load_si512(current_coeff_SIMD + 3);
704 9 const __m512i coef_r2r3_0_31lo = _mm512_load_si512(current_coeff_SIMD + 4);
705 9 const __m512i coef_r2r3_0_31hi = _mm512_load_si512(current_coeff_SIMD + 5);
706 9 const __m512i coef_r2r3_32_63lo = _mm512_load_si512(current_coeff_SIMD + 6);
707 9 const __m512i coef_r2r3_32_63hi = _mm512_load_si512(current_coeff_SIMD + 7);
708 9 const __m512i coef_r4r5_0_31lo = _mm512_load_si512(current_coeff_SIMD + 8);
709 9 const __m512i coef_r4r5_0_31hi = _mm512_load_si512(current_coeff_SIMD + 9);
710 9 const __m512i coef_r4r5_32_63lo = _mm512_load_si512(current_coeff_SIMD + 10);
711 9 const __m512i coef_r4r5_32_63hi = _mm512_load_si512(current_coeff_SIMD + 11);
712 9 const __m512i coef_r6r7_0_31lo = _mm512_load_si512(current_coeff_SIMD + 12);
713 9 const __m512i coef_r6r7_0_31hi = _mm512_load_si512(current_coeff_SIMD + 13);
714 9 const __m512i coef_r6r7_32_63lo = _mm512_load_si512(current_coeff_SIMD + 14);
715 9 const __m512i coef_r6r7_32_63hi = _mm512_load_si512(current_coeff_SIMD + 15);
716
717 9 __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x]));
718 9 __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16]));
719 9 __m512i perm_0_32_47 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 32]));
720 9 __m512i perm_0_48_63 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 48]));
721
722 9 int iStart = program->pixel_offset[x];
723 9 __m512i m512i_Start = _mm512_set1_epi32(iStart);
724
725 9 perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start);
726 9 perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start);
727 9 perm_0_32_47 = _mm512_sub_epi32(perm_0_32_47, m512i_Start);
728 9 perm_0_48_63 = _mm512_sub_epi32(perm_0_48_63, m512i_Start);
729
730 9 __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);
731 9 __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);
732 9 __m256i m256i_perm_0_32_47 = _mm512_cvtepi32_epi16(perm_0_32_47);
733 9 __m256i m256i_perm_0_48_63 = _mm512_cvtepi32_epi16(perm_0_48_63);
734
735 18 __m512i perm_0_0_31 = _mm512_inserti64x4(_mm512_castsi256_si512(m256i_perm_0_0_15), m256i_perm_0_16_31, 1);
736 18 __m512i perm_0_32_63 = _mm512_inserti64x4(_mm512_castsi256_si512(m256i_perm_0_32_47), m256i_perm_0_48_63, 1);
737
738 9 __m512i perm_1_0_31 = _mm512_add_epi16(perm_0_0_31, one_epi16);
739 9 __m512i perm_1_32_63 = _mm512_add_epi16(perm_0_32_63, one_epi16);
740
741 9 const __m512i perm_r0r1_0_31lo = _mm512_unpacklo_epi16(perm_0_0_31, perm_1_0_31);
742 9 const __m512i perm_r0r1_0_31hi = _mm512_unpackhi_epi16(perm_0_0_31, perm_1_0_31);
743 9 const __m512i perm_r0r1_32_63lo = _mm512_unpacklo_epi16(perm_0_32_63, perm_1_32_63);
744 9 const __m512i perm_r0r1_32_63hi = _mm512_unpackhi_epi16(perm_0_32_63, perm_1_32_63);
745
746 9 const __m512i two_epi16 = _mm512_set1_epi16(2);
747
748 9 __m512i wi_r0r1_0_31lo={},sa_r0r1_0_31lo={},wi_r0r1_0_31hi={},sa_r0r1_0_31hi={};
749 9 __m512i wi_r0r1_32_63lo={},sa_r0r1_32_63lo={},wi_r0r1_32_63hi={},sa_r0r1_32_63hi={};
750 9 __m512i wi_r2r3_0_31lo={},sa_r2r3_0_31lo={},wi_r2r3_0_31hi={},sa_r2r3_0_31hi={};
751 9 __m512i wi_r2r3_32_63lo={},sa_r2r3_32_63lo={},wi_r2r3_32_63hi={},sa_r2r3_32_63hi={};
752 9 __m512i wi_r4r5_0_31lo={},sa_r4r5_0_31lo={},wi_r4r5_0_31hi={},sa_r4r5_0_31hi={};
753 9 __m512i wi_r4r5_32_63lo={},sa_r4r5_32_63lo={},wi_r4r5_32_63hi={},sa_r4r5_32_63hi={};
754 9 __m512i wi_r6r7_0_31lo={},sa_r6r7_0_31lo={},wi_r6r7_0_31hi={},sa_r6r7_0_31hi={};
755 9 __m512i wi_r6r7_32_63lo={},sa_r6r7_32_63lo={},wi_r6r7_32_63hi={},sa_r6r7_32_63hi={};
756 if constexpr (!UseVNNI) {
757 3 const __m512i c_8w = _mm512_set1_epi16(8);
758 51 auto make_wi_sa = [&](__m512i p, __m512i& wi, __m512i& sa) {
759 48 wi = _mm512_srli_epi16(p, 1);
760 96 sa = _mm512_and_si512(_mm512_slli_epi16(p, 3), c_8w);
761 };
762 3 __m512i p_lo = perm_r0r1_0_31lo, p_hi = perm_r0r1_0_31hi;
763 3 __m512i p_lo2 = perm_r0r1_32_63lo, p_hi2 = perm_r0r1_32_63hi;
764 3 make_wi_sa(p_lo, wi_r0r1_0_31lo, sa_r0r1_0_31lo); make_wi_sa(p_hi, wi_r0r1_0_31hi, sa_r0r1_0_31hi);
765 3 make_wi_sa(p_lo2, wi_r0r1_32_63lo, sa_r0r1_32_63lo); make_wi_sa(p_hi2, wi_r0r1_32_63hi, sa_r0r1_32_63hi);
766 6 p_lo = _mm512_add_epi16(p_lo, two_epi16); p_hi = _mm512_add_epi16(p_hi, two_epi16);
767 3 p_lo2 = _mm512_add_epi16(p_lo2, two_epi16); p_hi2 = _mm512_add_epi16(p_hi2, two_epi16);
768 3 make_wi_sa(p_lo, wi_r2r3_0_31lo, sa_r2r3_0_31lo); make_wi_sa(p_hi, wi_r2r3_0_31hi, sa_r2r3_0_31hi);
769 3 make_wi_sa(p_lo2, wi_r2r3_32_63lo, sa_r2r3_32_63lo); make_wi_sa(p_hi2, wi_r2r3_32_63hi, sa_r2r3_32_63hi);
770 6 p_lo = _mm512_add_epi16(p_lo, two_epi16); p_hi = _mm512_add_epi16(p_hi, two_epi16);
771 3 p_lo2 = _mm512_add_epi16(p_lo2, two_epi16); p_hi2 = _mm512_add_epi16(p_hi2, two_epi16);
772 3 make_wi_sa(p_lo, wi_r4r5_0_31lo, sa_r4r5_0_31lo); make_wi_sa(p_hi, wi_r4r5_0_31hi, sa_r4r5_0_31hi);
773 3 make_wi_sa(p_lo2, wi_r4r5_32_63lo, sa_r4r5_32_63lo); make_wi_sa(p_hi2, wi_r4r5_32_63hi, sa_r4r5_32_63hi);
774 6 p_lo = _mm512_add_epi16(p_lo, two_epi16); p_hi = _mm512_add_epi16(p_hi, two_epi16);
775 3 p_lo2 = _mm512_add_epi16(p_lo2, two_epi16); p_hi2 = _mm512_add_epi16(p_hi2, two_epi16);
776 3 make_wi_sa(p_lo, wi_r6r7_0_31lo, sa_r6r7_0_31lo); make_wi_sa(p_hi, wi_r6r7_0_31hi, sa_r6r7_0_31hi);
777 3 make_wi_sa(p_lo2, wi_r6r7_32_63lo, sa_r6r7_32_63lo); make_wi_sa(p_hi2, wi_r6r7_32_63hi, sa_r6r7_32_63hi);
778 }
779
780 9 uint8_t* AVS_RESTRICT dst_ptr = dst8 + x + y_from * dst_pitch;
781 9 const uint8_t* src_ptr = src8 + iStart + y_from * src_pitch;
782
783 9 const int remaining = program->source_size - iStart;
784 9 __mmask64 k1 = _bzhi_u64(~0ULL, remaining);
785 9 const __mmask64 k2 = _bzhi_u64(~0ULL, std::max(0, remaining - 64));
786 9 const __mmask64 k_zh8 = 0x5555555555555555ULL;
787
788
8/8
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 499 → 153 taken 5 times.
✓ Branch 499 → 500 taken 1 time.
✓ Branch 503 → 153 taken 10 times.
✓ Branch 503 → 504 taken 2 times.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 233 → 111 taken 5 times.
✓ Branch 233 → 234 taken 1 time.
✓ Branch 237 → 111 taken 37 times.
✓ Branch 237 → 238 taken 5 times.
66 for (int y = y_from; y < y_to; y++)
789 {
790 __m512i data_src, data_src2;
791
792 57 __m512i perm_rNrNp1_0_31lo_w = perm_r0r1_0_31lo;
793 57 __m512i perm_rNrNp1_0_31hi_w = perm_r0r1_0_31hi;
794 57 __m512i perm_rNrNp1_32_63lo_w = perm_r0r1_32_63lo;
795 57 __m512i perm_rNrNp1_32_63hi_w = perm_r0r1_32_63hi;
796
797 if constexpr (partial_load) {
798 47 data_src = _mm512_maskz_loadu_epi8(k1, src_ptr);
799 84 data_src2 = _mm512_maskz_loadu_epi8(k2, src_ptr + 64);
800 }
801 else {
802 10 data_src = _mm512_loadu_si512(src_ptr);
803 15 data_src2 = _mm512_loadu_si512(src_ptr + 64);
804 }
805
806 // rows 0..1
807 __m512i src_r0r1_0_31lo, src_r0r1_0_31hi, src_r0r1_32_63lo, src_r0r1_32_63hi;
808 if constexpr (UseVNNI) {
809 42 src_r0r1_0_31lo = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);
810 42 src_r0r1_0_31hi = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);
811 42 src_r0r1_32_63lo = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_32_63lo_w, data_src2);
812 42 src_r0r1_32_63hi = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_32_63hi_w, data_src2);
813 } else {
814 15 src_r0r1_0_31lo = _permutex2var_epi8_sim_get32(wi_r0r1_0_31lo, sa_r0r1_0_31lo, data_src, data_src2);
815 15 src_r0r1_0_31hi = _permutex2var_epi8_sim_get32(wi_r0r1_0_31hi, sa_r0r1_0_31hi, data_src, data_src2);
816 15 src_r0r1_32_63lo = _permutex2var_epi8_sim_get32(wi_r0r1_32_63lo, sa_r0r1_32_63lo, data_src, data_src2);
817 30 src_r0r1_32_63hi = _permutex2var_epi8_sim_get32(wi_r0r1_32_63hi, sa_r0r1_32_63hi, data_src, data_src2);
818 }
819
820 // for r2r3
821 57 perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);
822 57 perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);
823 57 perm_rNrNp1_32_63lo_w = _mm512_add_epi16(perm_rNrNp1_32_63lo_w, two_epi16);
824 57 perm_rNrNp1_32_63hi_w = _mm512_add_epi16(perm_rNrNp1_32_63hi_w, two_epi16);
825
826 __m512i src_r2r3_0_31lo, src_r2r3_0_31hi, src_r2r3_32_63lo, src_r2r3_32_63hi;
827 if constexpr (UseVNNI) {
828 42 src_r2r3_0_31lo = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);
829 42 src_r2r3_0_31hi = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);
830 42 src_r2r3_32_63lo = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_32_63lo_w, data_src2);
831 42 src_r2r3_32_63hi = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_32_63hi_w, data_src2);
832 } else {
833 15 src_r2r3_0_31lo = _permutex2var_epi8_sim_get32(wi_r2r3_0_31lo, sa_r2r3_0_31lo, data_src, data_src2);
834 15 src_r2r3_0_31hi = _permutex2var_epi8_sim_get32(wi_r2r3_0_31hi, sa_r2r3_0_31hi, data_src, data_src2);
835 15 src_r2r3_32_63lo = _permutex2var_epi8_sim_get32(wi_r2r3_32_63lo, sa_r2r3_32_63lo, data_src, data_src2);
836 30 src_r2r3_32_63hi = _permutex2var_epi8_sim_get32(wi_r2r3_32_63hi, sa_r2r3_32_63hi, data_src, data_src2);
837 }
838
839 // for r4r5
840 57 perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);
841 57 perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);
842 57 perm_rNrNp1_32_63lo_w = _mm512_add_epi16(perm_rNrNp1_32_63lo_w, two_epi16);
843 57 perm_rNrNp1_32_63hi_w = _mm512_add_epi16(perm_rNrNp1_32_63hi_w, two_epi16);
844
845 __m512i result_0_31lo, result_0_31hi;
846 __m512i result_32_63lo, result_32_63hi;
847
848 if constexpr (UseVNNI)
849 {
850 84 result_0_31lo = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31lo, coef_r0r1_0_31lo);
851 42 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r2r3_0_31lo, coef_r2r3_0_31lo);
852 84 result_0_31hi = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31hi, coef_r0r1_0_31hi);
853 42 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r2r3_0_31hi, coef_r2r3_0_31hi);
854 84 result_32_63lo = _mm512_dpwssd_epi32(rounder, src_r0r1_32_63lo, coef_r0r1_32_63lo);
855 42 result_32_63lo = _mm512_dpwssd_epi32(result_32_63lo, src_r2r3_32_63lo, coef_r2r3_32_63lo);
856 84 result_32_63hi = _mm512_dpwssd_epi32(rounder, src_r0r1_32_63hi, coef_r0r1_32_63hi);
857 42 result_32_63hi = _mm512_dpwssd_epi32(result_32_63hi, src_r2r3_32_63hi, coef_r2r3_32_63hi);
858 }
859 else
860 {
861 45 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo));
862 45 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi));
863 45 result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63lo, coef_r0r1_32_63lo), _mm512_madd_epi16(src_r2r3_32_63lo, coef_r2r3_32_63lo));
864 30 result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63hi, coef_r0r1_32_63hi), _mm512_madd_epi16(src_r2r3_32_63hi, coef_r2r3_32_63hi));
865 }
866
867 // rows 4..5
868 __m512i src_r4r5_0_31lo, src_r4r5_0_31hi, src_r4r5_32_63lo, src_r4r5_32_63hi;
869 if constexpr (UseVNNI) {
870 42 src_r4r5_0_31lo = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);
871 42 src_r4r5_0_31hi = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);
872 42 src_r4r5_32_63lo = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_32_63lo_w, data_src2);
873 42 src_r4r5_32_63hi = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_32_63hi_w, data_src2);
874 } else {
875 15 src_r4r5_0_31lo = _permutex2var_epi8_sim_get32(wi_r4r5_0_31lo, sa_r4r5_0_31lo, data_src, data_src2);
876 15 src_r4r5_0_31hi = _permutex2var_epi8_sim_get32(wi_r4r5_0_31hi, sa_r4r5_0_31hi, data_src, data_src2);
877 15 src_r4r5_32_63lo = _permutex2var_epi8_sim_get32(wi_r4r5_32_63lo, sa_r4r5_32_63lo, data_src, data_src2);
878 30 src_r4r5_32_63hi = _permutex2var_epi8_sim_get32(wi_r4r5_32_63hi, sa_r4r5_32_63hi, data_src, data_src2);
879 }
880
881 // for r6r7
882 57 perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);
883 57 perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);
884 57 perm_rNrNp1_32_63lo_w = _mm512_add_epi16(perm_rNrNp1_32_63lo_w, two_epi16);
885 57 perm_rNrNp1_32_63hi_w = _mm512_add_epi16(perm_rNrNp1_32_63hi_w, two_epi16);
886
887 __m512i src_r6r7_0_31lo, src_r6r7_0_31hi, src_r6r7_32_63lo, src_r6r7_32_63hi;
888 if constexpr (UseVNNI) {
889 42 src_r6r7_0_31lo = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);
890 42 src_r6r7_0_31hi = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);
891 42 src_r6r7_32_63lo = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_32_63lo_w, data_src2);
892 42 src_r6r7_32_63hi = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_32_63hi_w, data_src2);
893 } else {
894 15 src_r6r7_0_31lo = _permutex2var_epi8_sim_get32(wi_r6r7_0_31lo, sa_r6r7_0_31lo, data_src, data_src2);
895 15 src_r6r7_0_31hi = _permutex2var_epi8_sim_get32(wi_r6r7_0_31hi, sa_r6r7_0_31hi, data_src, data_src2);
896 15 src_r6r7_32_63lo = _permutex2var_epi8_sim_get32(wi_r6r7_32_63lo, sa_r6r7_32_63lo, data_src, data_src2);
897 30 src_r6r7_32_63hi = _permutex2var_epi8_sim_get32(wi_r6r7_32_63hi, sa_r6r7_32_63hi, data_src, data_src2);
898 }
899
900 if constexpr (UseVNNI)
901 {
902 42 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r4r5_0_31lo, coef_r4r5_0_31lo);
903 42 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r6r7_0_31lo, coef_r6r7_0_31lo);
904 42 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r4r5_0_31hi, coef_r4r5_0_31hi);
905 42 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r6r7_0_31hi, coef_r6r7_0_31hi);
906 42 result_32_63lo = _mm512_dpwssd_epi32(result_32_63lo, src_r4r5_32_63lo, coef_r4r5_32_63lo);
907 42 result_32_63lo = _mm512_dpwssd_epi32(result_32_63lo, src_r6r7_32_63lo, coef_r6r7_32_63lo);
908 42 result_32_63hi = _mm512_dpwssd_epi32(result_32_63hi, src_r4r5_32_63hi, coef_r4r5_32_63hi);
909 42 result_32_63hi = _mm512_dpwssd_epi32(result_32_63hi, src_r6r7_32_63hi, coef_r6r7_32_63hi);
910 // rounding VNNI in first FMA already summed
911 }
912 else
913 {
914 30 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31lo, coef_r4r5_0_31lo), result_0_31lo);
915 30 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31hi, coef_r4r5_0_31hi), result_0_31hi);
916 30 result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_32_63lo, coef_r4r5_32_63lo), result_32_63lo);
917 30 result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_32_63hi, coef_r4r5_32_63hi), result_32_63hi);
918
919 30 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31lo, coef_r6r7_0_31lo), result_0_31lo);
920 30 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31hi, coef_r6r7_0_31hi), result_0_31hi);
921 30 result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_32_63lo, coef_r6r7_32_63lo), result_32_63lo);
922 15 result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_32_63hi, coef_r6r7_32_63hi), result_32_63hi);
923
924 15 result_0_31lo = _mm512_add_epi32(result_0_31lo, rounder);
925 15 result_0_31hi = _mm512_add_epi32(result_0_31hi, rounder);
926 15 result_32_63lo = _mm512_add_epi32(result_32_63lo, rounder);
927 30 result_32_63hi = _mm512_add_epi32(result_32_63hi, rounder);
928 }
929
930 57 result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale8bits);
931 57 result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale8bits);
932 57 result_32_63lo = _mm512_srai_epi32(result_32_63lo, FPScale8bits);
933 57 result_32_63hi = _mm512_srai_epi32(result_32_63hi, FPScale8bits);
934
935 57 __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);
936 57 __m512i result_32_63_int16 = _mm512_packus_epi32(result_32_63lo, result_32_63hi);
937
938 57 __m256i result_0_31_u8 = _mm512_cvtusepi16_epi8(result_0_31_int16);
939 57 __m256i result_32_63_u8 = _mm512_cvtusepi16_epi8(result_32_63_int16);
940
941 114 _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr), _mm512_inserti64x4(_mm512_castsi256_si512(result_0_31_u8), result_32_63_u8, 1));
942
943 57 dst_ptr += dst_pitch;
944 57 src_ptr += src_pitch;
945 }
946
947 9 current_coeff_SIMD += 16;
948 };
949
950
4/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 18 → 16 taken 1 time.
✓ Branch 18 → 19 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 18 → 16 taken 1 time.
✓ Branch 18 → 19 taken 4 times.
7 for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)
951 {
952
1/2
✓ Branch 16 → 17 taken 1 time.
✗ Branch 16 → 26 not taken.
2 do_h_integer_core(std::false_type{});
953 }
954
955
4/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 22 → 20 taken 2 times.
✓ Branch 22 → 23 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks8_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 22 → 20 taken 5 times.
✓ Branch 22 → 23 taken 4 times.
12 for (; x < width; x += PIXELS_AT_A_TIME)
956 {
957
1/2
✓ Branch 20 → 21 taken 5 times.
✗ Branch 20 → 26 not taken.
7 do_h_integer_core(std::true_type{});
958 }
959 }
960 5 }
961
962 // filter size up to 16, pretransposed coefficients
963 // 32 target uint8_t pixels at a time
964 // 128-byte source loads (2x64 uint8_t pixels)
965 template<bool UseVNNI>
966 11 void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_pretransposed_coeffs_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)
967 {
968 11 constexpr int PIXELS_AT_A_TIME = 32;
969
970
2/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 4 not taken.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 2 → 3 taken 10 times.
✗ Branch 2 → 4 not taken.
11 const int width_safe_mod = (program->safelimit_128_pixels_each64th_target.overread_possible ? program->safelimit_128_pixels_each64th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;
971
972
2/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 10 times.
11 assert(program->filter_size_real <= 16);
973
2/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 10 times.
11 assert(program->target_size_alignment >= 32);
974 assert(FRAME_ALIGN >= 32);
975
2/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 10 times.
11 assert(program->filter_size_alignment >= 16);
976
977 11 const int max_scanlines = program->max_scanlines;
978
979 11 __m512i rounder = _mm512_set1_epi32(1 << (FPScale8bits - 1));
980
981
4/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 14 taken 1 time.
✓ Branch 24 → 25 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 14 taken 10 times.
✓ Branch 24 → 25 taken 10 times.
22 for (int y_from = 0; y_from < height; y_from += max_scanlines)
982 {
983 11 int y_to = std::min(y_from + max_scanlines, height);
984
985 11 const __m512i* AVS_RESTRICT current_coeff_SIMD = (__m512i*)program->pixel_coefficient_AVX512_H;
986
987 11 int x = 0;
988
989 32 auto do_h_integer_core = [&](auto partial_load) {
990 21 __m512i one_epi16 = _mm512_set1_epi16(1);
991
992 21 const __m512i coef_r0r1_0_31lo = _mm512_load_si512(current_coeff_SIMD + 0);
993 21 const __m512i coef_r0r1_0_31hi = _mm512_load_si512(current_coeff_SIMD + 1);
994 21 const __m512i coef_r2r3_0_31lo = _mm512_load_si512(current_coeff_SIMD + 2);
995 21 const __m512i coef_r2r3_0_31hi = _mm512_load_si512(current_coeff_SIMD + 3);
996 21 const __m512i coef_r4r5_0_31lo = _mm512_load_si512(current_coeff_SIMD + 4);
997 21 const __m512i coef_r4r5_0_31hi = _mm512_load_si512(current_coeff_SIMD + 5);
998 21 const __m512i coef_r6r7_0_31lo = _mm512_load_si512(current_coeff_SIMD + 6);
999 21 const __m512i coef_r6r7_0_31hi = _mm512_load_si512(current_coeff_SIMD + 7);
1000 21 const __m512i coef_r8r9_0_31lo = _mm512_load_si512(current_coeff_SIMD + 8);
1001 21 const __m512i coef_r8r9_0_31hi = _mm512_load_si512(current_coeff_SIMD + 9);
1002 21 const __m512i coef_r10r11_0_31lo = _mm512_load_si512(current_coeff_SIMD + 10);
1003 21 const __m512i coef_r10r11_0_31hi = _mm512_load_si512(current_coeff_SIMD + 11);
1004 21 const __m512i coef_r12r13_0_31lo = _mm512_load_si512(current_coeff_SIMD + 12);
1005 21 const __m512i coef_r12r13_0_31hi = _mm512_load_si512(current_coeff_SIMD + 13);
1006 21 const __m512i coef_r14r15_0_31lo = _mm512_load_si512(current_coeff_SIMD + 14);
1007 21 const __m512i coef_r14r15_0_31hi = _mm512_load_si512(current_coeff_SIMD + 15);
1008
1009 21 __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x]));
1010 21 __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16]));
1011
1012 21 int iStart = program->pixel_offset[x];
1013 21 __m512i m512i_Start = _mm512_set1_epi32(iStart);
1014
1015 21 perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start);
1016 21 perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start);
1017
1018 21 __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);
1019 21 __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);
1020
1021 42 __m512i perm_0_0_31 = _mm512_inserti64x4(_mm512_castsi256_si512(m256i_perm_0_0_15), m256i_perm_0_16_31, 1);
1022 21 __m512i perm_1_0_31 = _mm512_add_epi16(perm_0_0_31, one_epi16);
1023
1024 21 const __m512i perm_r0r1_0_31lo = _mm512_unpacklo_epi16(perm_0_0_31, perm_1_0_31);
1025 21 const __m512i perm_r0r1_0_31hi = _mm512_unpackhi_epi16(perm_0_0_31, perm_1_0_31);
1026
1027 21 const __m512i two_epi16 = _mm512_set1_epi16(2);
1028
1029 // BASE path: precompute word-index (wi) and shift-amount (sa) for each tap-pair perm.
1030 // perm_rNrNp1 holds 32 x 16-bit byte addresses; wi = addr>>1 selects the 16-bit word in
1031 // {data_src, data_src2}, sa = (addr<<3)&8 selects high (1) or low (0) byte within that word.
1032 // Precomputing here eliminates ~12 instructions/gather (cvtepu8+extract+slli+srli+maskz_mov)
1033 // from the hot y-loop, leaving only the 3-instruction sim_get32 core per tap-pair.
1034 21 __m512i wi_r0r1_lo={},sa_r0r1_lo={},wi_r0r1_hi={},sa_r0r1_hi={};
1035 21 __m512i wi_r2r3_lo={},sa_r2r3_lo={},wi_r2r3_hi={},sa_r2r3_hi={};
1036 21 __m512i wi_r4r5_lo={},sa_r4r5_lo={},wi_r4r5_hi={},sa_r4r5_hi={};
1037 21 __m512i wi_r6r7_lo={},sa_r6r7_lo={},wi_r6r7_hi={},sa_r6r7_hi={};
1038 21 __m512i wi_r8r9_lo={},sa_r8r9_lo={},wi_r8r9_hi={},sa_r8r9_hi={};
1039 21 __m512i wi_r10r11_lo={},sa_r10r11_lo={},wi_r10r11_hi={},sa_r10r11_hi={};
1040 21 __m512i wi_r12r13_lo={},sa_r12r13_lo={},wi_r12r13_hi={},sa_r12r13_hi={};
1041 21 __m512i wi_r14r15_lo={},sa_r14r15_lo={},wi_r14r15_hi={},sa_r14r15_hi={};
1042 if constexpr (!UseVNNI) {
1043 6 const __m512i c_8w = _mm512_set1_epi16(8);
1044 102 auto make_wi_sa = [&](__m512i p, __m512i& wi, __m512i& sa) {
1045 96 wi = _mm512_srli_epi16(p, 1);
1046 192 sa = _mm512_and_si512(_mm512_slli_epi16(p, 3), c_8w);
1047 };
1048 6 __m512i p_lo = perm_r0r1_0_31lo, p_hi = perm_r0r1_0_31hi;
1049 6 make_wi_sa(p_lo, wi_r0r1_lo, sa_r0r1_lo); make_wi_sa(p_hi, wi_r0r1_hi, sa_r0r1_hi);
1050 6 p_lo = _mm512_add_epi16(p_lo, two_epi16); p_hi = _mm512_add_epi16(p_hi, two_epi16);
1051 6 make_wi_sa(p_lo, wi_r2r3_lo, sa_r2r3_lo); make_wi_sa(p_hi, wi_r2r3_hi, sa_r2r3_hi);
1052 6 p_lo = _mm512_add_epi16(p_lo, two_epi16); p_hi = _mm512_add_epi16(p_hi, two_epi16);
1053 6 make_wi_sa(p_lo, wi_r4r5_lo, sa_r4r5_lo); make_wi_sa(p_hi, wi_r4r5_hi, sa_r4r5_hi);
1054 6 p_lo = _mm512_add_epi16(p_lo, two_epi16); p_hi = _mm512_add_epi16(p_hi, two_epi16);
1055 6 make_wi_sa(p_lo, wi_r6r7_lo, sa_r6r7_lo); make_wi_sa(p_hi, wi_r6r7_hi, sa_r6r7_hi);
1056 6 p_lo = _mm512_add_epi16(p_lo, two_epi16); p_hi = _mm512_add_epi16(p_hi, two_epi16);
1057 6 make_wi_sa(p_lo, wi_r8r9_lo, sa_r8r9_lo); make_wi_sa(p_hi, wi_r8r9_hi, sa_r8r9_hi);
1058 6 p_lo = _mm512_add_epi16(p_lo, two_epi16); p_hi = _mm512_add_epi16(p_hi, two_epi16);
1059 6 make_wi_sa(p_lo, wi_r10r11_lo, sa_r10r11_lo); make_wi_sa(p_hi, wi_r10r11_hi, sa_r10r11_hi);
1060 6 p_lo = _mm512_add_epi16(p_lo, two_epi16); p_hi = _mm512_add_epi16(p_hi, two_epi16);
1061 6 make_wi_sa(p_lo, wi_r12r13_lo, sa_r12r13_lo); make_wi_sa(p_hi, wi_r12r13_hi, sa_r12r13_hi);
1062 6 p_lo = _mm512_add_epi16(p_lo, two_epi16); p_hi = _mm512_add_epi16(p_hi, two_epi16);
1063 6 make_wi_sa(p_lo, wi_r14r15_lo, sa_r14r15_lo); make_wi_sa(p_hi, wi_r14r15_hi, sa_r14r15_hi);
1064 }
1065
1066 21 uint8_t* AVS_RESTRICT dst_ptr = dst8 + x + y_from * dst_pitch;
1067 21 const uint8_t* src_ptr = src8 + iStart + y_from * src_pitch;
1068
1069 21 const int remaining = program->source_size - iStart;
1070 21 __mmask64 k1 = _bzhi_u64(~0ULL, remaining);
1071 21 const __mmask64 k2 = _bzhi_u64(~0ULL, std::max(0, remaining - 64));
1072 21 const __mmask64 k_zh8 = 0x5555555555555555ULL;
1073
1074
8/8
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 459 → 125 taken 10 times.
✓ Branch 459 → 460 taken 2 times.
✓ Branch 463 → 125 taken 20 times.
✓ Branch 463 → 464 taken 4 times.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 189 → 79 taken 10 times.
✓ Branch 189 → 190 taken 2 times.
✓ Branch 193 → 79 taken 101 times.
✓ Branch 193 → 194 taken 13 times.
162 for (int y = y_from; y < y_to; y++)
1075 {
1076 __m512i data_src, data_src2;
1077
1078 141 __m512i perm_rNrNp1_0_31lo_w = perm_r0r1_0_31lo;
1079 141 __m512i perm_rNrNp1_0_31hi_w = perm_r0r1_0_31hi;
1080
1081 if constexpr (partial_load) {
1082 121 data_src = _mm512_maskz_loadu_epi8(k1, src_ptr);
1083 222 data_src2 = _mm512_maskz_loadu_epi8(k2, src_ptr + 64);
1084 }
1085 else {
1086 20 data_src = _mm512_loadu_si512(src_ptr);
1087 30 data_src2 = _mm512_loadu_si512(src_ptr + 64);
1088 }
1089
1090 // rows 0..1
1091 __m512i src_r0r1_0_31lo, src_r0r1_0_31hi;
1092 if constexpr (UseVNNI) {
1093 111 src_r0r1_0_31lo = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);
1094 111 src_r0r1_0_31hi = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);
1095 } else {
1096 30 src_r0r1_0_31lo = _permutex2var_epi8_sim_get32(wi_r0r1_lo, sa_r0r1_lo, data_src, data_src2);
1097 60 src_r0r1_0_31hi = _permutex2var_epi8_sim_get32(wi_r0r1_hi, sa_r0r1_hi, data_src, data_src2);
1098 }
1099
1100 // for r2r3
1101 141 perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);
1102 141 perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);
1103
1104 __m512i src_r2r3_0_31lo, src_r2r3_0_31hi;
1105 if constexpr (UseVNNI) {
1106 111 src_r2r3_0_31lo = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);
1107 111 src_r2r3_0_31hi = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);
1108 } else {
1109 30 src_r2r3_0_31lo = _permutex2var_epi8_sim_get32(wi_r2r3_lo, sa_r2r3_lo, data_src, data_src2);
1110 60 src_r2r3_0_31hi = _permutex2var_epi8_sim_get32(wi_r2r3_hi, sa_r2r3_hi, data_src, data_src2);
1111 }
1112
1113 // for r4r5
1114 141 perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);
1115 141 perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);
1116
1117 __m512i result_0_31lo, result_0_31hi;
1118
1119 if constexpr (UseVNNI)
1120 {
1121 222 result_0_31lo = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31lo, coef_r0r1_0_31lo);
1122 111 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r2r3_0_31lo, coef_r2r3_0_31lo);
1123 222 result_0_31hi = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31hi, coef_r0r1_0_31hi);
1124 111 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r2r3_0_31hi, coef_r2r3_0_31hi);
1125 }
1126 else
1127 {
1128 90 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo));
1129 60 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi));
1130 }
1131
1132 // rows 4..5
1133 __m512i src_r4r5_0_31lo, src_r4r5_0_31hi;
1134 if constexpr (UseVNNI) {
1135 111 src_r4r5_0_31lo = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);
1136 111 src_r4r5_0_31hi = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);
1137 } else {
1138 30 src_r4r5_0_31lo = _permutex2var_epi8_sim_get32(wi_r4r5_lo, sa_r4r5_lo, data_src, data_src2);
1139 60 src_r4r5_0_31hi = _permutex2var_epi8_sim_get32(wi_r4r5_hi, sa_r4r5_hi, data_src, data_src2);
1140 }
1141
1142 // for r6r7
1143 141 perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);
1144 141 perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);
1145
1146 __m512i src_r6r7_0_31lo, src_r6r7_0_31hi;
1147 if constexpr (UseVNNI) {
1148 111 src_r6r7_0_31lo = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);
1149 111 src_r6r7_0_31hi = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);
1150 } else {
1151 30 src_r6r7_0_31lo = _permutex2var_epi8_sim_get32(wi_r6r7_lo, sa_r6r7_lo, data_src, data_src2);
1152 60 src_r6r7_0_31hi = _permutex2var_epi8_sim_get32(wi_r6r7_hi, sa_r6r7_hi, data_src, data_src2);
1153 }
1154
1155 // for r8r9
1156 141 perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);
1157 141 perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);
1158
1159 if constexpr (UseVNNI)
1160 {
1161 111 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r4r5_0_31lo, coef_r4r5_0_31lo);
1162 111 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r6r7_0_31lo, coef_r6r7_0_31lo);
1163 111 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r4r5_0_31hi, coef_r4r5_0_31hi);
1164 111 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r6r7_0_31hi, coef_r6r7_0_31hi);
1165 }
1166 else
1167 {
1168 60 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31lo, coef_r4r5_0_31lo), result_0_31lo);
1169 60 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31hi, coef_r4r5_0_31hi), result_0_31hi);
1170 60 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31lo, coef_r6r7_0_31lo), result_0_31lo);
1171 30 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31hi, coef_r6r7_0_31hi), result_0_31hi);
1172 }
1173
1174 // rows 8..9
1175 __m512i src_r8r9_0_31lo, src_r8r9_0_31hi;
1176 if constexpr (UseVNNI) {
1177 111 src_r8r9_0_31lo = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);
1178 111 src_r8r9_0_31hi = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);
1179 } else {
1180 30 src_r8r9_0_31lo = _permutex2var_epi8_sim_get32(wi_r8r9_lo, sa_r8r9_lo, data_src, data_src2);
1181 60 src_r8r9_0_31hi = _permutex2var_epi8_sim_get32(wi_r8r9_hi, sa_r8r9_hi, data_src, data_src2);
1182 }
1183
1184 // for r10r11
1185 141 perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);
1186 141 perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);
1187
1188 __m512i src_r10r11_0_31lo, src_r10r11_0_31hi;
1189 if constexpr (UseVNNI) {
1190 111 src_r10r11_0_31lo = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);
1191 111 src_r10r11_0_31hi = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);
1192 } else {
1193 30 src_r10r11_0_31lo = _permutex2var_epi8_sim_get32(wi_r10r11_lo, sa_r10r11_lo, data_src, data_src2);
1194 60 src_r10r11_0_31hi = _permutex2var_epi8_sim_get32(wi_r10r11_hi, sa_r10r11_hi, data_src, data_src2);
1195 }
1196
1197 // for r12r13
1198 141 perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);
1199 141 perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);
1200
1201 if constexpr (UseVNNI)
1202 {
1203 111 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r8r9_0_31lo, coef_r8r9_0_31lo);
1204 111 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r10r11_0_31lo, coef_r10r11_0_31lo);
1205 111 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r8r9_0_31hi, coef_r8r9_0_31hi);
1206 111 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r10r11_0_31hi, coef_r10r11_0_31hi);
1207 }
1208 else
1209 {
1210 60 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r8r9_0_31lo, coef_r8r9_0_31lo), result_0_31lo);
1211 60 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r8r9_0_31hi, coef_r8r9_0_31hi), result_0_31hi);
1212 60 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r10r11_0_31lo, coef_r10r11_0_31lo), result_0_31lo);
1213 30 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r10r11_0_31hi, coef_r10r11_0_31hi), result_0_31hi);
1214 }
1215
1216 // rows 12..13
1217 __m512i src_r12r13_0_31lo, src_r12r13_0_31hi;
1218 if constexpr (UseVNNI) {
1219 111 src_r12r13_0_31lo = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);
1220 111 src_r12r13_0_31hi = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);
1221 } else {
1222 30 src_r12r13_0_31lo = _permutex2var_epi8_sim_get32(wi_r12r13_lo, sa_r12r13_lo, data_src, data_src2);
1223 60 src_r12r13_0_31hi = _permutex2var_epi8_sim_get32(wi_r12r13_hi, sa_r12r13_hi, data_src, data_src2);
1224 }
1225
1226 // for r14r15
1227 141 perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);
1228 141 perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);
1229
1230 __m512i src_r14r15_0_31lo, src_r14r15_0_31hi;
1231 if constexpr (UseVNNI) {
1232 111 src_r14r15_0_31lo = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31lo_w, data_src2);
1233 111 src_r14r15_0_31hi = _mm512_maskz_permutex2var_epi8(k_zh8, data_src, perm_rNrNp1_0_31hi_w, data_src2);
1234 } else {
1235 30 src_r14r15_0_31lo = _permutex2var_epi8_sim_get32(wi_r14r15_lo, sa_r14r15_lo, data_src, data_src2);
1236 60 src_r14r15_0_31hi = _permutex2var_epi8_sim_get32(wi_r14r15_hi, sa_r14r15_hi, data_src, data_src2);
1237 }
1238
1239 if constexpr (UseVNNI)
1240 {
1241 111 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r12r13_0_31lo, coef_r12r13_0_31lo);
1242 111 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r14r15_0_31lo, coef_r14r15_0_31lo);
1243 111 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r12r13_0_31hi, coef_r12r13_0_31hi);
1244 111 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r14r15_0_31hi, coef_r14r15_0_31hi);
1245 // rounding VNNI in first FMA already summed
1246 }
1247 else
1248 {
1249 60 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r12r13_0_31lo, coef_r12r13_0_31lo), result_0_31lo);
1250 60 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r12r13_0_31hi, coef_r12r13_0_31hi), result_0_31hi);
1251 60 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r14r15_0_31lo, coef_r14r15_0_31lo), result_0_31lo);
1252 30 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r14r15_0_31hi, coef_r14r15_0_31hi), result_0_31hi);
1253
1254 30 result_0_31lo = _mm512_add_epi32(result_0_31lo, rounder);
1255 60 result_0_31hi = _mm512_add_epi32(result_0_31hi, rounder);
1256 }
1257
1258 141 result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale8bits);
1259 141 result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale8bits);
1260
1261 141 __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);
1262
1263 141 __m256i result_0_31_u8 = _mm512_cvtusepi16_epi8(result_0_31_int16);
1264
1265 _mm256_stream_si256(reinterpret_cast<__m256i*>(dst_ptr), result_0_31_u8);
1266
1267 141 dst_ptr += dst_pitch;
1268 141 src_ptr += src_pitch;
1269 }
1270
1271 21 current_coeff_SIMD += 16;
1272 };
1273
1274
4/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 18 → 16 taken 2 times.
✓ Branch 18 → 19 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 18 → 16 taken 2 times.
✓ Branch 18 → 19 taken 10 times.
15 for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)
1275 {
1276
1/2
✓ Branch 16 → 17 taken 2 times.
✗ Branch 16 → 26 not taken.
4 do_h_integer_core(std::false_type{});
1277 }
1278
1279
4/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 22 → 20 taken 4 times.
✓ Branch 22 → 23 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_ks16_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 22 → 20 taken 13 times.
✓ Branch 22 → 23 taken 10 times.
28 for (; x < width; x += PIXELS_AT_A_TIME)
1280 {
1281
1/2
✓ Branch 20 → 21 taken 13 times.
✗ Branch 20 → 26 not taken.
17 do_h_integer_core(std::true_type{});
1282 }
1283 }
1284 11 }
1285
1286 // filter size up to 64, pretransposed coefficients
1287 // 64 target uint8_t pixels at a time in 2 groups of 32
1288 // 2 groups of 128-byte source loads
1289 template<bool UseVNNI>
1290 2 void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)
1291 {
1292 2 int filter_size_real = program->filter_size_real;
1293
2/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
2 if ((filter_size_real / 2 * 2) != filter_size_real) filter_size_real++;
1294
1295 2 constexpr int PIXELS_AT_A_TIME = 64;
1296
1297
2/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 6 not taken.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 6 not taken.
2 const int width_safe_mod = (program->safelimit_128_pixels_each64th_target.overread_possible ? program->safelimit_128_pixels_each64th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;
1298
1299
2/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 1 time.
2 assert(program->filter_size_real <= 64);
1300
2/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 1 time.
2 assert(program->target_size_alignment >= 64);
1301 assert(FRAME_ALIGN >= 64);
1302
2/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 1 time.
2 assert(program->filter_size_alignment >= 8);
1303
1304 2 const int max_scanlines = program->max_scanlines;
1305
1306 2 __m512i rounder = _mm512_set1_epi32(1 << (FPScale8bits - 1));
1307
1308
4/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 26 → 16 taken 1 time.
✓ Branch 26 → 27 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 26 → 16 taken 1 time.
✓ Branch 26 → 27 taken 1 time.
4 for (int y_from = 0; y_from < height; y_from += max_scanlines)
1309 {
1310 2 int y_to = std::min(y_from + max_scanlines, height);
1311
1312 2 const __m512i* AVS_RESTRICT current_coeff_SIMD = (__m512i*)program->pixel_coefficient_AVX512_H;
1313
1314 2 int x = 0;
1315
1316 14 auto do_h_integer_core = [&](auto partial_load) {
1317
1318 6 __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x]));
1319 6 __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16]));
1320 6 __m512i perm_0_32_47 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 32]));
1321 6 __m512i perm_0_48_63 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 48]));
1322
1323 6 int iStart = program->pixel_offset[x];
1324 6 int iStart_2 = program->pixel_offset[x + 32];
1325 6 __m512i m512i_Start = _mm512_set1_epi32(iStart);
1326 6 __m512i m512i_Start_2 = _mm512_set1_epi32(iStart_2);
1327
1328 6 perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start);
1329 6 perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start);
1330 6 perm_0_32_47 = _mm512_sub_epi32(perm_0_32_47, m512i_Start_2);
1331 6 perm_0_48_63 = _mm512_sub_epi32(perm_0_48_63, m512i_Start_2);
1332
1333 6 __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);
1334 6 __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);
1335 6 __m256i m256i_perm_0_32_47 = _mm512_cvtepi32_epi16(perm_0_32_47);
1336 6 __m256i m256i_perm_0_48_63 = _mm512_cvtepi32_epi16(perm_0_48_63);
1337
1338 12 __m512i perm_0_0_31 = _mm512_inserti64x4(_mm512_castsi256_si512(m256i_perm_0_0_15), m256i_perm_0_16_31, 1);
1339 12 __m512i perm_0_32_63 = _mm512_inserti64x4(_mm512_castsi256_si512(m256i_perm_0_32_47), m256i_perm_0_48_63, 1);
1340
1341 6 __m512i one_epi16 = _mm512_set1_epi16(1);
1342 6 __m512i perm_1_0_31 = _mm512_add_epi16(perm_0_0_31, one_epi16);
1343 6 __m512i perm_1_32_63 = _mm512_add_epi16(perm_0_32_63, one_epi16);
1344
1345 6 const __m512i two_epi16 = _mm512_set1_epi16(2);
1346
1347 // BASE: precompute wi/sa outside y-loop. perm vectors are epi16 (32 16-bit byte indices).
1348 // Each kr step the perm advances by +2 bytes = +1 word, so wi += 1 and sa is invariant.
1349 // perm_1 = perm_0 + 1: wi_p1[i] = wi_p0[i] + (perm_0[i] & 1), sa_p1 = sa_p0 ^ 8.
1350 6 __m512i wi_g1_p0_base = {}, wi_g2_p0_base = {}, wi_g1_p1_base = {}, wi_g2_p1_base = {};
1351 6 __m512i sa_g1_p0 = {}, sa_g2_p0 = {}, sa_g1_p1 = {}, sa_g2_p1 = {};
1352 if constexpr (!UseVNNI) {
1353 3 const __m512i c_8w = _mm512_set1_epi16(8);
1354 6 sa_g1_p0 = _mm512_and_si512(_mm512_slli_epi16(perm_0_0_31, 3), c_8w);
1355 3 wi_g1_p0_base = _mm512_srli_epi16(perm_0_0_31, 1);
1356 3 sa_g1_p1 = _mm512_xor_si512(sa_g1_p0, c_8w);
1357 6 wi_g1_p1_base = _mm512_add_epi16(wi_g1_p0_base, _mm512_srli_epi16(sa_g1_p0, 3));
1358 6 sa_g2_p0 = _mm512_and_si512(_mm512_slli_epi16(perm_0_32_63, 3), c_8w);
1359 3 wi_g2_p0_base = _mm512_srli_epi16(perm_0_32_63, 1);
1360 3 sa_g2_p1 = _mm512_xor_si512(sa_g2_p0, c_8w);
1361 3 wi_g2_p1_base = _mm512_add_epi16(wi_g2_p0_base, _mm512_srli_epi16(sa_g2_p0, 3));
1362 }
1363
1364 6 uint8_t* AVS_RESTRICT dst_ptr = dst8 + x + y_from * dst_pitch;
1365 6 const uint8_t* src_ptr = src8 + iStart + y_from * src_pitch;
1366 6 const uint8_t* src_ptr_2 = src8 + iStart_2 + y_from * src_pitch;
1367
1368 6 const int remaining = program->source_size - iStart;
1369 6 const int remaining_2 = program->source_size - iStart_2;
1370 6 const __mmask64 k1 = _bzhi_u64(~0ULL, remaining);
1371 6 const __mmask64 k2 = _bzhi_u64(~0ULL, std::max(0, remaining - 64));
1372 6 const __mmask64 k1_2 = _bzhi_u64(~0ULL, remaining_2);
1373 6 const __mmask64 k2_2 = _bzhi_u64(~0ULL, std::max(0, remaining_2 - 64));
1374 6 const __mmask64 k_zh8 = 0x5555555555555555ULL;
1375
1376
8/8
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 242 → 97 taken 5 times.
✓ Branch 242 → 243 taken 1 time.
✓ Branch 250 → 97 taken 10 times.
✓ Branch 250 → 251 taken 2 times.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 168 → 71 taken 5 times.
✓ Branch 168 → 169 taken 1 time.
✓ Branch 176 → 71 taken 10 times.
✓ Branch 176 → 177 taken 2 times.
36 for (int y = y_from; y < y_to; y++)
1377 {
1378 __m512i data_src, data_src2, data_src_2, data_src2_2;
1379
1380 // VBMI: reset working perm copies per row; BASE: reset running wi counters per row
1381 30 __m512i perm_0_0_31w = {}, perm_0_32_63w = {}, perm_1_0_31w = {}, perm_1_32_63w = {};
1382 30 __m512i wi_g1_p0 = {}, wi_g2_p0 = {}, wi_g1_p1 = {}, wi_g2_p1 = {};
1383 if constexpr (UseVNNI) {
1384 15 perm_0_0_31w = perm_0_0_31;
1385 15 perm_0_32_63w = perm_0_32_63;
1386 15 perm_1_0_31w = perm_1_0_31;
1387 15 perm_1_32_63w = perm_1_32_63;
1388 } else {
1389 15 wi_g1_p0 = wi_g1_p0_base;
1390 15 wi_g2_p0 = wi_g2_p0_base;
1391 15 wi_g1_p1 = wi_g1_p1_base;
1392 15 wi_g2_p1 = wi_g2_p1_base;
1393 }
1394
1395 if constexpr (partial_load) {
1396 20 data_src = _mm512_maskz_loadu_epi8(k1, src_ptr);
1397 40 data_src2 = _mm512_maskz_loadu_epi8(k2, src_ptr + 64);
1398 20 data_src_2 = _mm512_maskz_loadu_epi8(k1_2, src_ptr_2);
1399 20 data_src2_2 = _mm512_maskz_loadu_epi8(k2_2, src_ptr_2 + 64);
1400 }
1401 else {
1402 10 data_src = _mm512_loadu_si512(src_ptr);
1403 20 data_src2 = _mm512_loadu_si512(src_ptr + 64);
1404 10 data_src_2 = _mm512_loadu_si512(src_ptr_2);
1405 10 data_src2_2 = _mm512_loadu_si512(src_ptr_2 + 64);
1406 }
1407
1408 30 __m512i result_0_31lo = rounder;
1409 30 __m512i result_0_31hi = rounder;
1410 30 __m512i result_32_63lo = rounder;
1411 30 __m512i result_32_63hi = rounder;
1412
1413 30 const __m512i* current_coeff_SIMDw = current_coeff_SIMD;
1414
1415
8/8
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 211 → 106 taken 50 times.
✓ Branch 211 → 212 taken 5 times.
✓ Branch 219 → 114 taken 100 times.
✓ Branch 219 → 220 taken 10 times.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 137 → 80 taken 50 times.
✓ Branch 137 → 138 taken 5 times.
✓ Branch 145 → 88 taken 100 times.
✓ Branch 145 → 146 taken 10 times.
330 for (int kr = 0; kr < filter_size_real; kr += 2)
1416 {
1417 __m512i src_r0_0_31, src_r0_32_63, src_r1_0_31, src_r1_32_63;
1418 if constexpr (UseVNNI) {
1419 150 src_r0_0_31 = _mm512_maskz_permutex2var_epi8_SIMUL<true>(k_zh8, data_src, perm_0_0_31w, data_src2);
1420 150 src_r0_32_63 = _mm512_maskz_permutex2var_epi8_SIMUL<true>(k_zh8, data_src_2, perm_0_32_63w, data_src2_2);
1421 150 src_r1_0_31 = _mm512_maskz_permutex2var_epi8_SIMUL<true>(k_zh8, data_src, perm_1_0_31w, data_src2);
1422 150 src_r1_32_63 = _mm512_maskz_permutex2var_epi8_SIMUL<true>(k_zh8, data_src_2, perm_1_32_63w, data_src2_2);
1423 150 perm_0_0_31w = _mm512_add_epi16(perm_0_0_31w, two_epi16);
1424 150 perm_0_32_63w = _mm512_add_epi16(perm_0_32_63w, two_epi16);
1425 150 perm_1_0_31w = _mm512_add_epi16(perm_1_0_31w, two_epi16);
1426 150 perm_1_32_63w = _mm512_add_epi16(perm_1_32_63w, two_epi16);
1427 } else {
1428 // BASE: sim_get32 reads word wi (already indexed into [data_src | data_src2])
1429 // and shifts by sa to extract the target byte; avoids full SIMUL recomputation
1430 150 src_r0_0_31 = _permutex2var_epi8_sim_get32(wi_g1_p0, sa_g1_p0, data_src, data_src2);
1431 150 src_r0_32_63 = _permutex2var_epi8_sim_get32(wi_g2_p0, sa_g2_p0, data_src_2, data_src2_2);
1432 150 src_r1_0_31 = _permutex2var_epi8_sim_get32(wi_g1_p1, sa_g1_p1, data_src, data_src2);
1433 150 src_r1_32_63 = _permutex2var_epi8_sim_get32(wi_g2_p1, sa_g2_p1, data_src_2, data_src2_2);
1434 150 wi_g1_p0 = _mm512_add_epi16(wi_g1_p0, one_epi16);
1435 150 wi_g2_p0 = _mm512_add_epi16(wi_g2_p0, one_epi16);
1436 150 wi_g1_p1 = _mm512_add_epi16(wi_g1_p1, one_epi16);
1437 150 wi_g2_p1 = _mm512_add_epi16(wi_g2_p1, one_epi16);
1438 }
1439
1440 300 __m512i src_r0r1_0_31lo = _mm512_unpacklo_epi16(src_r0_0_31, src_r1_0_31);
1441 300 __m512i src_r0r1_0_31hi = _mm512_unpackhi_epi16(src_r0_0_31, src_r1_0_31);
1442 300 __m512i src_r0r1_32_63lo = _mm512_unpacklo_epi16(src_r0_32_63, src_r1_32_63);
1443 300 __m512i src_r0r1_32_63hi = _mm512_unpackhi_epi16(src_r0_32_63, src_r1_32_63);
1444
1445 if constexpr (UseVNNI)
1446 {
1447 150 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r0r1_0_31lo, _mm512_load_si512(current_coeff_SIMDw + 0));
1448 300 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r0r1_0_31hi, _mm512_load_si512(current_coeff_SIMDw + 1));
1449 300 result_32_63lo = _mm512_dpwssd_epi32(result_32_63lo, src_r0r1_32_63lo, _mm512_load_si512(current_coeff_SIMDw + 2));
1450 300 result_32_63hi = _mm512_dpwssd_epi32(result_32_63hi, src_r0r1_32_63hi, _mm512_load_si512(current_coeff_SIMDw + 3));
1451 }
1452 else
1453 {
1454 300 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, _mm512_load_si512(current_coeff_SIMDw + 0)), result_0_31lo);
1455 450 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, _mm512_load_si512(current_coeff_SIMDw + 1)), result_0_31hi);
1456 450 result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63lo, _mm512_load_si512(current_coeff_SIMDw + 2)), result_32_63lo);
1457 450 result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63hi, _mm512_load_si512(current_coeff_SIMDw + 3)), result_32_63hi);
1458 }
1459
1460 300 current_coeff_SIMDw += 4;
1461 }
1462
1463 30 result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale8bits);
1464 30 result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale8bits);
1465 30 result_32_63lo = _mm512_srai_epi32(result_32_63lo, FPScale8bits);
1466 30 result_32_63hi = _mm512_srai_epi32(result_32_63hi, FPScale8bits);
1467
1468 30 __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);
1469 30 __m512i result_32_63_int16 = _mm512_packus_epi32(result_32_63lo, result_32_63hi);
1470
1471 30 __m256i result_0_31_u8 = _mm512_cvtusepi16_epi8(result_0_31_int16);
1472 30 __m256i result_32_63_u8 = _mm512_cvtusepi16_epi8(result_32_63_int16);
1473
1474 60 _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr), _mm512_inserti64x4(_mm512_castsi256_si512(result_0_31_u8), result_32_63_u8, 1));
1475
1476 30 dst_ptr += dst_pitch;
1477 30 src_ptr += src_pitch;
1478 30 src_ptr_2 += src_pitch;
1479 }
1480
1481 6 current_coeff_SIMD += filter_size_real * 2;
1482 };
1483
1484
4/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 20 → 18 taken 1 time.
✓ Branch 20 → 21 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 20 → 18 taken 1 time.
✓ Branch 20 → 21 taken 1 time.
4 for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)
1485 {
1486
1/2
✓ Branch 18 → 19 taken 1 time.
✗ Branch 18 → 28 not taken.
2 do_h_integer_core(std::false_type{});
1487 }
1488
1489
4/4
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 22 taken 2 times.
✓ Branch 24 → 25 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_mpz_2s32_ks64_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 22 taken 2 times.
✓ Branch 24 → 25 taken 1 time.
6 for (; x < width; x += PIXELS_AT_A_TIME)
1490 {
1491
1/2
✓ Branch 22 → 23 taken 2 times.
✗ Branch 22 → 28 not taken.
4 do_h_integer_core(std::true_type{});
1492 }
1493 }
1494 2 }
1495
1496 // filter size 8, pretransposed coefficients
1497 // 64 target uint8_t pixels at a time in 2 groups of 32
1498 // 2 groups of 128-byte source loads
1499 template<bool UseVNNI>
1500 2 void resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_pretransposed_coeffs_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)
1501 {
1502 2 constexpr int PIXELS_AT_A_TIME = 64;
1503
1504
2/4
void resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
2 const int width_safe_mod = (program->safelimit_128_pixels_each64th_target.overread_possible ? program->safelimit_128_pixels_each64th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;
1505
1506 2 const int max_scanlines = program->max_scanlines;
1507
1508 2 __m512i rounder = _mm512_set1_epi32(1 << (FPScale8bits - 1));
1509
1510
4/4
void resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 18 → 8 taken 1 time.
✓ Branch 18 → 19 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 18 → 8 taken 1 time.
✓ Branch 18 → 19 taken 1 time.
4 for (int y_from = 0; y_from < height; y_from += max_scanlines)
1511 {
1512 2 int y_to = std::min(y_from + max_scanlines, height);
1513
1514 2 const __m512i* AVS_RESTRICT current_coeff_SIMD = (__m512i*)program->pixel_coefficient_AVX512_H;
1515
1516 2 int x = 0;
1517
1518 6 auto do_h_integer_core = [&](auto partial_load) {
1519 2 const __m512i coef_r0r1_0_31lo = _mm512_load_si512(current_coeff_SIMD + 0);
1520 2 const __m512i coef_r0r1_0_31hi = _mm512_load_si512(current_coeff_SIMD + 1);
1521 2 const __m512i coef_r0r1_32_63lo = _mm512_load_si512(current_coeff_SIMD + 2);
1522 2 const __m512i coef_r0r1_32_63hi = _mm512_load_si512(current_coeff_SIMD + 3);
1523 2 const __m512i coef_r2r3_0_31lo = _mm512_load_si512(current_coeff_SIMD + 4);
1524 2 const __m512i coef_r2r3_0_31hi = _mm512_load_si512(current_coeff_SIMD + 5);
1525 2 const __m512i coef_r2r3_32_63lo = _mm512_load_si512(current_coeff_SIMD + 6);
1526 2 const __m512i coef_r2r3_32_63hi = _mm512_load_si512(current_coeff_SIMD + 7);
1527 2 const __m512i coef_r4r5_0_31lo = _mm512_load_si512(current_coeff_SIMD + 8);
1528 2 const __m512i coef_r4r5_0_31hi = _mm512_load_si512(current_coeff_SIMD + 9);
1529 2 const __m512i coef_r4r5_32_63lo = _mm512_load_si512(current_coeff_SIMD + 10);
1530 2 const __m512i coef_r4r5_32_63hi = _mm512_load_si512(current_coeff_SIMD + 11);
1531 2 const __m512i coef_r6r7_0_31lo = _mm512_load_si512(current_coeff_SIMD + 12);
1532 2 const __m512i coef_r6r7_0_31hi = _mm512_load_si512(current_coeff_SIMD + 13);
1533 2 const __m512i coef_r6r7_32_63lo = _mm512_load_si512(current_coeff_SIMD + 14);
1534 2 const __m512i coef_r6r7_32_63hi = _mm512_load_si512(current_coeff_SIMD + 15);
1535
1536 2 __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x]));
1537 2 __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16]));
1538 2 __m512i perm_0_32_47 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 32]));
1539 2 __m512i perm_0_48_63 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 48]));
1540
1541 2 int iStart = program->pixel_offset[x];
1542 2 int iStart_2 = program->pixel_offset[x + 32];
1543 2 __m512i m512i_Start = _mm512_set1_epi32(iStart);
1544 2 __m512i m512i_Start_2 = _mm512_set1_epi32(iStart_2);
1545
1546 2 perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start);
1547 2 perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start);
1548 2 perm_0_32_47 = _mm512_sub_epi32(perm_0_32_47, m512i_Start_2);
1549 2 perm_0_48_63 = _mm512_sub_epi32(perm_0_48_63, m512i_Start_2);
1550
1551 2 __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);
1552 2 __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);
1553 2 __m256i m256i_perm_0_32_47 = _mm512_cvtepi32_epi16(perm_0_32_47);
1554 2 __m256i m256i_perm_0_48_63 = _mm512_cvtepi32_epi16(perm_0_48_63);
1555
1556 2 __m128i mm128i_perm_0_0_15 = _mm256_cvtepi16_epi8(m256i_perm_0_0_15);
1557 2 __m128i mm128i_perm_0_16_31 = _mm256_cvtepi16_epi8(m256i_perm_0_16_31);
1558 2 __m128i mm128i_perm_0_32_47 = _mm256_cvtepi16_epi8(m256i_perm_0_32_47);
1559 2 __m128i mm128i_perm_0_48_63 = _mm256_cvtepi16_epi8(m256i_perm_0_48_63);
1560
1561 2 __m512i perm_0 = _mm512_inserti32x4(_mm512_castsi128_si512(mm128i_perm_0_0_15), mm128i_perm_0_16_31, 1);
1562 2 perm_0 = _mm512_inserti32x4(perm_0, mm128i_perm_0_32_47, 2);
1563 2 perm_0 = _mm512_inserti32x4(perm_0, mm128i_perm_0_48_63, 3);
1564
1565 2 uint8_t* AVS_RESTRICT dst_ptr = dst8 + x + y_from * dst_pitch;
1566 2 const uint8_t* src_ptr = src8 + iStart + y_from * src_pitch;
1567 2 const uint8_t* src_ptr_2 = src8 + iStart_2 + y_from * src_pitch;
1568
1569 2 const int remaining = program->source_size - iStart;
1570 2 const int remaining_2 = program->source_size - iStart_2;
1571 2 const __mmask64 k1 = _bzhi_u64(~0ULL, remaining);
1572 2 const __mmask64 k2 = _bzhi_u64(~0ULL, std::max(0, remaining - 64));
1573 2 const __mmask64 k1_2 = _bzhi_u64(~0ULL, remaining_2);
1574 4 const __mmask64 k2_2 = _bzhi_u64(~0ULL, std::max(0, remaining_2 - 64));
1575
1576 // perm_0+N for each kernel tap — loop-invariant, precomputed for both VBMI and BASE paths
1577 4 const __m512i pw_1 = _mm512_add_epi8(perm_0, _mm512_set1_epi8(1));
1578 4 const __m512i pw_2 = _mm512_add_epi8(perm_0, _mm512_set1_epi8(2));
1579 4 const __m512i pw_3 = _mm512_add_epi8(perm_0, _mm512_set1_epi8(3));
1580 4 const __m512i pw_4 = _mm512_add_epi8(perm_0, _mm512_set1_epi8(4));
1581 4 const __m512i pw_5 = _mm512_add_epi8(perm_0, _mm512_set1_epi8(5));
1582 4 const __m512i pw_6 = _mm512_add_epi8(perm_0, _mm512_set1_epi8(6));
1583 2 const __m512i pw_7 = _mm512_add_epi8(perm_0, _mm512_set1_epi8(7));
1584
1585 // BASE path only: precompute word_idx and shift_amt from each perm vector.
1586 // MSVC fails to hoist these from the y-loop even though perm_0 is invariant.
1587 2 __m512i wi_lo_0 = {}, sa_lo_0 = {}, wi_hi_0 = {}, sa_hi_0 = {};
1588 2 __m512i wi_lo_1 = {}, sa_lo_1 = {}, wi_hi_1 = {}, sa_hi_1 = {};
1589 2 __m512i wi_lo_2 = {}, sa_lo_2 = {}, wi_hi_2 = {}, sa_hi_2 = {};
1590 2 __m512i wi_lo_3 = {}, sa_lo_3 = {}, wi_hi_3 = {}, sa_hi_3 = {};
1591 2 __m512i wi_lo_4 = {}, sa_lo_4 = {}, wi_hi_4 = {}, sa_hi_4 = {};
1592 2 __m512i wi_lo_5 = {}, sa_lo_5 = {}, wi_hi_5 = {}, sa_hi_5 = {};
1593 2 __m512i wi_lo_6 = {}, sa_lo_6 = {}, wi_hi_6 = {}, sa_hi_6 = {};
1594 2 __m512i wi_lo_7 = {}, sa_lo_7 = {}, wi_hi_7 = {}, sa_hi_7 = {};
1595 if constexpr (!UseVNNI) {
1596 1 const __m512i c_8 = _mm512_set1_epi16(8);
1597 9 auto make_wi_sa = [&](const __m512i pw, __m512i &wi_lo, __m512i &sa_lo, __m512i &wi_hi, __m512i &sa_hi) {
1598 16 __m512i lo = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(pw));
1599 16 __m512i hi = _mm512_cvtepu8_epi16(_mm512_extracti64x4_epi64(pw, 1));
1600 8 wi_lo = _mm512_srli_epi16(lo, 1);
1601 24 sa_lo = _mm512_and_si512(_mm512_slli_epi16(lo, 3), c_8);
1602 8 wi_hi = _mm512_srli_epi16(hi, 1);
1603 16 sa_hi = _mm512_and_si512(_mm512_slli_epi16(hi, 3), c_8);
1604 };
1605 1 make_wi_sa(perm_0, wi_lo_0, sa_lo_0, wi_hi_0, sa_hi_0);
1606 1 make_wi_sa(pw_1, wi_lo_1, sa_lo_1, wi_hi_1, sa_hi_1);
1607 1 make_wi_sa(pw_2, wi_lo_2, sa_lo_2, wi_hi_2, sa_hi_2);
1608 1 make_wi_sa(pw_3, wi_lo_3, sa_lo_3, wi_hi_3, sa_hi_3);
1609 1 make_wi_sa(pw_4, wi_lo_4, sa_lo_4, wi_hi_4, sa_hi_4);
1610 1 make_wi_sa(pw_5, wi_lo_5, sa_lo_5, wi_hi_5, sa_hi_5);
1611 1 make_wi_sa(pw_6, wi_lo_6, sa_lo_6, wi_hi_6, sa_hi_6);
1612 1 make_wi_sa(pw_7, wi_lo_7, sa_lo_7, wi_hi_7, sa_hi_7);
1613 }
1614
1615 // 512-bit vpermi2b + vextracti64x4 + vpunpcklw/hi saturated port 5 on Ice Lake
1616 // (56 port-5 uops/iter vs BASE's 32), costing ~8% vs the BASE simulation path.
1617 // Combined 256-bit indices eliminate extract+unpack, matching BASE at 32 port-5 uops.
1618 // Coefficient layout is unchanged; unpackbw+unpackqdq construction replicates the word
1619 // order of unpacklo/hi_epi16. Dual-AVX-512-pipe CPUs (Sapphire Rapids+) may not have
1620 // suffered this bottleneck due to higher port-5 throughput.
1621 2 __m256i comb_01_g1lo={}, comb_01_g1hi={}, comb_01_g2lo={}, comb_01_g2hi={};
1622 2 __m256i comb_23_g1lo={}, comb_23_g1hi={}, comb_23_g2lo={}, comb_23_g2hi={};
1623 2 __m256i comb_45_g1lo={}, comb_45_g1hi={}, comb_45_g2lo={}, comb_45_g2hi={};
1624 2 __m256i comb_67_g1lo={}, comb_67_g1hi={}, comb_67_g2lo={}, comb_67_g2hi={};
1625 if constexpr (UseVNNI) {
1626 8 auto make_combined = [&](__m256i pa, __m256i pb, __m256i& clo, __m256i& chi) {
1627 8 __m256i t0 = _mm256_unpacklo_epi8(pa, pb);
1628 8 __m256i t1 = _mm256_unpackhi_epi8(pa, pb);
1629 8 clo = _mm256_unpacklo_epi64(t0, t1);
1630 8 chi = _mm256_unpackhi_epi64(t0, t1);
1631 };
1632 1 __m256i p0g1 = _mm512_castsi512_si256(perm_0);
1633 1 __m256i p0g2 = _mm512_extracti64x4_epi64(perm_0, 1);
1634 // pw_N lower half is a free register alias; upper half = p0g2+N avoids 7 extra extracts
1635 1 make_combined(p0g1, _mm512_castsi512_si256(pw_1), comb_01_g1lo, comb_01_g1hi);
1636 2 make_combined(p0g2, _mm256_add_epi8(p0g2, _mm256_set1_epi8(1)), comb_01_g2lo, comb_01_g2hi);
1637 2 make_combined(_mm512_castsi512_si256(pw_2), _mm512_castsi512_si256(pw_3), comb_23_g1lo, comb_23_g1hi);
1638 4 make_combined(_mm256_add_epi8(p0g2, _mm256_set1_epi8(2)), _mm256_add_epi8(p0g2, _mm256_set1_epi8(3)), comb_23_g2lo, comb_23_g2hi);
1639 2 make_combined(_mm512_castsi512_si256(pw_4), _mm512_castsi512_si256(pw_5), comb_45_g1lo, comb_45_g1hi);
1640 4 make_combined(_mm256_add_epi8(p0g2, _mm256_set1_epi8(4)), _mm256_add_epi8(p0g2, _mm256_set1_epi8(5)), comb_45_g2lo, comb_45_g2hi);
1641 2 make_combined(_mm512_castsi512_si256(pw_6), _mm512_castsi512_si256(pw_7), comb_67_g1lo, comb_67_g1hi);
1642 4 make_combined(_mm256_add_epi8(p0g2, _mm256_set1_epi8(6)), _mm256_add_epi8(p0g2, _mm256_set1_epi8(7)), comb_67_g2lo, comb_67_g2hi);
1643 }
1644
1645
4/8
void resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 535 → 145 taken 5 times.
✓ Branch 535 → 536 taken 1 time.
✗ Branch 543 → 145 not taken.
✗ Branch 543 → 544 not taken.
void resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 481 → 219 taken 5 times.
✓ Branch 481 → 482 taken 1 time.
✗ Branch 489 → 219 not taken.
✗ Branch 489 → 490 not taken.
12 for (int y = y_from; y < y_to; y++)
1646 {
1647 __m512i data_src, data_src2, data_src_2, data_src2_2;
1648
1649 if constexpr (partial_load) {
1650 data_src = _mm512_maskz_loadu_epi8(k1, src_ptr);
1651 data_src2 = _mm512_maskz_loadu_epi8(k2, src_ptr + 64);
1652 data_src_2 = _mm512_maskz_loadu_epi8(k1_2, src_ptr_2);
1653 data_src2_2 = _mm512_maskz_loadu_epi8(k2_2, src_ptr_2 + 64);
1654 }
1655 else {
1656 10 data_src = _mm512_loadu_si512(src_ptr);
1657 20 data_src2 = _mm512_loadu_si512(src_ptr + 64);
1658 10 data_src_2 = _mm512_loadu_si512(src_ptr_2);
1659 10 data_src2_2 = _mm512_loadu_si512(src_ptr_2 + 64);
1660 }
1661
1662 __m512i src_r0r1_0_31lo, src_r0r1_0_31hi, src_r0r1_32_63lo, src_r0r1_32_63hi;
1663 __m512i src_r2r3_0_31lo, src_r2r3_0_31hi, src_r2r3_32_63lo, src_r2r3_32_63hi;
1664
1665 if constexpr (UseVNNI) {
1666 // 512-bit vpermi2b keeps the full 128-byte source window (256-bit vpermi2b only
1667 // addresses 64 bytes, corrupting pixels whose index falls in data_src[32..63]).
1668 // castsi256_si512 on index = free (upper 32 index bytes are undefined but only
1669 // affect output bytes 32-63 which are discarded by castsi512_si256 = also free).
1670 20 src_r0r1_0_31lo = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(_mm512_permutex2var_epi8(data_src, _mm512_castsi256_si512(comb_01_g1lo), data_src2)));
1671 20 src_r0r1_0_31hi = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(_mm512_permutex2var_epi8(data_src, _mm512_castsi256_si512(comb_01_g1hi), data_src2)));
1672 20 src_r0r1_32_63lo = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(_mm512_permutex2var_epi8(data_src_2, _mm512_castsi256_si512(comb_01_g2lo), data_src2_2)));
1673 20 src_r0r1_32_63hi = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(_mm512_permutex2var_epi8(data_src_2, _mm512_castsi256_si512(comb_01_g2hi), data_src2_2)));
1674 20 src_r2r3_0_31lo = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(_mm512_permutex2var_epi8(data_src, _mm512_castsi256_si512(comb_23_g1lo), data_src2)));
1675 20 src_r2r3_0_31hi = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(_mm512_permutex2var_epi8(data_src, _mm512_castsi256_si512(comb_23_g1hi), data_src2)));
1676 20 src_r2r3_32_63lo = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(_mm512_permutex2var_epi8(data_src_2, _mm512_castsi256_si512(comb_23_g2lo), data_src2_2)));
1677 20 src_r2r3_32_63hi = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(_mm512_permutex2var_epi8(data_src_2, _mm512_castsi256_si512(comb_23_g2hi), data_src2_2)));
1678 } else {
1679 // BASE: sim_get32 returns 32 16-bit words with gathered bytes in low 8 bits;
1680 // feed unpacklo/hi directly — avoids cvtepu8_epi16 round-trip
1681 5 __m512i d0l = _permutex2var_epi8_sim_get32(wi_lo_0, sa_lo_0, data_src, data_src2);
1682 5 __m512i d0h = _permutex2var_epi8_sim_get32(wi_hi_0, sa_hi_0, data_src_2, data_src2_2);
1683 5 __m512i d1l = _permutex2var_epi8_sim_get32(wi_lo_1, sa_lo_1, data_src, data_src2);
1684 5 __m512i d1h = _permutex2var_epi8_sim_get32(wi_hi_1, sa_hi_1, data_src_2, data_src2_2);
1685 5 __m512i d2l = _permutex2var_epi8_sim_get32(wi_lo_2, sa_lo_2, data_src, data_src2);
1686 5 __m512i d2h = _permutex2var_epi8_sim_get32(wi_hi_2, sa_hi_2, data_src_2, data_src2_2);
1687 5 __m512i d3l = _permutex2var_epi8_sim_get32(wi_lo_3, sa_lo_3, data_src, data_src2);
1688 10 __m512i d3h = _permutex2var_epi8_sim_get32(wi_hi_3, sa_hi_3, data_src_2, data_src2_2);
1689 5 src_r0r1_0_31lo = _mm512_unpacklo_epi16(d0l, d1l);
1690 5 src_r0r1_0_31hi = _mm512_unpackhi_epi16(d0l, d1l);
1691 5 src_r0r1_32_63lo = _mm512_unpacklo_epi16(d0h, d1h);
1692 5 src_r0r1_32_63hi = _mm512_unpackhi_epi16(d0h, d1h);
1693 5 src_r2r3_0_31lo = _mm512_unpacklo_epi16(d2l, d3l);
1694 5 src_r2r3_0_31hi = _mm512_unpackhi_epi16(d2l, d3l);
1695 5 src_r2r3_32_63lo = _mm512_unpacklo_epi16(d2h, d3h);
1696 5 src_r2r3_32_63hi = _mm512_unpackhi_epi16(d2h, d3h);
1697 }
1698
1699 __m512i result_0_31lo, result_0_31hi, result_32_63lo, result_32_63hi;
1700
1701 if constexpr (UseVNNI)
1702 {
1703 5 result_0_31lo = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31lo, coef_r0r1_0_31lo);
1704 5 result_0_31hi = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31hi, coef_r0r1_0_31hi);
1705 5 result_32_63lo = _mm512_dpwssd_epi32(rounder, src_r0r1_32_63lo, coef_r0r1_32_63lo);
1706 10 result_32_63hi = _mm512_dpwssd_epi32(rounder, src_r0r1_32_63hi, coef_r0r1_32_63hi);
1707 5 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r2r3_0_31lo, coef_r2r3_0_31lo);
1708 5 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r2r3_0_31hi, coef_r2r3_0_31hi);
1709 5 result_32_63lo = _mm512_dpwssd_epi32(result_32_63lo, src_r2r3_32_63lo, coef_r2r3_32_63lo);
1710 5 result_32_63hi = _mm512_dpwssd_epi32(result_32_63hi, src_r2r3_32_63hi, coef_r2r3_32_63hi);
1711 }
1712 else
1713 {
1714 15 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo));
1715 15 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi));
1716 15 result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63lo, coef_r0r1_32_63lo), _mm512_madd_epi16(src_r2r3_32_63lo, coef_r2r3_32_63lo));
1717 10 result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63hi, coef_r0r1_32_63hi), _mm512_madd_epi16(src_r2r3_32_63hi, coef_r2r3_32_63hi));
1718 }
1719
1720 __m512i src_r4r5_0_31lo, src_r4r5_0_31hi, src_r4r5_32_63lo, src_r4r5_32_63hi;
1721 __m512i src_r6r7_0_31lo, src_r6r7_0_31hi, src_r6r7_32_63lo, src_r6r7_32_63hi;
1722
1723 if constexpr (UseVNNI) {
1724 20 src_r4r5_0_31lo = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(_mm512_permutex2var_epi8(data_src, _mm512_castsi256_si512(comb_45_g1lo), data_src2)));
1725 20 src_r4r5_0_31hi = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(_mm512_permutex2var_epi8(data_src, _mm512_castsi256_si512(comb_45_g1hi), data_src2)));
1726 20 src_r4r5_32_63lo = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(_mm512_permutex2var_epi8(data_src_2, _mm512_castsi256_si512(comb_45_g2lo), data_src2_2)));
1727 20 src_r4r5_32_63hi = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(_mm512_permutex2var_epi8(data_src_2, _mm512_castsi256_si512(comb_45_g2hi), data_src2_2)));
1728 20 src_r6r7_0_31lo = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(_mm512_permutex2var_epi8(data_src, _mm512_castsi256_si512(comb_67_g1lo), data_src2)));
1729 20 src_r6r7_0_31hi = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(_mm512_permutex2var_epi8(data_src, _mm512_castsi256_si512(comb_67_g1hi), data_src2)));
1730 20 src_r6r7_32_63lo = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(_mm512_permutex2var_epi8(data_src_2, _mm512_castsi256_si512(comb_67_g2lo), data_src2_2)));
1731 25 src_r6r7_32_63hi = _mm512_cvtepu8_epi16(_mm512_castsi512_si256(_mm512_permutex2var_epi8(data_src_2, _mm512_castsi256_si512(comb_67_g2hi), data_src2_2)));
1732 } else {
1733 5 __m512i d4l = _permutex2var_epi8_sim_get32(wi_lo_4, sa_lo_4, data_src, data_src2);
1734 5 __m512i d4h = _permutex2var_epi8_sim_get32(wi_hi_4, sa_hi_4, data_src_2, data_src2_2);
1735 5 __m512i d5l = _permutex2var_epi8_sim_get32(wi_lo_5, sa_lo_5, data_src, data_src2);
1736 5 __m512i d5h = _permutex2var_epi8_sim_get32(wi_hi_5, sa_hi_5, data_src_2, data_src2_2);
1737 5 __m512i d6l = _permutex2var_epi8_sim_get32(wi_lo_6, sa_lo_6, data_src, data_src2);
1738 5 __m512i d6h = _permutex2var_epi8_sim_get32(wi_hi_6, sa_hi_6, data_src_2, data_src2_2);
1739 5 __m512i d7l = _permutex2var_epi8_sim_get32(wi_lo_7, sa_lo_7, data_src, data_src2);
1740 10 __m512i d7h = _permutex2var_epi8_sim_get32(wi_hi_7, sa_hi_7, data_src_2, data_src2_2);
1741 5 src_r4r5_0_31lo = _mm512_unpacklo_epi16(d4l, d5l);
1742 5 src_r4r5_0_31hi = _mm512_unpackhi_epi16(d4l, d5l);
1743 5 src_r4r5_32_63lo = _mm512_unpacklo_epi16(d4h, d5h);
1744 5 src_r4r5_32_63hi = _mm512_unpackhi_epi16(d4h, d5h);
1745 5 src_r6r7_0_31lo = _mm512_unpacklo_epi16(d6l, d7l);
1746 5 src_r6r7_0_31hi = _mm512_unpackhi_epi16(d6l, d7l);
1747 5 src_r6r7_32_63lo = _mm512_unpacklo_epi16(d6h, d7h);
1748 5 src_r6r7_32_63hi = _mm512_unpackhi_epi16(d6h, d7h);
1749 }
1750
1751 if constexpr (UseVNNI)
1752 {
1753 5 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r4r5_0_31lo, coef_r4r5_0_31lo);
1754 5 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r4r5_0_31hi, coef_r4r5_0_31hi);
1755 5 result_32_63lo = _mm512_dpwssd_epi32(result_32_63lo, src_r4r5_32_63lo, coef_r4r5_32_63lo);
1756 5 result_32_63hi = _mm512_dpwssd_epi32(result_32_63hi, src_r4r5_32_63hi, coef_r4r5_32_63hi);
1757 5 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r6r7_0_31lo, coef_r6r7_0_31lo);
1758 5 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r6r7_0_31hi, coef_r6r7_0_31hi);
1759 5 result_32_63lo = _mm512_dpwssd_epi32(result_32_63lo, src_r6r7_32_63lo, coef_r6r7_32_63lo);
1760 5 result_32_63hi = _mm512_dpwssd_epi32(result_32_63hi, src_r6r7_32_63hi, coef_r6r7_32_63hi);
1761 }
1762 else
1763 {
1764 10 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31lo, coef_r4r5_0_31lo), result_0_31lo);
1765 10 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31hi, coef_r4r5_0_31hi), result_0_31hi);
1766 10 result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_32_63lo, coef_r4r5_32_63lo), result_32_63lo);
1767 10 result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_32_63hi, coef_r4r5_32_63hi), result_32_63hi);
1768 10 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31lo, coef_r6r7_0_31lo), result_0_31lo);
1769 10 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31hi, coef_r6r7_0_31hi), result_0_31hi);
1770 10 result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_32_63lo, coef_r6r7_32_63lo), result_32_63lo);
1771 5 result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_32_63hi, coef_r6r7_32_63hi), result_32_63hi);
1772
1773 5 result_0_31lo = _mm512_add_epi32(result_0_31lo, rounder);
1774 5 result_0_31hi = _mm512_add_epi32(result_0_31hi, rounder);
1775 5 result_32_63lo = _mm512_add_epi32(result_32_63lo, rounder);
1776 10 result_32_63hi = _mm512_add_epi32(result_32_63hi, rounder);
1777 }
1778
1779 10 result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale8bits);
1780 10 result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale8bits);
1781 10 result_32_63lo = _mm512_srai_epi32(result_32_63lo, FPScale8bits);
1782 10 result_32_63hi = _mm512_srai_epi32(result_32_63hi, FPScale8bits);
1783
1784 10 __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);
1785 10 __m512i result_32_63_int16 = _mm512_packus_epi32(result_32_63lo, result_32_63hi);
1786
1787 10 __m256i result_0_31_u8 = _mm512_cvtusepi16_epi8(result_0_31_int16);
1788 10 __m256i result_32_63_u8 = _mm512_cvtusepi16_epi8(result_32_63_int16);
1789
1790 20 _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr), _mm512_inserti64x4(_mm512_castsi256_si512(result_0_31_u8), result_32_63_u8, 1));
1791
1792 10 dst_ptr += dst_pitch;
1793 10 src_ptr += src_pitch;
1794 10 src_ptr_2 += src_pitch;
1795 }
1796
1797 2 current_coeff_SIMD += 16;
1798 };
1799
1800
4/4
void resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 12 → 10 taken 1 time.
✓ Branch 12 → 13 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 12 → 10 taken 1 time.
✓ Branch 12 → 13 taken 1 time.
4 for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)
1801 {
1802
1/2
✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 20 not taken.
2 do_h_integer_core(std::false_type{});
1803 }
1804
1805
2/4
void resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_pretransposed_coeffs_internal<false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 16 → 14 not taken.
✓ Branch 16 → 17 taken 1 time.
void resize_h_planar_uint8_avx512_permutex_vstripe_2s32_ks8_pretransposed_coeffs_internal<true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 16 → 14 not taken.
✓ Branch 16 → 17 taken 1 time.
2 for (; x < width; x += PIXELS_AT_A_TIME)
1806 {
1807 do_h_integer_core(std::true_type{});
1808 }
1809 }
1810 2 }
1811
1812 // filter size up to 4, pretransposed coefficients
1813 // 64 target uint16_t pixels at a time in 2 groups of 32
1814 template<bool lessthan16bit, bool UseVNNI>
1815 9 void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)
1816 {
1817 9 const uint16_t* src = (uint16_t*)src8;
1818 9 uint16_t* AVS_RESTRICT dst = (uint16_t* AVS_RESTRICT)dst8;
1819 9 dst_pitch = dst_pitch / sizeof(uint16_t);
1820 9 src_pitch = src_pitch / sizeof(uint16_t);
1821
1822 9 constexpr int PIXELS_AT_A_TIME = 64;
1823
1824
4/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 4 not taken.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 2 → 3 taken 6 times.
✗ Branch 2 → 4 not taken.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 4 not taken.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 4 not taken.
9 const int width_safe_mod = (program->safelimit_64_pixels_each32th_target.overread_possible ? program->safelimit_64_pixels_each32th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;
1825
1826
4/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 6 times.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 1 time.
9 assert(program->filter_size_real <= 4);
1827
4/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 6 times.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 1 time.
9 assert(program->target_size_alignment >= 64);
1828 assert(FRAME_ALIGN >= 64);
1829
4/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 6 times.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 1 time.
9 assert(program->filter_size_alignment >= 4);
1830
1831 9 const int max_scanlines = program->max_scanlines;
1832
1833 9 const __m512i shifttosigned = _mm512_set1_epi16(-32768);
1834 9 const __m512i shiftfromsigned = _mm512_set1_epi32(32768 << FPScale16bits);
1835
1836 9 const int limit = (1 << bits_per_pixel) - 1;
1837 18 __m512i clamp_limit = _mm512_set1_epi16((short)limit);
1838 9 __m512i rounder = _mm512_set1_epi32(1 << (FPScale16bits - 1));
1839
1840
8/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 30 → 20 taken 1 time.
✓ Branch 30 → 31 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 30 → 20 taken 6 times.
✓ Branch 30 → 31 taken 6 times.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 30 → 20 taken 1 time.
✓ Branch 30 → 31 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 30 → 20 taken 1 time.
✓ Branch 30 → 31 taken 1 time.
18 for (int y_from = 0; y_from < height; y_from += max_scanlines)
1841 {
1842 9 int y_to = std::min(y_from + max_scanlines, height);
1843
1844 9 const __m512i* AVS_RESTRICT current_coeff_SIMD = (__m512i*)program->pixel_coefficient_AVX512_H;
1845
1846 9 int x = 0;
1847
1848 26 auto do_h_integer_core = [&](auto partial_load) {
1849 17 __m512i one_epi16 = _mm512_set1_epi16(1);
1850
1851 17 const __m512i coef_r0r1_0_31lo = _mm512_load_si512(current_coeff_SIMD + 0);
1852 17 const __m512i coef_r0r1_0_31hi = _mm512_load_si512(current_coeff_SIMD + 1);
1853 17 const __m512i coef_r0r1_32_63lo = _mm512_load_si512(current_coeff_SIMD + 2);
1854 17 const __m512i coef_r0r1_32_63hi = _mm512_load_si512(current_coeff_SIMD + 3);
1855 17 const __m512i coef_r2r3_0_31lo = _mm512_load_si512(current_coeff_SIMD + 4);
1856 17 const __m512i coef_r2r3_0_31hi = _mm512_load_si512(current_coeff_SIMD + 5);
1857 17 const __m512i coef_r2r3_32_63lo = _mm512_load_si512(current_coeff_SIMD + 6);
1858 17 const __m512i coef_r2r3_32_63hi = _mm512_load_si512(current_coeff_SIMD + 7);
1859
1860 17 __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x]));
1861 17 __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16]));
1862 17 __m512i perm_0_32_47 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 32]));
1863 17 __m512i perm_0_48_63 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 48]));
1864
1865 17 int iStart_0_31 = program->pixel_offset[x];
1866 17 int iStart_32_63 = program->pixel_offset[x + 32];
1867 17 __m512i m512i_Start_0_31 = _mm512_set1_epi32(iStart_0_31);
1868 17 __m512i m512i_Start_32_63 = _mm512_set1_epi32(iStart_32_63);
1869
1870 17 perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start_0_31);
1871 17 perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start_0_31);
1872 17 perm_0_32_47 = _mm512_sub_epi32(perm_0_32_47, m512i_Start_32_63);
1873 17 perm_0_48_63 = _mm512_sub_epi32(perm_0_48_63, m512i_Start_32_63);
1874
1875 17 __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);
1876 17 __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);
1877 17 __m256i m256i_perm_0_32_47 = _mm512_cvtepi32_epi16(perm_0_32_47);
1878 17 __m256i m256i_perm_0_48_63 = _mm512_cvtepi32_epi16(perm_0_48_63);
1879
1880 34 __m512i perm_0_0_31 = _mm512_inserti64x4(_mm512_castsi256_si512(m256i_perm_0_0_15), m256i_perm_0_16_31, 1);
1881 34 __m512i perm_0_32_63 = _mm512_inserti64x4(_mm512_castsi256_si512(m256i_perm_0_32_47), m256i_perm_0_48_63, 1);
1882
1883 17 __m512i perm_1_0_31 = _mm512_add_epi16(perm_0_0_31, one_epi16);
1884 17 __m512i perm_1_32_63 = _mm512_add_epi16(perm_0_32_63, one_epi16);
1885
1886 17 const __m512i perm_r0r1_0_31lo = _mm512_unpacklo_epi16(perm_0_0_31, perm_1_0_31);
1887 17 const __m512i perm_r0r1_0_31hi = _mm512_unpackhi_epi16(perm_0_0_31, perm_1_0_31);
1888 17 const __m512i perm_r0r1_32_63lo = _mm512_unpacklo_epi16(perm_0_32_63, perm_1_32_63);
1889 17 const __m512i perm_r0r1_32_63hi = _mm512_unpackhi_epi16(perm_0_32_63, perm_1_32_63);
1890
1891 17 const __m512i two_epi16 = _mm512_set1_epi16(2);
1892
1893 17 uint16_t* AVS_RESTRICT dst_ptr = dst + x + y_from * dst_pitch;
1894 17 const uint16_t* src_ptr_0_31 = src + iStart_0_31 + y_from * src_pitch;
1895 17 const uint16_t* src_ptr_32_63 = src + iStart_32_63 + y_from * src_pitch;
1896
1897 17 const int remaining_0_31 = program->source_size - iStart_0_31;
1898 17 const __mmask32 k1_0_31 = _bzhi_u32(~0UL, remaining_0_31);
1899 17 const __mmask32 k2_0_31 = _bzhi_u32(~0UL, remaining_0_31 - 32);
1900 17 const int remaining_32_63 = program->source_size - iStart_32_63;
1901 17 const __mmask32 k1_32_63 = _bzhi_u32(~0UL, remaining_32_63);
1902 17 const __mmask32 k2_32_63 = _bzhi_u32(~0UL, remaining_32_63 - 32);
1903
1904
16/16
✓ Branch 178 → 101 taken 10 times.
✓ Branch 178 → 179 taken 2 times.
✓ Branch 186 → 101 taken 5 times.
✓ Branch 186 → 187 taken 1 time.
✓ Branch 194 → 101 taken 10 times.
✓ Branch 194 → 195 taken 2 times.
✓ Branch 202 → 101 taken 26 times.
✓ Branch 202 → 203 taken 6 times.
✓ Branch 210 → 101 taken 10 times.
✓ Branch 210 → 211 taken 2 times.
✓ Branch 218 → 101 taken 5 times.
✓ Branch 218 → 219 taken 1 time.
✓ Branch 226 → 101 taken 10 times.
✓ Branch 226 → 227 taken 2 times.
✓ Branch 234 → 101 taken 5 times.
✓ Branch 234 → 235 taken 1 time.
98 for (int y = y_from; y < y_to; y++)
1905 {
1906 __m512i data_src_0_31, data_src2_0_31, data_src_32_63, data_src2_32_63;
1907
1908 81 __m512i perm_rNrNp1_0_31lo = perm_r0r1_0_31lo;
1909 81 __m512i perm_rNrNp1_0_31hi = perm_r0r1_0_31hi;
1910 81 __m512i perm_rNrNp1_32_63lo = perm_r0r1_32_63lo;
1911 81 __m512i perm_rNrNp1_32_63hi = perm_r0r1_32_63hi;
1912
1913 if constexpr (partial_load) {
1914 41 data_src_0_31 = _mm512_maskz_loadu_epi16(k1_0_31, src_ptr_0_31);
1915 82 data_src2_0_31 = _mm512_maskz_loadu_epi16(k2_0_31, src_ptr_0_31 + 32);
1916 41 data_src_32_63 = _mm512_maskz_loadu_epi16(k1_32_63, src_ptr_32_63);
1917 82 data_src2_32_63 = _mm512_maskz_loadu_epi16(k2_32_63, src_ptr_32_63 + 32);
1918 }
1919 else {
1920 40 data_src_0_31 = _mm512_loadu_si512(src_ptr_0_31);
1921 80 data_src2_0_31 = _mm512_loadu_si512(src_ptr_0_31 + 32);
1922 40 data_src_32_63 = _mm512_loadu_si512(src_ptr_32_63);
1923 80 data_src2_32_63 = _mm512_loadu_si512(src_ptr_32_63 + 32);
1924 }
1925
1926 81 __m512i src_r0r1_0_31lo = _mm512_permutex2var_epi16(data_src_0_31, perm_rNrNp1_0_31lo, data_src2_0_31);
1927 81 __m512i src_r0r1_0_31hi = _mm512_permutex2var_epi16(data_src_0_31, perm_rNrNp1_0_31hi, data_src2_0_31);
1928 81 __m512i src_r0r1_32_63lo = _mm512_permutex2var_epi16(data_src_32_63, perm_rNrNp1_32_63lo, data_src2_32_63);
1929 81 __m512i src_r0r1_32_63hi = _mm512_permutex2var_epi16(data_src_32_63, perm_rNrNp1_32_63hi, data_src2_32_63);
1930
1931 // for r2r3
1932 81 perm_rNrNp1_0_31lo = _mm512_add_epi16(perm_rNrNp1_0_31lo, two_epi16);
1933 81 perm_rNrNp1_0_31hi = _mm512_add_epi16(perm_rNrNp1_0_31hi, two_epi16);
1934 81 perm_rNrNp1_32_63lo = _mm512_add_epi16(perm_rNrNp1_32_63lo, two_epi16);
1935 81 perm_rNrNp1_32_63hi = _mm512_add_epi16(perm_rNrNp1_32_63hi, two_epi16);
1936
1937 if constexpr (!lessthan16bit) {
1938 51 src_r0r1_0_31lo = _mm512_add_epi16(src_r0r1_0_31lo, shifttosigned);
1939 51 src_r0r1_0_31hi = _mm512_add_epi16(src_r0r1_0_31hi, shifttosigned);
1940 51 src_r0r1_32_63lo = _mm512_add_epi16(src_r0r1_32_63lo, shifttosigned);
1941 51 src_r0r1_32_63hi = _mm512_add_epi16(src_r0r1_32_63hi, shifttosigned);
1942 }
1943
1944 __m512i result_0_31lo, result_0_31hi, result_32_63lo, result_32_63hi;
1945
1946 if constexpr (UseVNNI)
1947 {
1948 51 result_0_31lo = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31lo, coef_r0r1_0_31lo);
1949 51 result_0_31hi = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31hi, coef_r0r1_0_31hi);
1950 51 result_32_63lo = _mm512_dpwssd_epi32(rounder, src_r0r1_32_63lo, coef_r0r1_32_63lo);
1951 102 result_32_63hi = _mm512_dpwssd_epi32(rounder, src_r0r1_32_63hi, coef_r0r1_32_63hi);
1952 }
1953 else
1954 {
1955 60 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), rounder);
1956 60 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), rounder);
1957 60 result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63lo, coef_r0r1_32_63lo), rounder);
1958 90 result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63hi, coef_r0r1_32_63hi), rounder);
1959 }
1960
1961 81 __m512i src_r2r3_0_31lo = _mm512_permutex2var_epi16(data_src_0_31, perm_rNrNp1_0_31lo, data_src2_0_31);
1962 81 __m512i src_r2r3_0_31hi = _mm512_permutex2var_epi16(data_src_0_31, perm_rNrNp1_0_31hi, data_src2_0_31);
1963 81 __m512i src_r2r3_32_63lo = _mm512_permutex2var_epi16(data_src_32_63, perm_rNrNp1_32_63lo, data_src2_32_63);
1964 30 __m512i src_r2r3_32_63hi = _mm512_permutex2var_epi16(data_src_32_63, perm_rNrNp1_32_63hi, data_src2_32_63);
1965
1966 if constexpr (!lessthan16bit) {
1967 51 src_r2r3_0_31lo = _mm512_add_epi16(src_r2r3_0_31lo, shifttosigned);
1968 51 src_r2r3_0_31hi = _mm512_add_epi16(src_r2r3_0_31hi, shifttosigned);
1969 51 src_r2r3_32_63lo = _mm512_add_epi16(src_r2r3_32_63lo, shifttosigned);
1970 102 src_r2r3_32_63hi = _mm512_add_epi16(src_r2r3_32_63hi, shifttosigned);
1971 }
1972
1973 if constexpr (UseVNNI)
1974 {
1975 51 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r2r3_0_31lo, coef_r2r3_0_31lo);
1976 51 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r2r3_0_31hi, coef_r2r3_0_31hi);
1977 51 result_32_63lo = _mm512_dpwssd_epi32(result_32_63lo, src_r2r3_32_63lo, coef_r2r3_32_63lo);
1978 15 result_32_63hi = _mm512_dpwssd_epi32(result_32_63hi, src_r2r3_32_63hi, coef_r2r3_32_63hi);
1979 }
1980 else
1981 {
1982 60 result_0_31lo = _mm512_add_epi32(result_0_31lo, _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo));
1983 60 result_0_31hi = _mm512_add_epi32(result_0_31hi, _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi));
1984 60 result_32_63lo = _mm512_add_epi32(result_32_63lo, _mm512_madd_epi16(src_r2r3_32_63lo, coef_r2r3_32_63lo));
1985 45 result_32_63hi = _mm512_add_epi32(result_32_63hi, _mm512_madd_epi16(src_r2r3_32_63hi, coef_r2r3_32_63hi));
1986 }
1987
1988 if constexpr (!lessthan16bit) {
1989 51 result_0_31lo = _mm512_add_epi32(result_0_31lo, shiftfromsigned);
1990 51 result_0_31hi = _mm512_add_epi32(result_0_31hi, shiftfromsigned);
1991 51 result_32_63lo = _mm512_add_epi32(result_32_63lo, shiftfromsigned);
1992 102 result_32_63hi = _mm512_add_epi32(result_32_63hi, shiftfromsigned);
1993 }
1994
1995 81 result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale16bits);
1996 81 result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale16bits);
1997 81 result_32_63lo = _mm512_srai_epi32(result_32_63lo, FPScale16bits);
1998 81 result_32_63hi = _mm512_srai_epi32(result_32_63hi, FPScale16bits);
1999
2000 81 __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);
2001 51 __m512i result_32_63_int16 = _mm512_packus_epi32(result_32_63lo, result_32_63hi);
2002
2003 if constexpr (lessthan16bit) {
2004 30 result_0_31_int16 = _mm512_min_epu16(result_0_31_int16, clamp_limit);
2005 60 result_32_63_int16 = _mm512_min_epu16(result_32_63_int16, clamp_limit);
2006 }
2007
2008 _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr), result_0_31_int16);
2009
2010 81 const int w_mod32 = width / 32 * 32;
2011
9/16
✓ Branch 174 → 175 taken 10 times.
✗ Branch 174 → 177 not taken.
✓ Branch 182 → 183 taken 5 times.
✗ Branch 182 → 185 not taken.
✓ Branch 190 → 191 taken 10 times.
✗ Branch 190 → 193 not taken.
✓ Branch 198 → 199 taken 5 times.
✓ Branch 198 → 201 taken 21 times.
✓ Branch 206 → 207 taken 10 times.
✗ Branch 206 → 209 not taken.
✓ Branch 214 → 215 taken 5 times.
✗ Branch 214 → 217 not taken.
✓ Branch 222 → 223 taken 10 times.
✗ Branch 222 → 225 not taken.
✓ Branch 230 → 231 taken 5 times.
✗ Branch 230 → 233 not taken.
81 if (x < (w_mod32 - 32))
2012 60 _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr + 32), result_32_63_int16);
2013
2014 81 dst_ptr += dst_pitch;
2015 81 src_ptr_0_31 += src_pitch;
2016 81 src_ptr_32_63 += src_pitch;
2017 }
2018
2019 17 current_coeff_SIMD += 8;
2020 };
2021
2022
8/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 22 taken 2 times.
✓ Branch 24 → 25 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 22 taken 2 times.
✓ Branch 24 → 25 taken 6 times.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 22 taken 2 times.
✓ Branch 24 → 25 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 22 taken 2 times.
✓ Branch 24 → 25 taken 1 time.
17 for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)
2023 {
2024 8 do_h_integer_core(std::false_type{});
2025 }
2026
2027
8/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 28 → 26 taken 1 time.
✓ Branch 28 → 29 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 28 → 26 taken 6 times.
✓ Branch 28 → 29 taken 6 times.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 28 → 26 taken 1 time.
✓ Branch 28 → 29 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks4_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 28 → 26 taken 1 time.
✓ Branch 28 → 29 taken 1 time.
18 for (; x < width; x += PIXELS_AT_A_TIME)
2028 {
2029 9 do_h_integer_core(std::true_type{});
2030 }
2031 }
2032 9 }
2033
2034 template<bool lessthan16bit, bool UseVNNI>
2035 7 void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks8_pretransposed_coeffs_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)
2036 {
2037 7 const uint16_t* src = (uint16_t*)src8;
2038 7 uint16_t* AVS_RESTRICT dst = (uint16_t* AVS_RESTRICT)dst8;
2039 7 dst_pitch = dst_pitch / sizeof(uint16_t);
2040 7 src_pitch = src_pitch / sizeof(uint16_t);
2041
2042 7 constexpr int PIXELS_AT_A_TIME = 64;
2043
2044
4/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks8_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 4 not taken.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks8_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 2 → 3 taken 4 times.
✗ Branch 2 → 4 not taken.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks8_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 4 not taken.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks8_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 4 not taken.
7 const int width_safe_mod = (program->safelimit_64_pixels_each32th_target.overread_possible ? program->safelimit_64_pixels_each32th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;
2045
2046 7 const int max_scanlines = program->max_scanlines;
2047
2048 7 const __m512i shifttosigned = _mm512_set1_epi16(-32768);
2049 7 const __m512i shiftfromsigned = _mm512_set1_epi32(32768 << FPScale16bits);
2050
2051 7 const int limit = (1 << bits_per_pixel) - 1;
2052 14 __m512i clamp_limit = _mm512_set1_epi16((short)limit);
2053 7 __m512i rounder = _mm512_set1_epi32(1 << (FPScale16bits - 1));
2054
2055
8/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks8_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 14 taken 1 time.
✓ Branch 24 → 25 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks8_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 14 taken 4 times.
✓ Branch 24 → 25 taken 4 times.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks8_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 14 taken 1 time.
✓ Branch 24 → 25 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks8_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 14 taken 1 time.
✓ Branch 24 → 25 taken 1 time.
14 for (int y_from = 0; y_from < height; y_from += max_scanlines)
2056 {
2057 7 int y_to = std::min(y_from + max_scanlines, height);
2058
2059 7 const __m512i* AVS_RESTRICT current_coeff_SIMD = (__m512i*)program->pixel_coefficient_AVX512_H;
2060
2061 7 int x = 0;
2062
2063 22 auto do_h_integer_core = [&](auto partial_load) {
2064 15 __m512i one_epi16 = _mm512_set1_epi16(1);
2065
2066 15 const __m512i coef_r0r1_0_31lo = _mm512_load_si512(current_coeff_SIMD + 0);
2067 15 const __m512i coef_r0r1_0_31hi = _mm512_load_si512(current_coeff_SIMD + 1);
2068 15 const __m512i coef_r0r1_32_63lo = _mm512_load_si512(current_coeff_SIMD + 2);
2069 15 const __m512i coef_r0r1_32_63hi = _mm512_load_si512(current_coeff_SIMD + 3);
2070 15 const __m512i coef_r2r3_0_31lo = _mm512_load_si512(current_coeff_SIMD + 4);
2071 15 const __m512i coef_r2r3_0_31hi = _mm512_load_si512(current_coeff_SIMD + 5);
2072 15 const __m512i coef_r2r3_32_63lo = _mm512_load_si512(current_coeff_SIMD + 6);
2073 15 const __m512i coef_r2r3_32_63hi = _mm512_load_si512(current_coeff_SIMD + 7);
2074 15 const __m512i coef_r4r5_0_31lo = _mm512_load_si512(current_coeff_SIMD + 8);
2075 15 const __m512i coef_r4r5_0_31hi = _mm512_load_si512(current_coeff_SIMD + 9);
2076 15 const __m512i coef_r4r5_32_63lo = _mm512_load_si512(current_coeff_SIMD + 10);
2077 15 const __m512i coef_r4r5_32_63hi = _mm512_load_si512(current_coeff_SIMD + 11);
2078 15 const __m512i coef_r6r7_0_31lo = _mm512_load_si512(current_coeff_SIMD + 12);
2079 15 const __m512i coef_r6r7_0_31hi = _mm512_load_si512(current_coeff_SIMD + 13);
2080 15 const __m512i coef_r6r7_32_63lo = _mm512_load_si512(current_coeff_SIMD + 14);
2081 15 const __m512i coef_r6r7_32_63hi = _mm512_load_si512(current_coeff_SIMD + 15);
2082
2083 15 __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x]));
2084 15 __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16]));
2085 15 __m512i perm_0_32_47 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 32]));
2086 15 __m512i perm_0_48_63 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 48]));
2087
2088 15 int iStart_0_31 = program->pixel_offset[x];
2089 15 int iStart_32_63 = program->pixel_offset[x + 32];
2090 15 __m512i m512i_Start_0_31 = _mm512_set1_epi32(iStart_0_31);
2091 15 __m512i m512i_Start_32_63 = _mm512_set1_epi32(iStart_32_63);
2092
2093 15 perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start_0_31);
2094 15 perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start_0_31);
2095 15 perm_0_32_47 = _mm512_sub_epi32(perm_0_32_47, m512i_Start_32_63);
2096 15 perm_0_48_63 = _mm512_sub_epi32(perm_0_48_63, m512i_Start_32_63);
2097
2098 15 __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);
2099 15 __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);
2100 15 __m256i m256i_perm_0_32_47 = _mm512_cvtepi32_epi16(perm_0_32_47);
2101 15 __m256i m256i_perm_0_48_63 = _mm512_cvtepi32_epi16(perm_0_48_63);
2102
2103 30 __m512i perm_0_0_31 = _mm512_inserti64x4(_mm512_castsi256_si512(m256i_perm_0_0_15), m256i_perm_0_16_31, 1);
2104 30 __m512i perm_0_32_63 = _mm512_inserti64x4(_mm512_castsi256_si512(m256i_perm_0_32_47), m256i_perm_0_48_63, 1);
2105
2106 15 __m512i perm_1_0_31 = _mm512_add_epi16(perm_0_0_31, one_epi16);
2107 15 __m512i perm_1_32_63 = _mm512_add_epi16(perm_0_32_63, one_epi16);
2108
2109 15 const __m512i perm_r0r1_0_31lo = _mm512_unpacklo_epi16(perm_0_0_31, perm_1_0_31);
2110 15 const __m512i perm_r0r1_0_31hi = _mm512_unpackhi_epi16(perm_0_0_31, perm_1_0_31);
2111 15 const __m512i perm_r0r1_32_63lo = _mm512_unpacklo_epi16(perm_0_32_63, perm_1_32_63);
2112 15 const __m512i perm_r0r1_32_63hi = _mm512_unpackhi_epi16(perm_0_32_63, perm_1_32_63);
2113
2114 15 const __m512i two_epi16 = _mm512_set1_epi16(2);
2115
2116 15 uint16_t* AVS_RESTRICT dst_ptr = dst + x + y_from * dst_pitch;
2117 15 const uint16_t* src_ptr_0_31 = src + iStart_0_31 + y_from * src_pitch;
2118 15 const uint16_t* src_ptr_32_63 = src + iStart_32_63 + y_from * src_pitch;
2119
2120 15 const int remaining_0_31 = program->source_size - iStart_0_31;
2121 15 const __mmask32 k1_0_31 = _bzhi_u32(~0UL, remaining_0_31);
2122 15 const __mmask32 k2_0_31 = _bzhi_u32(~0UL, remaining_0_31 - 32);
2123 15 const int remaining_32_63 = program->source_size - iStart_32_63;
2124 15 const __mmask32 k1_32_63 = _bzhi_u32(~0UL, remaining_32_63);
2125 15 const __mmask32 k2_32_63 = _bzhi_u32(~0UL, remaining_32_63 - 32);
2126
2127
16/16
✓ Branch 242 → 117 taken 10 times.
✓ Branch 242 → 243 taken 2 times.
✓ Branch 250 → 117 taken 5 times.
✓ Branch 250 → 251 taken 1 time.
✓ Branch 274 → 117 taken 10 times.
✓ Branch 274 → 275 taken 2 times.
✓ Branch 282 → 117 taken 20 times.
✓ Branch 282 → 283 taken 4 times.
✓ Branch 306 → 117 taken 10 times.
✓ Branch 306 → 307 taken 2 times.
✓ Branch 314 → 117 taken 5 times.
✓ Branch 314 → 315 taken 1 time.
✓ Branch 338 → 117 taken 10 times.
✓ Branch 338 → 339 taken 2 times.
✓ Branch 346 → 117 taken 5 times.
✓ Branch 346 → 347 taken 1 time.
90 for (int y = y_from; y < y_to; y++)
2128 {
2129 __m512i data_src_0_31, data_src2_0_31, data_src_32_63, data_src2_32_63;
2130
2131 75 __m512i perm_rNrNp1_0_31lo = perm_r0r1_0_31lo;
2132 75 __m512i perm_rNrNp1_0_31hi = perm_r0r1_0_31hi;
2133 75 __m512i perm_rNrNp1_32_63lo = perm_r0r1_32_63lo;
2134 75 __m512i perm_rNrNp1_32_63hi = perm_r0r1_32_63hi;
2135
2136 if constexpr (partial_load) {
2137 35 data_src_0_31 = _mm512_maskz_loadu_epi16(k1_0_31, src_ptr_0_31);
2138 70 data_src2_0_31 = _mm512_maskz_loadu_epi16(k2_0_31, src_ptr_0_31 + 32);
2139 35 data_src_32_63 = _mm512_maskz_loadu_epi16(k1_32_63, src_ptr_32_63);
2140 70 data_src2_32_63 = _mm512_maskz_loadu_epi16(k2_32_63, src_ptr_32_63 + 32);
2141 }
2142 else {
2143 40 data_src_0_31 = _mm512_loadu_si512(src_ptr_0_31);
2144 80 data_src2_0_31 = _mm512_loadu_si512(src_ptr_0_31 + 32);
2145 40 data_src_32_63 = _mm512_loadu_si512(src_ptr_32_63);
2146 80 data_src2_32_63 = _mm512_loadu_si512(src_ptr_32_63 + 32);
2147 }
2148
2149 __m512i result_0_31lo, result_0_31hi, result_32_63lo, result_32_63hi;
2150
2151 75 __m512i src_r0r1_0_31lo = _mm512_permutex2var_epi16(data_src_0_31, perm_rNrNp1_0_31lo, data_src2_0_31);
2152 75 __m512i src_r0r1_0_31hi = _mm512_permutex2var_epi16(data_src_0_31, perm_rNrNp1_0_31hi, data_src2_0_31);
2153 75 __m512i src_r0r1_32_63lo = _mm512_permutex2var_epi16(data_src_32_63, perm_rNrNp1_32_63lo, data_src2_32_63);
2154 75 __m512i src_r0r1_32_63hi = _mm512_permutex2var_epi16(data_src_32_63, perm_rNrNp1_32_63hi, data_src2_32_63);
2155
2156 75 perm_rNrNp1_0_31lo = _mm512_add_epi16(perm_rNrNp1_0_31lo, two_epi16);
2157 75 perm_rNrNp1_0_31hi = _mm512_add_epi16(perm_rNrNp1_0_31hi, two_epi16);
2158 75 perm_rNrNp1_32_63lo = _mm512_add_epi16(perm_rNrNp1_32_63lo, two_epi16);
2159 75 perm_rNrNp1_32_63hi = _mm512_add_epi16(perm_rNrNp1_32_63hi, two_epi16);
2160
2161 if constexpr (!lessthan16bit) {
2162 45 src_r0r1_0_31lo = _mm512_add_epi16(src_r0r1_0_31lo, shifttosigned);
2163 45 src_r0r1_0_31hi = _mm512_add_epi16(src_r0r1_0_31hi, shifttosigned);
2164 45 src_r0r1_32_63lo = _mm512_add_epi16(src_r0r1_32_63lo, shifttosigned);
2165 45 src_r0r1_32_63hi = _mm512_add_epi16(src_r0r1_32_63hi, shifttosigned);
2166 }
2167
2168 if constexpr (UseVNNI)
2169 {
2170 45 result_0_31lo = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31lo, coef_r0r1_0_31lo);
2171 45 result_0_31hi = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31hi, coef_r0r1_0_31hi);
2172 45 result_32_63lo = _mm512_dpwssd_epi32(rounder, src_r0r1_32_63lo, coef_r0r1_32_63lo);
2173 90 result_32_63hi = _mm512_dpwssd_epi32(rounder, src_r0r1_32_63hi, coef_r0r1_32_63hi);
2174 }
2175 else
2176 {
2177 60 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), rounder);
2178 60 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), rounder);
2179 60 result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63lo, coef_r0r1_32_63lo), rounder);
2180 90 result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63hi, coef_r0r1_32_63hi), rounder);
2181 }
2182
2183 75 __m512i src_r2r3_0_31lo = _mm512_permutex2var_epi16(data_src_0_31, perm_rNrNp1_0_31lo, data_src2_0_31);
2184 75 __m512i src_r2r3_0_31hi = _mm512_permutex2var_epi16(data_src_0_31, perm_rNrNp1_0_31hi, data_src2_0_31);
2185 75 __m512i src_r2r3_32_63lo = _mm512_permutex2var_epi16(data_src_32_63, perm_rNrNp1_32_63lo, data_src2_32_63);
2186 75 __m512i src_r2r3_32_63hi = _mm512_permutex2var_epi16(data_src_32_63, perm_rNrNp1_32_63hi, data_src2_32_63);
2187
2188 75 perm_rNrNp1_0_31lo = _mm512_add_epi16(perm_rNrNp1_0_31lo, two_epi16);
2189 75 perm_rNrNp1_0_31hi = _mm512_add_epi16(perm_rNrNp1_0_31hi, two_epi16);
2190 75 perm_rNrNp1_32_63lo = _mm512_add_epi16(perm_rNrNp1_32_63lo, two_epi16);
2191 30 perm_rNrNp1_32_63hi = _mm512_add_epi16(perm_rNrNp1_32_63hi, two_epi16);
2192
2193 if constexpr (!lessthan16bit) {
2194 45 src_r2r3_0_31lo = _mm512_add_epi16(src_r2r3_0_31lo, shifttosigned);
2195 45 src_r2r3_0_31hi = _mm512_add_epi16(src_r2r3_0_31hi, shifttosigned);
2196 45 src_r2r3_32_63lo = _mm512_add_epi16(src_r2r3_32_63lo, shifttosigned);
2197 90 src_r2r3_32_63hi = _mm512_add_epi16(src_r2r3_32_63hi, shifttosigned);
2198 }
2199
2200 if constexpr (UseVNNI)
2201 {
2202 45 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r2r3_0_31lo, coef_r2r3_0_31lo);
2203 45 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r2r3_0_31hi, coef_r2r3_0_31hi);
2204 45 result_32_63lo = _mm512_dpwssd_epi32(result_32_63lo, src_r2r3_32_63lo, coef_r2r3_32_63lo);
2205 45 result_32_63hi = _mm512_dpwssd_epi32(result_32_63hi, src_r2r3_32_63hi, coef_r2r3_32_63hi);
2206 }
2207 else
2208 {
2209 60 result_0_31lo = _mm512_add_epi32(result_0_31lo, _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo));
2210 60 result_0_31hi = _mm512_add_epi32(result_0_31hi, _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi));
2211 60 result_32_63lo = _mm512_add_epi32(result_32_63lo, _mm512_madd_epi16(src_r2r3_32_63lo, coef_r2r3_32_63lo));
2212 60 result_32_63hi = _mm512_add_epi32(result_32_63hi, _mm512_madd_epi16(src_r2r3_32_63hi, coef_r2r3_32_63hi));
2213 }
2214
2215 75 __m512i src_r4r5_0_31lo = _mm512_permutex2var_epi16(data_src_0_31, perm_rNrNp1_0_31lo, data_src2_0_31);
2216 75 __m512i src_r4r5_0_31hi = _mm512_permutex2var_epi16(data_src_0_31, perm_rNrNp1_0_31hi, data_src2_0_31);
2217 75 __m512i src_r4r5_32_63lo = _mm512_permutex2var_epi16(data_src_32_63, perm_rNrNp1_32_63lo, data_src2_32_63);
2218 75 __m512i src_r4r5_32_63hi = _mm512_permutex2var_epi16(data_src_32_63, perm_rNrNp1_32_63hi, data_src2_32_63);
2219
2220 75 perm_rNrNp1_0_31lo = _mm512_add_epi16(perm_rNrNp1_0_31lo, two_epi16);
2221 75 perm_rNrNp1_0_31hi = _mm512_add_epi16(perm_rNrNp1_0_31hi, two_epi16);
2222 75 perm_rNrNp1_32_63lo = _mm512_add_epi16(perm_rNrNp1_32_63lo, two_epi16);
2223 30 perm_rNrNp1_32_63hi = _mm512_add_epi16(perm_rNrNp1_32_63hi, two_epi16);
2224
2225 if constexpr (!lessthan16bit) {
2226 45 src_r4r5_0_31lo = _mm512_add_epi16(src_r4r5_0_31lo, shifttosigned);
2227 45 src_r4r5_0_31hi = _mm512_add_epi16(src_r4r5_0_31hi, shifttosigned);
2228 45 src_r4r5_32_63lo = _mm512_add_epi16(src_r4r5_32_63lo, shifttosigned);
2229 90 src_r4r5_32_63hi = _mm512_add_epi16(src_r4r5_32_63hi, shifttosigned);
2230 }
2231
2232 if constexpr (UseVNNI)
2233 {
2234 45 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r4r5_0_31lo, coef_r4r5_0_31lo);
2235 45 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r4r5_0_31hi, coef_r4r5_0_31hi);
2236 45 result_32_63lo = _mm512_dpwssd_epi32(result_32_63lo, src_r4r5_32_63lo, coef_r4r5_32_63lo);
2237 45 result_32_63hi = _mm512_dpwssd_epi32(result_32_63hi, src_r4r5_32_63hi, coef_r4r5_32_63hi);
2238 }
2239 else
2240 {
2241 60 result_0_31lo = _mm512_add_epi32(result_0_31lo, _mm512_madd_epi16(src_r4r5_0_31lo, coef_r4r5_0_31lo));
2242 60 result_0_31hi = _mm512_add_epi32(result_0_31hi, _mm512_madd_epi16(src_r4r5_0_31hi, coef_r4r5_0_31hi));
2243 60 result_32_63lo = _mm512_add_epi32(result_32_63lo, _mm512_madd_epi16(src_r4r5_32_63lo, coef_r4r5_32_63lo));
2244 60 result_32_63hi = _mm512_add_epi32(result_32_63hi, _mm512_madd_epi16(src_r4r5_32_63hi, coef_r4r5_32_63hi));
2245 }
2246
2247 75 __m512i src_r6r7_0_31lo = _mm512_permutex2var_epi16(data_src_0_31, perm_rNrNp1_0_31lo, data_src2_0_31);
2248 75 __m512i src_r6r7_0_31hi = _mm512_permutex2var_epi16(data_src_0_31, perm_rNrNp1_0_31hi, data_src2_0_31);
2249 75 __m512i src_r6r7_32_63lo = _mm512_permutex2var_epi16(data_src_32_63, perm_rNrNp1_32_63lo, data_src2_32_63);
2250 30 __m512i src_r6r7_32_63hi = _mm512_permutex2var_epi16(data_src_32_63, perm_rNrNp1_32_63hi, data_src2_32_63);
2251
2252 if constexpr (!lessthan16bit) {
2253 45 src_r6r7_0_31lo = _mm512_add_epi16(src_r6r7_0_31lo, shifttosigned);
2254 45 src_r6r7_0_31hi = _mm512_add_epi16(src_r6r7_0_31hi, shifttosigned);
2255 45 src_r6r7_32_63lo = _mm512_add_epi16(src_r6r7_32_63lo, shifttosigned);
2256 90 src_r6r7_32_63hi = _mm512_add_epi16(src_r6r7_32_63hi, shifttosigned);
2257 }
2258
2259 if constexpr (UseVNNI)
2260 {
2261 45 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r6r7_0_31lo, coef_r6r7_0_31lo);
2262 45 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r6r7_0_31hi, coef_r6r7_0_31hi);
2263 45 result_32_63lo = _mm512_dpwssd_epi32(result_32_63lo, src_r6r7_32_63lo, coef_r6r7_32_63lo);
2264 15 result_32_63hi = _mm512_dpwssd_epi32(result_32_63hi, src_r6r7_32_63hi, coef_r6r7_32_63hi);
2265 }
2266 else
2267 {
2268 60 result_0_31lo = _mm512_add_epi32(result_0_31lo, _mm512_madd_epi16(src_r6r7_0_31lo, coef_r6r7_0_31lo));
2269 60 result_0_31hi = _mm512_add_epi32(result_0_31hi, _mm512_madd_epi16(src_r6r7_0_31hi, coef_r6r7_0_31hi));
2270 60 result_32_63lo = _mm512_add_epi32(result_32_63lo, _mm512_madd_epi16(src_r6r7_32_63lo, coef_r6r7_32_63lo));
2271 45 result_32_63hi = _mm512_add_epi32(result_32_63hi, _mm512_madd_epi16(src_r6r7_32_63hi, coef_r6r7_32_63hi));
2272 }
2273
2274 if constexpr (!lessthan16bit) {
2275 45 result_0_31lo = _mm512_add_epi32(result_0_31lo, shiftfromsigned);
2276 45 result_0_31hi = _mm512_add_epi32(result_0_31hi, shiftfromsigned);
2277 45 result_32_63lo = _mm512_add_epi32(result_32_63lo, shiftfromsigned);
2278 90 result_32_63hi = _mm512_add_epi32(result_32_63hi, shiftfromsigned);
2279 }
2280
2281 75 result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale16bits);
2282 75 result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale16bits);
2283 75 result_32_63lo = _mm512_srai_epi32(result_32_63lo, FPScale16bits);
2284 75 result_32_63hi = _mm512_srai_epi32(result_32_63hi, FPScale16bits);
2285
2286 75 __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);
2287 45 __m512i result_32_63_int16 = _mm512_packus_epi32(result_32_63lo, result_32_63hi);
2288
2289 if constexpr (lessthan16bit) {
2290 30 result_0_31_int16 = _mm512_min_epu16(result_0_31_int16, clamp_limit);
2291 60 result_32_63_int16 = _mm512_min_epu16(result_32_63_int16, clamp_limit);
2292 }
2293
2294 _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr), result_0_31_int16);
2295
2296 75 const int w_mod32 = width / 32 * 32;
2297
9/16
✓ Branch 238 → 239 taken 10 times.
✗ Branch 238 → 241 not taken.
✓ Branch 246 → 247 taken 5 times.
✗ Branch 246 → 249 not taken.
✓ Branch 270 → 271 taken 10 times.
✗ Branch 270 → 273 not taken.
✓ Branch 278 → 279 taken 5 times.
✓ Branch 278 → 281 taken 15 times.
✓ Branch 302 → 303 taken 10 times.
✗ Branch 302 → 305 not taken.
✓ Branch 310 → 311 taken 5 times.
✗ Branch 310 → 313 not taken.
✓ Branch 334 → 335 taken 10 times.
✗ Branch 334 → 337 not taken.
✓ Branch 342 → 343 taken 5 times.
✗ Branch 342 → 345 not taken.
75 if (x < (w_mod32 - 32))
2298 60 _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr + 32), result_32_63_int16);
2299
2300 75 dst_ptr += dst_pitch;
2301 75 src_ptr_0_31 += src_pitch;
2302 75 src_ptr_32_63 += src_pitch;
2303 }
2304
2305 15 current_coeff_SIMD += 16;
2306 };
2307
2308
8/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks8_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 18 → 16 taken 2 times.
✓ Branch 18 → 19 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks8_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 18 → 16 taken 2 times.
✓ Branch 18 → 19 taken 4 times.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks8_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 18 → 16 taken 2 times.
✓ Branch 18 → 19 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks8_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 18 → 16 taken 2 times.
✓ Branch 18 → 19 taken 1 time.
15 for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)
2309 {
2310 8 do_h_integer_core(std::false_type{});
2311 }
2312
2313
8/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks8_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 22 → 20 taken 1 time.
✓ Branch 22 → 23 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks8_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 22 → 20 taken 4 times.
✓ Branch 22 → 23 taken 4 times.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks8_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 22 → 20 taken 1 time.
✓ Branch 22 → 23 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_2s32_ks8_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 22 → 20 taken 1 time.
✓ Branch 22 → 23 taken 1 time.
14 for (; x < width; x += PIXELS_AT_A_TIME)
2314 {
2315 7 do_h_integer_core(std::true_type{});
2316 }
2317 }
2318 7 }
2319
2320 template<bool lessthan16bit, bool UseVNNI>
2321 4 void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks8_pretransposed_coeffs_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)
2322 {
2323 4 const uint16_t* src = (uint16_t*)src8;
2324 4 uint16_t* AVS_RESTRICT dst = (uint16_t* AVS_RESTRICT)dst8;
2325 4 dst_pitch = dst_pitch / sizeof(uint16_t);
2326 4 src_pitch = src_pitch / sizeof(uint16_t);
2327
2328 4 constexpr int PIXELS_AT_A_TIME = 64;
2329
2330
4/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks8_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks8_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks8_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks8_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
4 const int width_safe_mod = (program->safelimit_64_pixels_each32th_target.overread_possible ? program->safelimit_64_pixels_each32th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;
2331
2332 4 const int max_scanlines = program->max_scanlines;
2333
2334 4 const __m512i shifttosigned = _mm512_set1_epi16(-32768);
2335 4 const __m512i shiftfromsigned = _mm512_set1_epi32(32768 << FPScale16bits);
2336
2337 4 const int limit = (1 << bits_per_pixel) - 1;
2338 8 __m512i clamp_limit = _mm512_set1_epi16((short)limit);
2339 4 __m512i rounder = _mm512_set1_epi32(1 << (FPScale16bits - 1));
2340
2341
8/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks8_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 14 taken 1 time.
✓ Branch 24 → 25 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks8_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 14 taken 1 time.
✓ Branch 24 → 25 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks8_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 14 taken 1 time.
✓ Branch 24 → 25 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks8_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 14 taken 1 time.
✓ Branch 24 → 25 taken 1 time.
8 for (int y_from = 0; y_from < height; y_from += max_scanlines)
2342 {
2343 4 int y_to = std::min(y_from + max_scanlines, height);
2344
2345 4 const __m512i* AVS_RESTRICT current_coeff_SIMD = (__m512i*)program->pixel_coefficient_AVX512_H;
2346
2347 4 int x = 0;
2348
2349 8 auto do_h_integer_core = [&](auto partial_load) {
2350 4 __m512i one_epi16 = _mm512_set1_epi16(1);
2351
2352 4 const __m512i coef_r0r1_0_31lo = _mm512_load_si512(current_coeff_SIMD + 0);
2353 4 const __m512i coef_r0r1_0_31hi = _mm512_load_si512(current_coeff_SIMD + 1);
2354 4 const __m512i coef_r0r1_32_63lo = _mm512_load_si512(current_coeff_SIMD + 2);
2355 4 const __m512i coef_r0r1_32_63hi = _mm512_load_si512(current_coeff_SIMD + 3);
2356 4 const __m512i coef_r2r3_0_31lo = _mm512_load_si512(current_coeff_SIMD + 4);
2357 4 const __m512i coef_r2r3_0_31hi = _mm512_load_si512(current_coeff_SIMD + 5);
2358 4 const __m512i coef_r2r3_32_63lo = _mm512_load_si512(current_coeff_SIMD + 6);
2359 4 const __m512i coef_r2r3_32_63hi = _mm512_load_si512(current_coeff_SIMD + 7);
2360 4 const __m512i coef_r4r5_0_31lo = _mm512_load_si512(current_coeff_SIMD + 8);
2361 4 const __m512i coef_r4r5_0_31hi = _mm512_load_si512(current_coeff_SIMD + 9);
2362 4 const __m512i coef_r4r5_32_63lo = _mm512_load_si512(current_coeff_SIMD + 10);
2363 4 const __m512i coef_r4r5_32_63hi = _mm512_load_si512(current_coeff_SIMD + 11);
2364 4 const __m512i coef_r6r7_0_31lo = _mm512_load_si512(current_coeff_SIMD + 12);
2365 4 const __m512i coef_r6r7_0_31hi = _mm512_load_si512(current_coeff_SIMD + 13);
2366 4 const __m512i coef_r6r7_32_63lo = _mm512_load_si512(current_coeff_SIMD + 14);
2367 4 const __m512i coef_r6r7_32_63hi = _mm512_load_si512(current_coeff_SIMD + 15);
2368
2369 4 __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x]));
2370 4 __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16]));
2371 4 __m512i perm_0_32_47 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 32]));
2372 4 __m512i perm_0_48_63 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 48]));
2373
2374 4 int iStart_0_15 = program->pixel_offset[x];
2375 4 int iStart_16_31 = program->pixel_offset[x + 16];
2376 4 int iStart_32_47 = program->pixel_offset[x + 32];
2377 4 int iStart_48_63 = program->pixel_offset[x + 48];
2378
2379 8 perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, _mm512_set1_epi32(iStart_0_15));
2380 8 perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, _mm512_set1_epi32(iStart_16_31));
2381 8 perm_0_32_47 = _mm512_sub_epi32(perm_0_32_47, _mm512_set1_epi32(iStart_32_47));
2382 8 perm_0_48_63 = _mm512_sub_epi32(perm_0_48_63, _mm512_set1_epi32(iStart_48_63));
2383
2384 4 __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);
2385 4 __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);
2386 4 __m256i m256i_perm_0_32_47 = _mm512_cvtepi32_epi16(perm_0_32_47);
2387 4 __m256i m256i_perm_0_48_63 = _mm512_cvtepi32_epi16(perm_0_48_63);
2388
2389 8 __m512i perm_0_0_31 = _mm512_inserti64x4(_mm512_castsi256_si512(m256i_perm_0_0_15), m256i_perm_0_16_31, 1);
2390 8 __m512i perm_0_32_63 = _mm512_inserti64x4(_mm512_castsi256_si512(m256i_perm_0_32_47), m256i_perm_0_48_63, 1);
2391
2392 4 __m512i perm_1_0_31 = _mm512_add_epi16(perm_0_0_31, one_epi16);
2393 4 __m512i perm_1_32_63 = _mm512_add_epi16(perm_0_32_63, one_epi16);
2394
2395 4 const __m512i perm_r0r1_0_31lo = _mm512_unpacklo_epi16(perm_0_0_31, perm_1_0_31);
2396 4 const __m512i perm_r0r1_0_31hi = _mm512_unpackhi_epi16(perm_0_0_31, perm_1_0_31);
2397 4 const __m512i perm_r0r1_32_63lo = _mm512_unpacklo_epi16(perm_0_32_63, perm_1_32_63);
2398 4 const __m512i perm_r0r1_32_63hi = _mm512_unpackhi_epi16(perm_0_32_63, perm_1_32_63);
2399
2400 4 const __m512i two_epi16 = _mm512_set1_epi16(2);
2401 4 const __mmask32 k_high = 0xFFFF0000;
2402
2403 4 uint16_t* AVS_RESTRICT dst_ptr = dst + x + y_from * dst_pitch;
2404 4 const uint16_t* src_ptr_0_15 = src + iStart_0_15 + y_from * src_pitch;
2405 4 const uint16_t* src_ptr_16_31 = src + iStart_16_31 + y_from * src_pitch;
2406 4 const uint16_t* src_ptr_32_47 = src + iStart_32_47 + y_from * src_pitch;
2407 4 const uint16_t* src_ptr_48_63 = src + iStart_48_63 + y_from * src_pitch;
2408
2409 4 const int remaining_0_15 = program->source_size - iStart_0_15;
2410 4 const __mmask32 k1_0_15 = _bzhi_u32(~0UL, remaining_0_15);
2411 4 const __mmask32 k2_0_15 = _bzhi_u32(~0UL, remaining_0_15 - 32);
2412 4 const int remaining_16_31 = program->source_size - iStart_16_31;
2413 4 const __mmask32 k1_16_31 = _bzhi_u32(~0UL, remaining_16_31);
2414 4 const __mmask32 k2_16_31 = _bzhi_u32(~0UL, remaining_16_31 - 32);
2415 4 const int remaining_32_47 = program->source_size - iStart_32_47;
2416 4 const __mmask32 k1_32_47 = _bzhi_u32(~0UL, remaining_32_47);
2417 4 const __mmask32 k2_32_47 = _bzhi_u32(~0UL, remaining_32_47 - 32);
2418 4 const int remaining_48_63 = program->source_size - iStart_48_63;
2419 4 const __mmask32 k1_48_63 = _bzhi_u32(~0UL, remaining_48_63);
2420 4 const __mmask32 k2_48_63 = _bzhi_u32(~0UL, remaining_48_63 - 32);
2421
2422
8/16
✓ Branch 296 → 131 taken 5 times.
✓ Branch 296 → 297 taken 1 time.
✗ Branch 312 → 131 not taken.
✗ Branch 312 → 313 not taken.
✓ Branch 328 → 131 taken 5 times.
✓ Branch 328 → 329 taken 1 time.
✗ Branch 344 → 131 not taken.
✗ Branch 344 → 345 not taken.
✓ Branch 360 → 131 taken 5 times.
✓ Branch 360 → 361 taken 1 time.
✗ Branch 376 → 131 not taken.
✗ Branch 376 → 377 not taken.
✓ Branch 392 → 131 taken 5 times.
✓ Branch 392 → 393 taken 1 time.
✗ Branch 408 → 131 not taken.
✗ Branch 408 → 409 not taken.
24 for (int y = y_from; y < y_to; y++)
2423 {
2424 __m512i data_src_0_15, data_src2_0_15;
2425 __m512i data_src_16_31, data_src2_16_31;
2426 __m512i data_src_32_47, data_src2_32_47;
2427 __m512i data_src_48_63, data_src2_48_63;
2428
2429 20 __m512i perm_rNrNp1_0_31lo = perm_r0r1_0_31lo;
2430 20 __m512i perm_rNrNp1_0_31hi = perm_r0r1_0_31hi;
2431 20 __m512i perm_rNrNp1_32_63lo = perm_r0r1_32_63lo;
2432 20 __m512i perm_rNrNp1_32_63hi = perm_r0r1_32_63hi;
2433
2434 if constexpr (partial_load) {
2435 data_src_0_15 = _mm512_maskz_loadu_epi16(k1_0_15, src_ptr_0_15);
2436 data_src_16_31 = _mm512_maskz_loadu_epi16(k1_16_31, src_ptr_16_31);
2437 data_src_32_47 = _mm512_maskz_loadu_epi16(k1_32_47, src_ptr_32_47);
2438 data_src_48_63 = _mm512_maskz_loadu_epi16(k1_48_63, src_ptr_48_63);
2439 data_src2_0_15 = _mm512_maskz_loadu_epi16(k2_0_15, src_ptr_0_15 + 32);
2440 data_src2_16_31 = _mm512_maskz_loadu_epi16(k2_16_31, src_ptr_16_31 + 32);
2441 data_src2_32_47 = _mm512_maskz_loadu_epi16(k2_32_47, src_ptr_32_47 + 32);
2442 data_src2_48_63 = _mm512_maskz_loadu_epi16(k2_48_63, src_ptr_48_63 + 32);
2443 }
2444 else {
2445 20 data_src_0_15 = _mm512_loadu_si512(src_ptr_0_15);
2446 20 data_src_16_31 = _mm512_loadu_si512(src_ptr_16_31);
2447 20 data_src_32_47 = _mm512_loadu_si512(src_ptr_32_47);
2448 20 data_src_48_63 = _mm512_loadu_si512(src_ptr_48_63);
2449 20 data_src2_0_15 = _mm512_loadu_si512(src_ptr_0_15 + 32);
2450 20 data_src2_16_31 = _mm512_loadu_si512(src_ptr_16_31 + 32);
2451 20 data_src2_32_47 = _mm512_loadu_si512(src_ptr_32_47 + 32);
2452 40 data_src2_48_63 = _mm512_loadu_si512(src_ptr_48_63 + 32);
2453 }
2454
2455 __m512i result_0_31lo, result_0_31hi, result_32_63lo, result_32_63hi;
2456
2457 40 __m512i src_r0r1_0_31lo = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(data_src_0_15, perm_rNrNp1_0_31lo, data_src2_0_15), _mm512_permutex2var_epi16(data_src_16_31, perm_rNrNp1_0_31lo, data_src2_16_31));
2458 40 __m512i src_r0r1_0_31hi = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(data_src_0_15, perm_rNrNp1_0_31hi, data_src2_0_15), _mm512_permutex2var_epi16(data_src_16_31, perm_rNrNp1_0_31hi, data_src2_16_31));
2459 40 __m512i src_r0r1_32_63lo = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(data_src_32_47, perm_rNrNp1_32_63lo, data_src2_32_47), _mm512_permutex2var_epi16(data_src_48_63, perm_rNrNp1_32_63lo, data_src2_48_63));
2460 40 __m512i src_r0r1_32_63hi = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(data_src_32_47, perm_rNrNp1_32_63hi, data_src2_32_47), _mm512_permutex2var_epi16(data_src_48_63, perm_rNrNp1_32_63hi, data_src2_48_63));
2461
2462 20 perm_rNrNp1_0_31lo = _mm512_add_epi16(perm_rNrNp1_0_31lo, two_epi16);
2463 20 perm_rNrNp1_0_31hi = _mm512_add_epi16(perm_rNrNp1_0_31hi, two_epi16);
2464 20 perm_rNrNp1_32_63lo = _mm512_add_epi16(perm_rNrNp1_32_63lo, two_epi16);
2465 20 perm_rNrNp1_32_63hi = _mm512_add_epi16(perm_rNrNp1_32_63hi, two_epi16);
2466
2467 if constexpr (!lessthan16bit) {
2468 10 src_r0r1_0_31lo = _mm512_add_epi16(src_r0r1_0_31lo, shifttosigned);
2469 10 src_r0r1_0_31hi = _mm512_add_epi16(src_r0r1_0_31hi, shifttosigned);
2470 10 src_r0r1_32_63lo = _mm512_add_epi16(src_r0r1_32_63lo, shifttosigned);
2471 10 src_r0r1_32_63hi = _mm512_add_epi16(src_r0r1_32_63hi, shifttosigned);
2472 }
2473
2474 if constexpr (UseVNNI)
2475 {
2476 10 result_0_31lo = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31lo, coef_r0r1_0_31lo);
2477 10 result_0_31hi = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31hi, coef_r0r1_0_31hi);
2478 10 result_32_63lo = _mm512_dpwssd_epi32(rounder, src_r0r1_32_63lo, coef_r0r1_32_63lo);
2479 20 result_32_63hi = _mm512_dpwssd_epi32(rounder, src_r0r1_32_63hi, coef_r0r1_32_63hi);
2480 }
2481 else
2482 {
2483 20 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), rounder);
2484 20 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), rounder);
2485 20 result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63lo, coef_r0r1_32_63lo), rounder);
2486 30 result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63hi, coef_r0r1_32_63hi), rounder);
2487 }
2488
2489 40 __m512i src_r2r3_0_31lo = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(data_src_0_15, perm_rNrNp1_0_31lo, data_src2_0_15), _mm512_permutex2var_epi16(data_src_16_31, perm_rNrNp1_0_31lo, data_src2_16_31));
2490 40 __m512i src_r2r3_0_31hi = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(data_src_0_15, perm_rNrNp1_0_31hi, data_src2_0_15), _mm512_permutex2var_epi16(data_src_16_31, perm_rNrNp1_0_31hi, data_src2_16_31));
2491 40 __m512i src_r2r3_32_63lo = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(data_src_32_47, perm_rNrNp1_32_63lo, data_src2_32_47), _mm512_permutex2var_epi16(data_src_48_63, perm_rNrNp1_32_63lo, data_src2_48_63));
2492 40 __m512i src_r2r3_32_63hi = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(data_src_32_47, perm_rNrNp1_32_63hi, data_src2_32_47), _mm512_permutex2var_epi16(data_src_48_63, perm_rNrNp1_32_63hi, data_src2_48_63));
2493
2494 20 perm_rNrNp1_0_31lo = _mm512_add_epi16(perm_rNrNp1_0_31lo, two_epi16);
2495 20 perm_rNrNp1_0_31hi = _mm512_add_epi16(perm_rNrNp1_0_31hi, two_epi16);
2496 20 perm_rNrNp1_32_63lo = _mm512_add_epi16(perm_rNrNp1_32_63lo, two_epi16);
2497 10 perm_rNrNp1_32_63hi = _mm512_add_epi16(perm_rNrNp1_32_63hi, two_epi16);
2498
2499 if constexpr (!lessthan16bit) {
2500 10 src_r2r3_0_31lo = _mm512_add_epi16(src_r2r3_0_31lo, shifttosigned);
2501 10 src_r2r3_0_31hi = _mm512_add_epi16(src_r2r3_0_31hi, shifttosigned);
2502 10 src_r2r3_32_63lo = _mm512_add_epi16(src_r2r3_32_63lo, shifttosigned);
2503 20 src_r2r3_32_63hi = _mm512_add_epi16(src_r2r3_32_63hi, shifttosigned);
2504 }
2505
2506 if constexpr (UseVNNI)
2507 {
2508 10 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r2r3_0_31lo, coef_r2r3_0_31lo);
2509 10 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r2r3_0_31hi, coef_r2r3_0_31hi);
2510 10 result_32_63lo = _mm512_dpwssd_epi32(result_32_63lo, src_r2r3_32_63lo, coef_r2r3_32_63lo);
2511 10 result_32_63hi = _mm512_dpwssd_epi32(result_32_63hi, src_r2r3_32_63hi, coef_r2r3_32_63hi);
2512 }
2513 else
2514 {
2515 20 result_0_31lo = _mm512_add_epi32(result_0_31lo, _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo));
2516 20 result_0_31hi = _mm512_add_epi32(result_0_31hi, _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi));
2517 20 result_32_63lo = _mm512_add_epi32(result_32_63lo, _mm512_madd_epi16(src_r2r3_32_63lo, coef_r2r3_32_63lo));
2518 20 result_32_63hi = _mm512_add_epi32(result_32_63hi, _mm512_madd_epi16(src_r2r3_32_63hi, coef_r2r3_32_63hi));
2519 }
2520
2521 40 __m512i src_r4r5_0_31lo = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(data_src_0_15, perm_rNrNp1_0_31lo, data_src2_0_15), _mm512_permutex2var_epi16(data_src_16_31, perm_rNrNp1_0_31lo, data_src2_16_31));
2522 40 __m512i src_r4r5_0_31hi = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(data_src_0_15, perm_rNrNp1_0_31hi, data_src2_0_15), _mm512_permutex2var_epi16(data_src_16_31, perm_rNrNp1_0_31hi, data_src2_16_31));
2523 40 __m512i src_r4r5_32_63lo = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(data_src_32_47, perm_rNrNp1_32_63lo, data_src2_32_47), _mm512_permutex2var_epi16(data_src_48_63, perm_rNrNp1_32_63lo, data_src2_48_63));
2524 40 __m512i src_r4r5_32_63hi = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(data_src_32_47, perm_rNrNp1_32_63hi, data_src2_32_47), _mm512_permutex2var_epi16(data_src_48_63, perm_rNrNp1_32_63hi, data_src2_48_63));
2525
2526 20 perm_rNrNp1_0_31lo = _mm512_add_epi16(perm_rNrNp1_0_31lo, two_epi16);
2527 20 perm_rNrNp1_0_31hi = _mm512_add_epi16(perm_rNrNp1_0_31hi, two_epi16);
2528 20 perm_rNrNp1_32_63lo = _mm512_add_epi16(perm_rNrNp1_32_63lo, two_epi16);
2529 10 perm_rNrNp1_32_63hi = _mm512_add_epi16(perm_rNrNp1_32_63hi, two_epi16);
2530
2531 if constexpr (!lessthan16bit) {
2532 10 src_r4r5_0_31lo = _mm512_add_epi16(src_r4r5_0_31lo, shifttosigned);
2533 10 src_r4r5_0_31hi = _mm512_add_epi16(src_r4r5_0_31hi, shifttosigned);
2534 10 src_r4r5_32_63lo = _mm512_add_epi16(src_r4r5_32_63lo, shifttosigned);
2535 20 src_r4r5_32_63hi = _mm512_add_epi16(src_r4r5_32_63hi, shifttosigned);
2536 }
2537
2538 if constexpr (UseVNNI)
2539 {
2540 10 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r4r5_0_31lo, coef_r4r5_0_31lo);
2541 10 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r4r5_0_31hi, coef_r4r5_0_31hi);
2542 10 result_32_63lo = _mm512_dpwssd_epi32(result_32_63lo, src_r4r5_32_63lo, coef_r4r5_32_63lo);
2543 10 result_32_63hi = _mm512_dpwssd_epi32(result_32_63hi, src_r4r5_32_63hi, coef_r4r5_32_63hi);
2544 }
2545 else
2546 {
2547 20 result_0_31lo = _mm512_add_epi32(result_0_31lo, _mm512_madd_epi16(src_r4r5_0_31lo, coef_r4r5_0_31lo));
2548 20 result_0_31hi = _mm512_add_epi32(result_0_31hi, _mm512_madd_epi16(src_r4r5_0_31hi, coef_r4r5_0_31hi));
2549 20 result_32_63lo = _mm512_add_epi32(result_32_63lo, _mm512_madd_epi16(src_r4r5_32_63lo, coef_r4r5_32_63lo));
2550 20 result_32_63hi = _mm512_add_epi32(result_32_63hi, _mm512_madd_epi16(src_r4r5_32_63hi, coef_r4r5_32_63hi));
2551 }
2552
2553 40 __m512i src_r6r7_0_31lo = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(data_src_0_15, perm_rNrNp1_0_31lo, data_src2_0_15), _mm512_permutex2var_epi16(data_src_16_31, perm_rNrNp1_0_31lo, data_src2_16_31));
2554 40 __m512i src_r6r7_0_31hi = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(data_src_0_15, perm_rNrNp1_0_31hi, data_src2_0_15), _mm512_permutex2var_epi16(data_src_16_31, perm_rNrNp1_0_31hi, data_src2_16_31));
2555 40 __m512i src_r6r7_32_63lo = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(data_src_32_47, perm_rNrNp1_32_63lo, data_src2_32_47), _mm512_permutex2var_epi16(data_src_48_63, perm_rNrNp1_32_63lo, data_src2_48_63));
2556 30 __m512i src_r6r7_32_63hi = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(data_src_32_47, perm_rNrNp1_32_63hi, data_src2_32_47), _mm512_permutex2var_epi16(data_src_48_63, perm_rNrNp1_32_63hi, data_src2_48_63));
2557
2558 if constexpr (!lessthan16bit) {
2559 10 src_r6r7_0_31lo = _mm512_add_epi16(src_r6r7_0_31lo, shifttosigned);
2560 10 src_r6r7_0_31hi = _mm512_add_epi16(src_r6r7_0_31hi, shifttosigned);
2561 10 src_r6r7_32_63lo = _mm512_add_epi16(src_r6r7_32_63lo, shifttosigned);
2562 20 src_r6r7_32_63hi = _mm512_add_epi16(src_r6r7_32_63hi, shifttosigned);
2563 }
2564
2565 if constexpr (UseVNNI)
2566 {
2567 10 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r6r7_0_31lo, coef_r6r7_0_31lo);
2568 10 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r6r7_0_31hi, coef_r6r7_0_31hi);
2569 10 result_32_63lo = _mm512_dpwssd_epi32(result_32_63lo, src_r6r7_32_63lo, coef_r6r7_32_63lo);
2570 5 result_32_63hi = _mm512_dpwssd_epi32(result_32_63hi, src_r6r7_32_63hi, coef_r6r7_32_63hi);
2571 }
2572 else
2573 {
2574 20 result_0_31lo = _mm512_add_epi32(result_0_31lo, _mm512_madd_epi16(src_r6r7_0_31lo, coef_r6r7_0_31lo));
2575 20 result_0_31hi = _mm512_add_epi32(result_0_31hi, _mm512_madd_epi16(src_r6r7_0_31hi, coef_r6r7_0_31hi));
2576 20 result_32_63lo = _mm512_add_epi32(result_32_63lo, _mm512_madd_epi16(src_r6r7_32_63lo, coef_r6r7_32_63lo));
2577 15 result_32_63hi = _mm512_add_epi32(result_32_63hi, _mm512_madd_epi16(src_r6r7_32_63hi, coef_r6r7_32_63hi));
2578 }
2579
2580 if constexpr (!lessthan16bit) {
2581 10 result_0_31lo = _mm512_add_epi32(result_0_31lo, shiftfromsigned);
2582 10 result_0_31hi = _mm512_add_epi32(result_0_31hi, shiftfromsigned);
2583 10 result_32_63lo = _mm512_add_epi32(result_32_63lo, shiftfromsigned);
2584 20 result_32_63hi = _mm512_add_epi32(result_32_63hi, shiftfromsigned);
2585 }
2586
2587 20 result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale16bits);
2588 20 result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale16bits);
2589 20 result_32_63lo = _mm512_srai_epi32(result_32_63lo, FPScale16bits);
2590 20 result_32_63hi = _mm512_srai_epi32(result_32_63hi, FPScale16bits);
2591
2592 20 __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);
2593 10 __m512i result_32_63_int16 = _mm512_packus_epi32(result_32_63lo, result_32_63hi);
2594
2595 if constexpr (lessthan16bit) {
2596 10 result_0_31_int16 = _mm512_min_epu16(result_0_31_int16, clamp_limit);
2597 20 result_32_63_int16 = _mm512_min_epu16(result_32_63_int16, clamp_limit);
2598 }
2599
2600 _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr), result_0_31_int16);
2601
2602 20 const int w_mod32 = width / 32 * 32;
2603
4/16
✓ Branch 292 → 293 taken 5 times.
✗ Branch 292 → 295 not taken.
✗ Branch 308 → 309 not taken.
✗ Branch 308 → 311 not taken.
✓ Branch 324 → 325 taken 5 times.
✗ Branch 324 → 327 not taken.
✗ Branch 340 → 341 not taken.
✗ Branch 340 → 343 not taken.
✓ Branch 356 → 357 taken 5 times.
✗ Branch 356 → 359 not taken.
✗ Branch 372 → 373 not taken.
✗ Branch 372 → 375 not taken.
✓ Branch 388 → 389 taken 5 times.
✗ Branch 388 → 391 not taken.
✗ Branch 404 → 405 not taken.
✗ Branch 404 → 407 not taken.
20 if (x < (w_mod32 - 32))
2604 20 _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr + 32), result_32_63_int16);
2605
2606 20 dst_ptr += dst_pitch;
2607 20 src_ptr_0_15 += src_pitch;
2608 20 src_ptr_16_31 += src_pitch;
2609 20 src_ptr_32_47 += src_pitch;
2610 20 src_ptr_48_63 += src_pitch;
2611 }
2612
2613 4 current_coeff_SIMD += 16;
2614 };
2615
2616
8/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks8_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 18 → 16 taken 1 time.
✓ Branch 18 → 19 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks8_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 18 → 16 taken 1 time.
✓ Branch 18 → 19 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks8_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 18 → 16 taken 1 time.
✓ Branch 18 → 19 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks8_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 18 → 16 taken 1 time.
✓ Branch 18 → 19 taken 1 time.
8 for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)
2617 {
2618 4 do_h_integer_core(std::false_type{});
2619 }
2620
2621
4/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks8_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 22 → 20 not taken.
✓ Branch 22 → 23 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks8_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 22 → 20 not taken.
✓ Branch 22 → 23 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks8_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 22 → 20 not taken.
✓ Branch 22 → 23 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks8_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 22 → 20 not taken.
✓ Branch 22 → 23 taken 1 time.
4 for (; x < width; x += PIXELS_AT_A_TIME)
2622 {
2623 do_h_integer_core(std::true_type{});
2624 }
2625 }
2626 4 }
2627
2628 template<bool lessthan16bit, bool UseVNNI>
2629 4 void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_pretransposed_coeffs_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)
2630 {
2631 4 const uint16_t* src = (uint16_t*)src8;
2632 4 uint16_t* AVS_RESTRICT dst = (uint16_t* AVS_RESTRICT)dst8;
2633 4 dst_pitch = dst_pitch / sizeof(uint16_t);
2634 4 src_pitch = src_pitch / sizeof(uint16_t);
2635
2636 4 constexpr int PIXELS_AT_A_TIME = 32;
2637
2638
4/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 4 not taken.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 4 not taken.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 4 not taken.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 4 not taken.
4 const int width_safe_mod = (program->safelimit_64_pixels_each32th_target.overread_possible ? program->safelimit_64_pixels_each32th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;
2639
2640 4 const int max_scanlines = program->max_scanlines;
2641
2642 4 const __m512i shifttosigned = _mm512_set1_epi16(-32768);
2643 4 const __m512i shiftfromsigned = _mm512_set1_epi32(32768 << FPScale16bits);
2644
2645 4 const int limit = (1 << bits_per_pixel) - 1;
2646 8 __m512i clamp_limit = _mm512_set1_epi16((short)limit);
2647 4 __m512i rounder = _mm512_set1_epi32(1 << (FPScale16bits - 1));
2648
2649
8/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 14 taken 1 time.
✓ Branch 24 → 25 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 14 taken 1 time.
✓ Branch 24 → 25 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 14 taken 1 time.
✓ Branch 24 → 25 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 14 taken 1 time.
✓ Branch 24 → 25 taken 1 time.
8 for (int y_from = 0; y_from < height; y_from += max_scanlines)
2650 {
2651 4 int y_to = std::min(y_from + max_scanlines, height);
2652
2653 4 const __m512i* AVS_RESTRICT current_coeff_SIMD = (__m512i*)program->pixel_coefficient_AVX512_H;
2654
2655 4 int x = 0;
2656
2657 28 auto do_h_integer_core = [&](auto partial_load) {
2658 24 __m512i one_epi16 = _mm512_set1_epi16(1);
2659
2660 24 const __m512i coef_r0r1_0_31lo = _mm512_load_si512(current_coeff_SIMD + 0);
2661 24 const __m512i coef_r0r1_0_31hi = _mm512_load_si512(current_coeff_SIMD + 1);
2662 24 const __m512i coef_r2r3_0_31lo = _mm512_load_si512(current_coeff_SIMD + 2);
2663 24 const __m512i coef_r2r3_0_31hi = _mm512_load_si512(current_coeff_SIMD + 3);
2664 24 const __m512i coef_r4r5_0_31lo = _mm512_load_si512(current_coeff_SIMD + 4);
2665 24 const __m512i coef_r4r5_0_31hi = _mm512_load_si512(current_coeff_SIMD + 5);
2666 24 const __m512i coef_r6r7_0_31lo = _mm512_load_si512(current_coeff_SIMD + 6);
2667 24 const __m512i coef_r6r7_0_31hi = _mm512_load_si512(current_coeff_SIMD + 7);
2668 24 const __m512i coef_r8r9_0_31lo = _mm512_load_si512(current_coeff_SIMD + 8);
2669 24 const __m512i coef_r8r9_0_31hi = _mm512_load_si512(current_coeff_SIMD + 9);
2670 24 const __m512i coef_r10r11_0_31lo = _mm512_load_si512(current_coeff_SIMD + 10);
2671 24 const __m512i coef_r10r11_0_31hi = _mm512_load_si512(current_coeff_SIMD + 11);
2672 24 const __m512i coef_r12r13_0_31lo = _mm512_load_si512(current_coeff_SIMD + 12);
2673 24 const __m512i coef_r12r13_0_31hi = _mm512_load_si512(current_coeff_SIMD + 13);
2674 24 const __m512i coef_r14r15_0_31lo = _mm512_load_si512(current_coeff_SIMD + 14);
2675 24 const __m512i coef_r14r15_0_31hi = _mm512_load_si512(current_coeff_SIMD + 15);
2676
2677 24 __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x]));
2678 24 __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16]));
2679
2680 24 int iStart = program->pixel_offset[x];
2681 24 __m512i m512i_Start = _mm512_set1_epi32(iStart);
2682
2683 24 perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, m512i_Start);
2684 24 perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, m512i_Start);
2685
2686 24 __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);
2687 24 __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);
2688
2689 48 __m512i perm_0_0_31 = _mm512_inserti64x4(_mm512_castsi256_si512(m256i_perm_0_0_15), m256i_perm_0_16_31, 1);
2690 24 __m512i perm_1_0_31 = _mm512_add_epi16(perm_0_0_31, one_epi16);
2691
2692 24 const __m512i perm_r0r1_0_31lo = _mm512_unpacklo_epi16(perm_0_0_31, perm_1_0_31);
2693 24 const __m512i perm_r0r1_0_31hi = _mm512_unpackhi_epi16(perm_0_0_31, perm_1_0_31);
2694
2695 24 const __m512i two_epi16 = _mm512_set1_epi16(2);
2696
2697 24 uint16_t* AVS_RESTRICT dst_ptr = dst + x + y_from * dst_pitch;
2698 24 const uint16_t* src_ptr = src + iStart + y_from * src_pitch;
2699
2700 24 const int remaining = program->source_size - iStart;
2701 24 const __mmask32 k1 = _bzhi_u32(~0UL, remaining);
2702 24 const __mmask32 k2 = _bzhi_u32(~0UL, remaining - 32);
2703
2704
16/16
✓ Branch 188 → 78 taken 20 times.
✓ Branch 188 → 189 taken 4 times.
✓ Branch 192 → 78 taken 10 times.
✓ Branch 192 → 193 taken 2 times.
✓ Branch 220 → 78 taken 20 times.
✓ Branch 220 → 221 taken 4 times.
✓ Branch 224 → 78 taken 10 times.
✓ Branch 224 → 225 taken 2 times.
✓ Branch 252 → 78 taken 20 times.
✓ Branch 252 → 253 taken 4 times.
✓ Branch 256 → 78 taken 10 times.
✓ Branch 256 → 257 taken 2 times.
✓ Branch 284 → 78 taken 20 times.
✓ Branch 284 → 285 taken 4 times.
✓ Branch 288 → 78 taken 10 times.
✓ Branch 288 → 289 taken 2 times.
144 for (int y = y_from; y < y_to; y++)
2705 {
2706 __m512i data_src, data_src2;
2707
2708 120 __m512i perm_rNrNp1_0_31lo_w = perm_r0r1_0_31lo;
2709 120 __m512i perm_rNrNp1_0_31hi_w = perm_r0r1_0_31hi;
2710
2711 if constexpr (partial_load) {
2712 40 data_src = _mm512_maskz_loadu_epi16(k1, src_ptr);
2713 80 data_src2 = _mm512_maskz_loadu_epi16(k2, src_ptr + 32);
2714 }
2715 else {
2716 80 data_src = _mm512_loadu_si512(src_ptr);
2717 160 data_src2 = _mm512_loadu_si512(src_ptr + 32);
2718 }
2719
2720 120 __m512i src_r0r1_0_31lo = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31lo_w, data_src2);
2721 120 __m512i src_r0r1_0_31hi = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31hi_w, data_src2);
2722
2723 120 perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);
2724 120 perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);
2725
2726 120 __m512i src_r2r3_0_31lo = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31lo_w, data_src2);
2727 120 __m512i src_r2r3_0_31hi = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31hi_w, data_src2);
2728
2729 120 perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);
2730 90 perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);
2731
2732 __m512i result_0_31lo, result_0_31hi;
2733
2734 if constexpr (!lessthan16bit) {
2735 60 src_r0r1_0_31lo = _mm512_add_epi16(src_r0r1_0_31lo, shifttosigned);
2736 60 src_r0r1_0_31hi = _mm512_add_epi16(src_r0r1_0_31hi, shifttosigned);
2737 60 src_r2r3_0_31lo = _mm512_add_epi16(src_r2r3_0_31lo, shifttosigned);
2738 90 src_r2r3_0_31hi = _mm512_add_epi16(src_r2r3_0_31hi, shifttosigned);
2739 }
2740
2741 if constexpr (UseVNNI)
2742 {
2743 120 result_0_31lo = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31lo, coef_r0r1_0_31lo);
2744 60 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r2r3_0_31lo, coef_r2r3_0_31lo);
2745 120 result_0_31hi = _mm512_dpwssd_epi32(rounder, src_r0r1_0_31hi, coef_r0r1_0_31hi);
2746 60 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r2r3_0_31hi, coef_r2r3_0_31hi);
2747 }
2748 else
2749 {
2750 180 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, coef_r0r1_0_31lo), _mm512_madd_epi16(src_r2r3_0_31lo, coef_r2r3_0_31lo));
2751 180 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, coef_r0r1_0_31hi), _mm512_madd_epi16(src_r2r3_0_31hi, coef_r2r3_0_31hi));
2752 }
2753
2754 120 __m512i src_r4r5_0_31lo = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31lo_w, data_src2);
2755 120 __m512i src_r4r5_0_31hi = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31hi_w, data_src2);
2756
2757 120 perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);
2758 120 perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);
2759
2760 120 __m512i src_r6r7_0_31lo = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31lo_w, data_src2);
2761 120 __m512i src_r6r7_0_31hi = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31hi_w, data_src2);
2762
2763 120 perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);
2764 60 perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);
2765
2766 if constexpr (!lessthan16bit) {
2767 60 src_r4r5_0_31lo = _mm512_add_epi16(src_r4r5_0_31lo, shifttosigned);
2768 60 src_r4r5_0_31hi = _mm512_add_epi16(src_r4r5_0_31hi, shifttosigned);
2769 60 src_r6r7_0_31lo = _mm512_add_epi16(src_r6r7_0_31lo, shifttosigned);
2770 120 src_r6r7_0_31hi = _mm512_add_epi16(src_r6r7_0_31hi, shifttosigned);
2771 }
2772
2773 if constexpr (UseVNNI)
2774 {
2775 60 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r4r5_0_31lo, coef_r4r5_0_31lo);
2776 60 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r6r7_0_31lo, coef_r6r7_0_31lo);
2777 60 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r4r5_0_31hi, coef_r4r5_0_31hi);
2778 60 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r6r7_0_31hi, coef_r6r7_0_31hi);
2779 }
2780 else
2781 {
2782 120 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31lo, coef_r4r5_0_31lo), result_0_31lo);
2783 120 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r4r5_0_31hi, coef_r4r5_0_31hi), result_0_31hi);
2784 120 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31lo, coef_r6r7_0_31lo), result_0_31lo);
2785 120 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r6r7_0_31hi, coef_r6r7_0_31hi), result_0_31hi);
2786 }
2787
2788 120 __m512i src_r8r9_0_31lo = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31lo_w, data_src2);
2789 120 __m512i src_r8r9_0_31hi = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31hi_w, data_src2);
2790
2791 120 perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);
2792 120 perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);
2793
2794 120 __m512i src_r10r11_0_31lo = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31lo_w, data_src2);
2795 120 __m512i src_r10r11_0_31hi = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31hi_w, data_src2);
2796
2797 120 perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);
2798 60 perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);
2799
2800 if constexpr (!lessthan16bit) {
2801 60 src_r8r9_0_31lo = _mm512_add_epi16(src_r8r9_0_31lo, shifttosigned);
2802 60 src_r8r9_0_31hi = _mm512_add_epi16(src_r8r9_0_31hi, shifttosigned);
2803 60 src_r10r11_0_31lo = _mm512_add_epi16(src_r10r11_0_31lo, shifttosigned);
2804 120 src_r10r11_0_31hi = _mm512_add_epi16(src_r10r11_0_31hi, shifttosigned);
2805 }
2806
2807 if constexpr (UseVNNI)
2808 {
2809 60 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r8r9_0_31lo, coef_r8r9_0_31lo);
2810 60 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r10r11_0_31lo, coef_r10r11_0_31lo);
2811 60 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r8r9_0_31hi, coef_r8r9_0_31hi);
2812 60 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r10r11_0_31hi, coef_r10r11_0_31hi);
2813 }
2814 else
2815 {
2816 120 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r8r9_0_31lo, coef_r8r9_0_31lo), result_0_31lo);
2817 120 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r8r9_0_31hi, coef_r8r9_0_31hi), result_0_31hi);
2818 120 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r10r11_0_31lo, coef_r10r11_0_31lo), result_0_31lo);
2819 120 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r10r11_0_31hi, coef_r10r11_0_31hi), result_0_31hi);
2820 }
2821
2822 120 __m512i src_r12r13_0_31lo = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31lo_w, data_src2);
2823 120 __m512i src_r12r13_0_31hi = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31hi_w, data_src2);
2824
2825 120 perm_rNrNp1_0_31lo_w = _mm512_add_epi16(perm_rNrNp1_0_31lo_w, two_epi16);
2826 120 perm_rNrNp1_0_31hi_w = _mm512_add_epi16(perm_rNrNp1_0_31hi_w, two_epi16);
2827
2828 120 __m512i src_r14r15_0_31lo = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31lo_w, data_src2);
2829 60 __m512i src_r14r15_0_31hi = _mm512_permutex2var_epi16(data_src, perm_rNrNp1_0_31hi_w, data_src2);
2830
2831 if constexpr (!lessthan16bit) {
2832 60 src_r12r13_0_31lo = _mm512_add_epi16(src_r12r13_0_31lo, shifttosigned);
2833 60 src_r12r13_0_31hi = _mm512_add_epi16(src_r12r13_0_31hi, shifttosigned);
2834 60 src_r14r15_0_31lo = _mm512_add_epi16(src_r14r15_0_31lo, shifttosigned);
2835 120 src_r14r15_0_31hi = _mm512_add_epi16(src_r14r15_0_31hi, shifttosigned);
2836 }
2837
2838 if constexpr (UseVNNI)
2839 {
2840 60 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r12r13_0_31lo, coef_r12r13_0_31lo);
2841 60 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r14r15_0_31lo, coef_r14r15_0_31lo);
2842 60 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r12r13_0_31hi, coef_r12r13_0_31hi);
2843 30 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r14r15_0_31hi, coef_r14r15_0_31hi);
2844 }
2845 else
2846 {
2847 120 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r12r13_0_31lo, coef_r12r13_0_31lo), result_0_31lo);
2848 120 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r12r13_0_31hi, coef_r12r13_0_31hi), result_0_31hi);
2849 120 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r14r15_0_31lo, coef_r14r15_0_31lo), result_0_31lo);
2850 60 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r14r15_0_31hi, coef_r14r15_0_31hi), result_0_31hi);
2851
2852 60 result_0_31lo = _mm512_add_epi32(result_0_31lo, rounder);
2853 90 result_0_31hi = _mm512_add_epi32(result_0_31hi, rounder);
2854 }
2855
2856 if constexpr (!lessthan16bit) {
2857 60 result_0_31lo = _mm512_add_epi32(result_0_31lo, shiftfromsigned);
2858 120 result_0_31hi = _mm512_add_epi32(result_0_31hi, shiftfromsigned);
2859 }
2860
2861 120 result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale16bits);
2862 120 result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale16bits);
2863
2864 60 __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);
2865
2866 if constexpr (lessthan16bit) {
2867 120 result_0_31_int16 = _mm512_min_epu16(result_0_31_int16, clamp_limit);
2868 }
2869
2870 _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr), result_0_31_int16);
2871
2872 120 dst_ptr += dst_pitch;
2873 120 src_ptr += src_pitch;
2874 }
2875
2876 24 current_coeff_SIMD += 16;
2877 };
2878
2879
8/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 18 → 16 taken 4 times.
✓ Branch 18 → 19 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 18 → 16 taken 4 times.
✓ Branch 18 → 19 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 18 → 16 taken 4 times.
✓ Branch 18 → 19 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 18 → 16 taken 4 times.
✓ Branch 18 → 19 taken 1 time.
20 for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)
2880 {
2881 16 do_h_integer_core(std::false_type{});
2882 }
2883
2884
8/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 22 → 20 taken 2 times.
✓ Branch 22 → 23 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 22 → 20 taken 2 times.
✓ Branch 22 → 23 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 22 → 20 taken 2 times.
✓ Branch 22 → 23 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_ks16_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 22 → 20 taken 2 times.
✓ Branch 22 → 23 taken 1 time.
12 for (; x < width; x += PIXELS_AT_A_TIME)
2885 {
2886 8 do_h_integer_core(std::true_type{});
2887 }
2888 }
2889 4 }
2890
2891 template<bool lessthan16bit, bool UseVNNI>
2892 4 void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal(BYTE* dst8, const BYTE* src8, int dst_pitch, int src_pitch, ResamplingProgram* program, int width, int height, int bits_per_pixel)
2893 {
2894 4 int filter_size_real = program->filter_size_real;
2895
4/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 1 time.
4 if ((filter_size_real / 2 * 2) != filter_size_real) filter_size_real++;
2896
2897 4 const uint16_t* src = (uint16_t*)src8;
2898 4 uint16_t* AVS_RESTRICT dst = (uint16_t* AVS_RESTRICT)dst8;
2899 4 dst_pitch = dst_pitch / sizeof(uint16_t);
2900 4 src_pitch = src_pitch / sizeof(uint16_t);
2901
2902 4 constexpr int PIXELS_AT_A_TIME = 64;
2903
2904
4/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 6 not taken.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 6 not taken.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 6 not taken.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 6 not taken.
4 const int width_safe_mod = (program->safelimit_64_pixels_each32th_target.overread_possible ? program->safelimit_64_pixels_each32th_target.source_overread_beyond_targetx : width) / PIXELS_AT_A_TIME * PIXELS_AT_A_TIME;
2905
2906 4 const int max_scanlines = program->max_scanlines;
2907
2908 4 const __m512i shifttosigned = _mm512_set1_epi16(-32768);
2909 4 const __m512i shiftfromsigned = _mm512_set1_epi32(32768 << FPScale16bits);
2910
2911 4 const int limit = (1 << bits_per_pixel) - 1;
2912 8 __m512i clamp_limit = _mm512_set1_epi16((short)limit);
2913 4 __m512i rounder = _mm512_set1_epi32(1 << (FPScale16bits - 1));
2914
2915
8/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 26 → 16 taken 1 time.
✓ Branch 26 → 27 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 26 → 16 taken 1 time.
✓ Branch 26 → 27 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 26 → 16 taken 1 time.
✓ Branch 26 → 27 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 26 → 16 taken 1 time.
✓ Branch 26 → 27 taken 1 time.
8 for (int y_from = 0; y_from < height; y_from += max_scanlines)
2916 {
2917 4 int y_to = std::min(y_from + max_scanlines, height);
2918
2919 4 const __m512i* AVS_RESTRICT current_coeff_SIMD = (__m512i*)program->pixel_coefficient_AVX512_H;
2920
2921 4 int x = 0;
2922
2923 16 auto do_h_integer_core = [&](auto partial_load) {
2924 12 __m512i one_epi16 = _mm512_set1_epi16(1);
2925
2926 12 __m512i perm_0_0_15 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x]));
2927 12 __m512i perm_0_16_31 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 16]));
2928 12 __m512i perm_0_32_47 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 32]));
2929 12 __m512i perm_0_48_63 = _mm512_loadu_si512((__m512i*)(&program->pixel_offset[x + 48]));
2930
2931 12 int iStart_0_15 = program->pixel_offset[x];
2932 12 int iStart_16_31 = program->pixel_offset[x + 16];
2933 12 int iStart_32_47 = program->pixel_offset[x + 32];
2934 12 int iStart_48_63 = program->pixel_offset[x + 48];
2935
2936 24 perm_0_0_15 = _mm512_sub_epi32(perm_0_0_15, _mm512_set1_epi32(iStart_0_15));
2937 24 perm_0_16_31 = _mm512_sub_epi32(perm_0_16_31, _mm512_set1_epi32(iStart_16_31));
2938 24 perm_0_32_47 = _mm512_sub_epi32(perm_0_32_47, _mm512_set1_epi32(iStart_32_47));
2939 24 perm_0_48_63 = _mm512_sub_epi32(perm_0_48_63, _mm512_set1_epi32(iStart_48_63));
2940
2941 12 __m256i m256i_perm_0_0_15 = _mm512_cvtepi32_epi16(perm_0_0_15);
2942 12 __m256i m256i_perm_0_16_31 = _mm512_cvtepi32_epi16(perm_0_16_31);
2943 12 __m256i m256i_perm_0_32_47 = _mm512_cvtepi32_epi16(perm_0_32_47);
2944 12 __m256i m256i_perm_0_48_63 = _mm512_cvtepi32_epi16(perm_0_48_63);
2945
2946 24 __m512i perm_0_0_31 = _mm512_inserti64x4(_mm512_castsi256_si512(m256i_perm_0_0_15), m256i_perm_0_16_31, 1);
2947 24 __m512i perm_0_32_63 = _mm512_inserti64x4(_mm512_castsi256_si512(m256i_perm_0_32_47), m256i_perm_0_48_63, 1);
2948
2949 12 __m512i perm_1_0_31 = _mm512_add_epi16(perm_0_0_31, one_epi16);
2950 12 __m512i perm_1_32_63 = _mm512_add_epi16(perm_0_32_63, one_epi16);
2951
2952 12 const __m512i perm_r0r1_0_31lo = _mm512_unpacklo_epi16(perm_0_0_31, perm_1_0_31);
2953 12 const __m512i perm_r0r1_0_31hi = _mm512_unpackhi_epi16(perm_0_0_31, perm_1_0_31);
2954 12 const __m512i perm_r0r1_32_63lo = _mm512_unpacklo_epi16(perm_0_32_63, perm_1_32_63);
2955 12 const __m512i perm_r0r1_32_63hi = _mm512_unpackhi_epi16(perm_0_32_63, perm_1_32_63);
2956
2957 12 const __m512i two_epi16 = _mm512_set1_epi16(2);
2958 12 const __mmask32 k_high = 0xFFFF0000;
2959
2960 12 uint16_t* AVS_RESTRICT dst_ptr = dst + x + y_from * dst_pitch;
2961 12 const uint16_t* src_ptr_0_15 = src + iStart_0_15 + y_from * src_pitch;
2962 12 const uint16_t* src_ptr_16_31 = src + iStart_16_31 + y_from * src_pitch;
2963 12 const uint16_t* src_ptr_32_47 = src + iStart_32_47 + y_from * src_pitch;
2964 12 const uint16_t* src_ptr_48_63 = src + iStart_48_63 + y_from * src_pitch;
2965
2966 12 const int remaining_0_15 = program->source_size - iStart_0_15;
2967 12 const __mmask32 k1_0_15 = _bzhi_u32(~0UL, remaining_0_15);
2968 12 const __mmask32 k2_0_15 = _bzhi_u32(~0UL, remaining_0_15 - 32);
2969 12 const int remaining_16_31 = program->source_size - iStart_16_31;
2970 12 const __mmask32 k1_16_31 = _bzhi_u32(~0UL, remaining_16_31);
2971 12 const __mmask32 k2_16_31 = _bzhi_u32(~0UL, remaining_16_31 - 32);
2972 12 const int remaining_32_47 = program->source_size - iStart_32_47;
2973 12 const __mmask32 k1_32_47 = _bzhi_u32(~0UL, remaining_32_47);
2974 12 const __mmask32 k2_32_47 = _bzhi_u32(~0UL, remaining_32_47 - 32);
2975 12 const int remaining_48_63 = program->source_size - iStart_48_63;
2976 12 const __mmask32 k1_48_63 = _bzhi_u32(~0UL, remaining_48_63);
2977 12 const __mmask32 k2_48_63 = _bzhi_u32(~0UL, remaining_48_63 - 32);
2978
2979
12/12
✓ Branch 187 → 99 taken 10 times.
✓ Branch 187 → 188 taken 2 times.
✓ Branch 195 → 99 taken 10 times.
✓ Branch 195 → 196 taken 2 times.
✓ Branch 203 → 99 taken 15 times.
✓ Branch 203 → 204 taken 3 times.
✓ Branch 211 → 99 taken 15 times.
✓ Branch 211 → 212 taken 3 times.
✓ Branch 219 → 99 taken 5 times.
✓ Branch 219 → 220 taken 1 time.
✓ Branch 227 → 99 taken 5 times.
✓ Branch 227 → 228 taken 1 time.
72 for (int y = y_from; y < y_to; y++)
2980 {
2981 __m512i data_src_0_15, data_src2_0_15;
2982 __m512i data_src_16_31, data_src2_16_31;
2983 __m512i data_src_32_47, data_src2_32_47;
2984 __m512i data_src_48_63, data_src2_48_63;
2985
2986 60 __m512i perm_rNrNp1_0_31lo = perm_r0r1_0_31lo;
2987 60 __m512i perm_rNrNp1_0_31hi = perm_r0r1_0_31hi;
2988 60 __m512i perm_rNrNp1_32_63lo = perm_r0r1_32_63lo;
2989 60 __m512i perm_rNrNp1_32_63hi = perm_r0r1_32_63hi;
2990
2991 if constexpr (partial_load) {
2992 20 data_src_0_15 = _mm512_maskz_loadu_epi16(k1_0_15, src_ptr_0_15);
2993 20 data_src_16_31 = _mm512_maskz_loadu_epi16(k1_16_31, src_ptr_16_31);
2994 20 data_src_32_47 = _mm512_maskz_loadu_epi16(k1_32_47, src_ptr_32_47);
2995 20 data_src_48_63 = _mm512_maskz_loadu_epi16(k1_48_63, src_ptr_48_63);
2996 20 data_src2_0_15 = _mm512_maskz_loadu_epi16(k2_0_15, src_ptr_0_15 + 32);
2997 20 data_src2_16_31 = _mm512_maskz_loadu_epi16(k2_16_31, src_ptr_16_31 + 32);
2998 20 data_src2_32_47 = _mm512_maskz_loadu_epi16(k2_32_47, src_ptr_32_47 + 32);
2999 20 data_src2_48_63 = _mm512_maskz_loadu_epi16(k2_48_63, src_ptr_48_63 + 32);
3000 }
3001 else {
3002 40 data_src_0_15 = _mm512_loadu_si512(src_ptr_0_15);
3003 40 data_src_16_31 = _mm512_loadu_si512(src_ptr_16_31);
3004 40 data_src_32_47 = _mm512_loadu_si512(src_ptr_32_47);
3005 40 data_src_48_63 = _mm512_loadu_si512(src_ptr_48_63);
3006 40 data_src2_0_15 = _mm512_loadu_si512(src_ptr_0_15 + 32);
3007 40 data_src2_16_31 = _mm512_loadu_si512(src_ptr_16_31 + 32);
3008 40 data_src2_32_47 = _mm512_loadu_si512(src_ptr_32_47 + 32);
3009 40 data_src2_48_63 = _mm512_loadu_si512(src_ptr_48_63 + 32);
3010 }
3011
3012 60 __m512i result_0_31lo = rounder;
3013 60 __m512i result_0_31hi = rounder;
3014 60 __m512i result_32_63lo = rounder;
3015 60 __m512i result_32_63hi = rounder;
3016
3017 60 const __m512i* current_coeff_SIMDw = current_coeff_SIMD;
3018
3019
14/14
✓ Branch 157 → 116 taken 100 times.
✓ Branch 157 → 158 taken 10 times.
✓ Branch 165 → 116 taken 100 times.
✓ Branch 165 → 166 taken 10 times.
✓ Branch 173 → 116 taken 100 times.
✓ Branch 173 → 132 taken 50 times.
✓ Branch 173 → 174 taken 15 times.
✓ Branch 181 → 116 taken 100 times.
✓ Branch 181 → 132 taken 50 times.
✓ Branch 181 → 182 taken 15 times.
✓ Branch 189 → 132 taken 50 times.
✓ Branch 189 → 190 taken 5 times.
✓ Branch 197 → 132 taken 50 times.
✓ Branch 197 → 198 taken 5 times.
660 for (int kr = 0; kr < filter_size_real; kr += 2)
3020 {
3021 1200 __m512i src_r0r1_0_31lo = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(data_src_0_15, perm_rNrNp1_0_31lo, data_src2_0_15), _mm512_permutex2var_epi16(data_src_16_31, perm_rNrNp1_0_31lo, data_src2_16_31));
3022 1200 __m512i src_r0r1_0_31hi = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(data_src_0_15, perm_rNrNp1_0_31hi, data_src2_0_15), _mm512_permutex2var_epi16(data_src_16_31, perm_rNrNp1_0_31hi, data_src2_16_31));
3023 1200 __m512i src_r0r1_32_63lo = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(data_src_32_47, perm_rNrNp1_32_63lo, data_src2_32_47), _mm512_permutex2var_epi16(data_src_48_63, perm_rNrNp1_32_63lo, data_src2_48_63));
3024 1200 __m512i src_r0r1_32_63hi = _mm512_mask_blend_epi16(k_high, _mm512_permutex2var_epi16(data_src_32_47, perm_rNrNp1_32_63hi, data_src2_32_47), _mm512_permutex2var_epi16(data_src_48_63, perm_rNrNp1_32_63hi, data_src2_48_63));
3025
3026 600 perm_rNrNp1_0_31lo = _mm512_add_epi16(perm_rNrNp1_0_31lo, two_epi16);
3027 600 perm_rNrNp1_0_31hi = _mm512_add_epi16(perm_rNrNp1_0_31hi, two_epi16);
3028 600 perm_rNrNp1_32_63lo = _mm512_add_epi16(perm_rNrNp1_32_63lo, two_epi16);
3029 300 perm_rNrNp1_32_63hi = _mm512_add_epi16(perm_rNrNp1_32_63hi, two_epi16);
3030
3031 if constexpr (!lessthan16bit) {
3032 300 src_r0r1_0_31lo = _mm512_add_epi16(src_r0r1_0_31lo, shifttosigned);
3033 300 src_r0r1_0_31hi = _mm512_add_epi16(src_r0r1_0_31hi, shifttosigned);
3034 300 src_r0r1_32_63lo = _mm512_add_epi16(src_r0r1_32_63lo, shifttosigned);
3035 600 src_r0r1_32_63hi = _mm512_add_epi16(src_r0r1_32_63hi, shifttosigned);
3036 }
3037
3038 if constexpr (UseVNNI)
3039 {
3040 300 result_0_31lo = _mm512_dpwssd_epi32(result_0_31lo, src_r0r1_0_31lo, _mm512_load_si512(current_coeff_SIMDw + 0));
3041 600 result_0_31hi = _mm512_dpwssd_epi32(result_0_31hi, src_r0r1_0_31hi, _mm512_load_si512(current_coeff_SIMDw + 1));
3042 600 result_32_63lo = _mm512_dpwssd_epi32(result_32_63lo, src_r0r1_32_63lo, _mm512_load_si512(current_coeff_SIMDw + 2));
3043 600 result_32_63hi = _mm512_dpwssd_epi32(result_32_63hi, src_r0r1_32_63hi, _mm512_load_si512(current_coeff_SIMDw + 3));
3044 }
3045 else
3046 {
3047 600 result_0_31lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31lo, _mm512_load_si512(current_coeff_SIMDw + 0)), result_0_31lo);
3048 900 result_0_31hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_0_31hi, _mm512_load_si512(current_coeff_SIMDw + 1)), result_0_31hi);
3049 900 result_32_63lo = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63lo, _mm512_load_si512(current_coeff_SIMDw + 2)), result_32_63lo);
3050 900 result_32_63hi = _mm512_add_epi32(_mm512_madd_epi16(src_r0r1_32_63hi, _mm512_load_si512(current_coeff_SIMDw + 3)), result_32_63hi);
3051 }
3052
3053 600 current_coeff_SIMDw += 4;
3054 }
3055
3056 if constexpr (!lessthan16bit) {
3057 30 result_0_31lo = _mm512_add_epi32(result_0_31lo, shiftfromsigned);
3058 30 result_0_31hi = _mm512_add_epi32(result_0_31hi, shiftfromsigned);
3059 30 result_32_63lo = _mm512_add_epi32(result_32_63lo, shiftfromsigned);
3060 60 result_32_63hi = _mm512_add_epi32(result_32_63hi, shiftfromsigned);
3061 }
3062
3063 60 result_0_31lo = _mm512_srai_epi32(result_0_31lo, FPScale16bits);
3064 60 result_0_31hi = _mm512_srai_epi32(result_0_31hi, FPScale16bits);
3065 60 result_32_63lo = _mm512_srai_epi32(result_32_63lo, FPScale16bits);
3066 60 result_32_63hi = _mm512_srai_epi32(result_32_63hi, FPScale16bits);
3067
3068 60 __m512i result_0_31_int16 = _mm512_packus_epi32(result_0_31lo, result_0_31hi);
3069 30 __m512i result_32_63_int16 = _mm512_packus_epi32(result_32_63lo, result_32_63hi);
3070
3071 if constexpr (lessthan16bit) {
3072 30 result_0_31_int16 = _mm512_min_epu16(result_0_31_int16, clamp_limit);
3073 60 result_32_63_int16 = _mm512_min_epu16(result_32_63_int16, clamp_limit);
3074 }
3075
3076 _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr), result_0_31_int16);
3077
3078 60 const int w_mod32 = width / 32 * 32;
3079
6/12
✓ Branch 183 → 184 taken 10 times.
✗ Branch 183 → 186 not taken.
✓ Branch 191 → 192 taken 10 times.
✗ Branch 191 → 194 not taken.
✓ Branch 199 → 200 taken 15 times.
✗ Branch 199 → 202 not taken.
✓ Branch 207 → 208 taken 15 times.
✗ Branch 207 → 210 not taken.
✓ Branch 215 → 216 taken 5 times.
✗ Branch 215 → 218 not taken.
✓ Branch 223 → 224 taken 5 times.
✗ Branch 223 → 226 not taken.
60 if (x < (w_mod32 - 32))
3080 60 _mm512_stream_si512(reinterpret_cast<__m512i*>(dst_ptr + 32), result_32_63_int16);
3081
3082 60 dst_ptr += dst_pitch;
3083 60 src_ptr_0_15 += src_pitch;
3084 60 src_ptr_16_31 += src_pitch;
3085 60 src_ptr_32_47 += src_pitch;
3086 60 src_ptr_48_63 += src_pitch;
3087 }
3088
3089 12 current_coeff_SIMD += filter_size_real * 2;
3090 };
3091
3092
8/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 20 → 18 taken 2 times.
✓ Branch 20 → 21 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 20 → 18 taken 2 times.
✓ Branch 20 → 21 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 20 → 18 taken 2 times.
✓ Branch 20 → 21 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 20 → 18 taken 2 times.
✓ Branch 20 → 21 taken 1 time.
12 for (; x < width_safe_mod; x += PIXELS_AT_A_TIME)
3093 {
3094 8 do_h_integer_core(std::false_type{});
3095 }
3096
3097
8/8
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal<false, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 22 taken 1 time.
✓ Branch 24 → 25 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal<false, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 22 taken 1 time.
✓ Branch 24 → 25 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal<true, false>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 22 taken 1 time.
✓ Branch 24 → 25 taken 1 time.
void resize_h_planar_uint16_avx512_permutex_vstripe_mp_4s16_ks48_pretransposed_coeffs_internal<true, true>(unsigned char*, unsigned char const*, int, int, ResamplingProgram*, int, int, int):
✓ Branch 24 → 22 taken 1 time.
✓ Branch 24 → 25 taken 1 time.
8 for (; x < width; x += PIXELS_AT_A_TIME)
3098 {
3099 4 do_h_integer_core(std::true_type{});
3100 }
3101 }
3102 4 }
3103