diff --git a/src/builtins/scan.c b/src/builtins/scan.c index 5de4cf58..471bd98d 100644 --- a/src/builtins/scan.c +++ b/src/builtins/scan.c @@ -280,6 +280,23 @@ B scan_c1(Md1D* d, B x) { B f = d->f; si_scan_stride_minmax[4*(rtid==n_ceil) + xe-el_i8](xp, rp, ia, csz); decG(x); return r; } + if (rtid==n_add) { + if (xe==el_bit) { x = toI8Any(x); xe=el_i8; } + restart: + B r; void* rp = m_tyarrc(&r, elWidth(xe), x, el2t(xe)); + void* xp = tyany_ptr(x); + bool done = si_scan_stride_add[xe-el_i8](xp, rp, ia, csz); + if (!done) { + decG(r); + switch (++xe) { + case el_i16: x = toI16Any(x); break; + case el_i32: x = toI32Any(x); break; + case el_f64: x = toF64Any(x); break; + } + goto restart; + } + decG(x); return r; + } #endif goto base; }} diff --git a/src/singeli/src/scan.singeli b/src/singeli/src/scan.singeli index 1d98c5bf..10c93e35 100644 --- a/src/singeli/src/scan.singeli +++ b/src/singeli/src/scan.singeli @@ -100,8 +100,11 @@ def shift_first{c:V=[l]_, p:V} = { # Strided scans -fn scan_stride_assoc{op, T}(xv:*void, rv:*void, ia:usz, l:usz) : void = { - def id = match (op) { {(min)} => maxvalue; {(max)} => minvalue } +fn scan_stride_assoc{op, T, Ret, check_over}(xv:*void, rv:*void, ia:usz, l:usz) : Ret = { + def id = match (op) { + {(min)} => maxvalue; {(max)} => minvalue + {(+)} => ({_}=>0) + } def f = width{T}/8; def vl = 16/f x:= *T~~xv; r:= *T~~rv def has_shuf = hasarch{'SSSE3'} or hasarch{'AARCH64'} @@ -112,8 +115,9 @@ fn scan_stride_assoc{op, T}(xv:*void, rv:*void, ia:usz, l:usz) : void = { spr:= I**16 - j + iv inds:= @collect (k) { v:= iv - (j &~ I~~(iv{}} +def check_add_over{w:V=[_]E, x:V, r:V} = { + o:= (if (not hasarch{'X86_64'} or width{E}<=16) any_hom{subs{r,w} != x} + else any_top{(w^r) & (x^r)}) + if (o) return{0} +} +def check_add_over{x, r} = check_add_over{r-x, x, r} export_tab{'si_scan_stride_minmax', flat_table{scan_stride_assoc, tup{min,max}, tup{i8,i16,i32,f64}} } +export_tab{'si_scan_stride_add', tup{ + ...each{scan_stride_assoc{+, ., u1, check_add_over}, tup{i8,i16,i32}}, + scan_stride_assoc{+, f64, u1, {..._}=>{}} +}} # xor scan