diff --git a/src/builtins/select.c b/src/builtins/select.c index f3ea8b1e..41daf25f 100644 --- a/src/builtins/select.c +++ b/src/builtins/select.c @@ -639,7 +639,9 @@ B select_rows_typed(B x, ux csz, ux cam, void* inds, ux indn, u8 ie, bool should if (bounds[0] < -(i64)csz) goto generic; if (csz < 128 && indn < INDS_BUF_MAX) { assert(ie == el_i8); - si_wrap_inds[ie-el_i8](inds, inds_buf, indn, csz); + si_wrap_inds[0](inds, inds_buf, indn, csz); + bounds[0] = 0; + bounds[1] = csz-1; inds = inds_buf; } else { fast = false; @@ -650,7 +652,7 @@ B select_rows_typed(B x, ux csz, ux cam, void* inds, ux indn, u8 ie, bool should #if SINGELI_AVX2 || SINGELI_NEON if (fast) { generic_allowed = false; - ux sh = select_rows_widen[lb](inds, inds_buf, indn); // TODO null element in table for guaranteed-zero + ux sh = select_rows_widen[lb](inds, inds_buf, bounds[1], indn); // TODO null element in table for guaranteed-zero if (sh!=0) { SELECT_ROWS_PRINTF("widening indices by factor of %d:\n", 1<=k} = { # : [k*sc]S def RV = [k*sc]S def add = make{RV, range{k*sc} % sc} if (hasarch{'AARCH64'} and [k]D == [2]u64 and S==u8) { - (RV~~sel{[16]u8, x, make{[16]u8, range{16}>>3}}<<3) + add + def x16 = undefPromote{[16]u8, x} + (RV~~sel{[16]u8, x16, make{[16]u8, range{16}>>3}}<<3) + add } else if (hasarch{'AVX2'} and [k]D == [4]u64 and S==u32) { (sel{[8]u32, undefPromote{[8]u32, x}, make{[8]u32, range{8}>>1}}<=arch_minvw} = T @@ -162,13 +162,15 @@ export{'INDS_BUF_MAX_COPY', ux~~inds_buf_max} def select_rows_better = scan{{p,{v,i}} => if (length{v}==0) p else i, 0, each{tup, select_rows_parts, range{4}}} exportP{u8, 'select_rows_better', select_rows_better+1} - fn select_rows_widen{sh}(src:*void, dst:*void, n:ux) : ux = { + fn select_rows_widen{sh}(src:*void, dst:*void, max:ux, n:ux) : ux = { if (sh != 0) { def bulk = (arch_defvw/8) >> sh def WV = [bulk< inds_buf_max) return{0} + if (max >= (inds_buf_max>>sh)) return{0} + @for_backwards (i to inds_buf_max/(width{WV}/8)) { - def V = [bulk]u8 def s = loadLow{*arch_minv{V}~~(*u8~~src + i*bulk), width{V}} def v = raw_widen_inds{bulk, sh, s} store{*WV~~dst, i, v} diff --git a/test/cases/cells.bqn b/test/cases/cells.bqn index f040f42f..6be1cff6 100644 --- a/test/cases/cells.bqn +++ b/test/cases/cells.bqn @@ -85,6 +85,9 @@ %USE eqvar ⋄ 0‿0‿0‿0 {𝕨⊸⊏˘𝕩}_eqvar ≍˘↕5 %% 5‿4⥊⌊4÷˜↕20 %USE eqvar ⋄ 0‿¯1‿0‿¯1 {𝕨⊸⊏˘𝕩}_eqvar ≍˘↕5 %% 5‿4⥊⌊4÷˜↕20 +%USE eqvar ⋄ 100‿¯3 {𝕨⊸⊏˘𝕩}_eqvar 10‿200⥊↕2000 %% 10‿2⥊100‿197‿300‿397‿500‿597‿700‿797‿900‿997‿1100‿1197‿1300‿1397‿1500‿1597‿1700‿1797‿1900‿1997 +%USE eqvar ⋄ 100‿50 {𝕨⊸⊏˘𝕩}_eqvar 10‿200⥊↕2000 %% 10‿2⥊100‿50‿300‿250‿500‿450‿700‿650‿900‿850‿1100‿1050‿1300‿1250‿1500‿1450‿1700‿1650‿1900‿1850 +%USE eqvar ⋄ ¯1‿¯2‿¯3 {𝕨⊸⊏˘𝕩}_eqvar 8‿80⥊↕557 %% 8‿3⥊79‿78‿77‿159‿158‿157‿239‿238‿237‿319‿318‿317‿399‿398‿397‿479‿478‿477‿2‿1‿0‿82‿81‿80 !"⊏: Indexing out-of-bounds (1∊𝕨, 1≡≠𝕩)" % %USE evar ⋄ 0‿¯1‿1‿¯1 {𝕨⊸⊏˘𝕩}_evar ≍˘↕5 !"⊏: Indexing out-of-bounds (¯2∊𝕨, 1≡≠𝕩)" % %USE evar ⋄ 0‿¯1‿¯2‿¯1 {𝕨⊸⊏˘𝕩}_evar ≍˘↕5