Enable vector max- min-, and wrapping plus-scan on NEON
Changes the results on NaNs, but they weren't consistent before
This commit is contained in:
parent
317871db55
commit
fb413b1966
@ -39,7 +39,7 @@ def get_scan_last{op, pre} = {
|
||||
|
||||
# Associative scan ?` if a?b?a = a?b = b?a, used for ⌊⌈
|
||||
def scan_idem = scan_scal
|
||||
fn scan_idem{T, op if hasarch{'X86_64'}}(x:*T, r:*T, len:u64, init:T) : void = {
|
||||
fn scan_idem{T, op if has_simd}(x:*T, r:*T, len:u64, init:T) : void = {
|
||||
def {scan, last} = get_scan_last{op, make_scan_idem{T, op}}
|
||||
def cmp = match (op) { {(min)} => (>); {(max)} => (<) }
|
||||
def step = arch_defvw/width{T}
|
||||
@ -82,8 +82,8 @@ def scan_plus = scan_assoc_id0{+}
|
||||
|
||||
# Associative scan
|
||||
def scan_assoc_0 = scan_scal
|
||||
fn scan_assoc_0{T, op if hasarch{'X86_64'}}(x:*T, r:*T, len:u64, init:T) : void = {
|
||||
# Prefix op on entire AVX register
|
||||
fn scan_assoc_0{T, op if has_simd}(x:*T, r:*T, len:u64, init:T) : void = {
|
||||
# Prefix op on entire SIMD register
|
||||
scan_loop{init, x, r, len, ...get_scan_last{op, scan_plus}}
|
||||
}
|
||||
export{'si_scan_pluswrap_u8', scan_assoc_0{u8 , +}}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
# Used by scan.singeli and bins.singeli
|
||||
|
||||
def has_sel8 = hasarch{'SSSE3'} or hasarch{'AARCH64'}
|
||||
def sel8{v:V, t} = sel{[16]u8, v, make{re_el{i8,V}, t}}
|
||||
def sel8{v:V, t if w256{V} and istup{t} and length{t}==16} = sel8{v, merge{t,t}}
|
||||
|
||||
@ -17,9 +18,9 @@ def spread{a:[_]T, ...up} = {
|
||||
}
|
||||
|
||||
# Set all elements with the last element of the input
|
||||
def toLast{n:VT, up if hasarch{'X86_64'} and w128{VT}} = {
|
||||
def toLast{n:VT, up if has_simd and w128{VT}} = {
|
||||
def l{v, w} = l{zip{up,v}, 2*w}
|
||||
def l{v, w if hasarch{'SSSE3'}} = sel8{v, up*(16-w/8)+iota{16}%(w/8)}
|
||||
def l{v, w if has_sel8} = sel8{v, up*(16-w/8)+iota{16}%(w/8)}
|
||||
def l{v, w==32} = shuf{[4]i32, v, 4**(up*3)}
|
||||
def l{v, w==64} = shuf{[2]i64, v, 2** up }
|
||||
l{n, elwidth{VT}}
|
||||
@ -49,7 +50,7 @@ def make_scan_idem{T, op, up} = {
|
||||
def id = make{V, merger{c**get_id{op,T}, (width{V}/w-c)**0}}
|
||||
(if (up) vec_shift_right_128 else vec_shift_left_128){v, c} | id
|
||||
}
|
||||
def shb{v, k if hasarch{'SSSE3'}} = sel8{v, shift{k/8,16}}
|
||||
def shb{v, k if has_sel8} = sel8{v, shift{k/8,16}}
|
||||
def shb{v, k if k>=32} = shuf{[4]u32, v, shift{k/32,4}}
|
||||
def shb{v, k if k==128 and hasarch{'AVX2'}} = {
|
||||
# After lanewise scan, broadcast end of lane 0 to entire lane 1
|
||||
|
||||
Loading…
Reference in New Issue
Block a user