From 54a9000d88fa97b0384aca66a9d23a7a8d87f23a Mon Sep 17 00:00:00 2001 From: dzaima Date: Mon, 28 Mar 2022 02:52:51 +0300 Subject: [PATCH] more general any-not-equal check --- src/singeli/src/avx.singeli | 3 ++- src/singeli/src/avx2.singeli | 1 + src/singeli/src/dyarith.singeli | 8 +++++--- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/singeli/src/avx.singeli b/src/singeli/src/avx.singeli index 7dc125dc..df01e10b 100644 --- a/src/singeli/src/avx.singeli +++ b/src/singeli/src/avx.singeli @@ -130,5 +130,6 @@ def pair{x} = pair{tupsel{0,x},tupsel{1,x}} # mask stuff def getmask{x:T & w256{T, 32}} = emit{u8, '_mm256_movemask_ps', v2f{x}} def getmask{x:T & w256{T, 64}} = emit{u8, '_mm256_movemask_pd', v2d{x}} -def any{x:T & w256i{T}} = getmask{x}!=0 # assumes elements of x all have equal bits (avx2 utilizes this for 16 bits) +def any{x:T & w256i{T}} = getmask{x} != 0 # assumes elements of x all have equal bits (avx2 utilizes this for 16 bits) +def all{x:T & w256i{T}} = getmask{x} == (1<>8) # TODO try out permute4x64 for fixing up } def any{x:T & w256i{T, 16}} = getmask{cast_v{[32]u8,x}}!=0 +def all{x:T & w256i{T, 16}} = getmask{cast_v{[32]u8,x}} == (1<<32)-1 def anyneg{x:T & w256s{T, 16}} = getmask{cast_v{[32]u8, cast_v{[16]i16,x} < broadcast{[16]i16, 0}}}!=0 diff --git a/src/singeli/src/dyarith.singeli b/src/singeli/src/dyarith.singeli index a6def3ba..a7362863 100644 --- a/src/singeli/src/dyarith.singeli +++ b/src/singeli/src/dyarith.singeli @@ -26,12 +26,14 @@ def genmask{T,n & w256{T,64}} = load{cast_p{[ 4]i64, emit{*i64, '', 'mask64'} + def maskstoreF{p, m, n, x:T & width{eltype{T}}>=32} = maskstore{p,m,n,x} def maskstoreF{p, m, n, x:T} = store{p, n, blendf{load{p,n}, x, m}} +def anyne{x:T, y:T, M & M{0}==0} = ~all{x==y} +def anyne{x:T, y:T, M & M{0}==1} = any{M{x!=y}} # + & - def arithChk1{F, M, w:T, x:T, r:T & match{F,__add}} = anyneg{M{(w^r) & (x^r)}} def arithChk1{F, M, w:T, x:T, r:T & match{F,__sub}} = anyneg{M{(w^x) & (w^r)}} -def arithChk1{F, M, w:T, x:T, r:T & match{F,__add} & isvec{T} & width{eltype{T}}<=16} = any{M{to_el{i8, __adds{w,x}} != to_el{i8, r}}} -def arithChk1{F, M, w:T, x:T, r:T & match{F,__sub} & isvec{T} & width{eltype{T}}<=16} = any{M{to_el{i8, __subs{w,x}} != to_el{i8, r}}} +def arithChk1{F, M, w:T, x:T, r:T & match{F,__add} & isvec{T} & width{eltype{T}}<=16} = anyne{__adds{w,x}, r, M} +def arithChk1{F, M, w:T, x:T, r:T & match{F,__sub} & isvec{T} & width{eltype{T}}<=16} = anyne{__subs{w,x}, r, M} def arithChk2{F, M, w:T, x:T, i & issigned{rootty{T}}} = { r:= F{w,x} @@ -47,7 +49,7 @@ def arithChk2{F, M, w:T, x:T, i & match{F,__mul} & match{typekind{T},'primitive' def arithChk2{F, M, w:T, x:T, i & match{F,__mul} & isvec{T} & i16==eltype{T}} = { rl:= __mul {w,x} rh:= __mulhi{w,x} - tup{rl, any{M{rh != rl>>15}}} + tup{rl, anyne{rh, rl>>15, M}} } def arithChk2{F, M, w:T, x:T, i & match{F,__mul} & isvec{T} & i8==eltype{T}} = { def wp = unpackQ{w, cast_v{T,broadcast{T,0}>w}}