summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordzaima <dzaimagit@gmail.com>2024-05-20 00:46:02 +0300
committerdzaima <dzaimagit@gmail.com>2024-05-20 01:03:57 +0300
commit44c8da7dc76a0fd4b38146a6d974586269d63707 (patch)
treee2dec8c6286dc3c94850bbba3bdd4b0ee755c113
parent52fb05fcd47364dede4b408f1b28836c44ba585a (diff)
add checks for l>0 on equal() impls
some Singeli `fn equal` paths already assumed such, this just makes the requirement properly checked for, benefited from, and documented
-rw-r--r--src/builtins/compare.c7
-rw-r--r--src/singeli/src/equal.singeli1
-rw-r--r--src/singeli/src/mask.singeli1
-rw-r--r--src/utils/calls.h3
4 files changed, 7 insertions, 5 deletions
diff --git a/src/builtins/compare.c b/src/builtins/compare.c
index a8b5268f..f55831cf 100644
--- a/src/builtins/compare.c
+++ b/src/builtins/compare.c
@@ -107,13 +107,14 @@ u8 const eqFnData[] = { // for the main diagonal, amount to shift length by; oth
#else
#define F(X) equal_##X
bool F(1_1)(void* w, void* x, u64 l, u64 d) {
+ assert(l>0);
u64* wp = w; u64* xp = x;
usz q = l/64;
for (usz i=0; i<q; i++) if (wp[i] != xp[i]) return false;
usz r = (-l)%64; return r==0 || (wp[q]^xp[q])<<r == 0;
}
#define DEF_EQ_U1(N, T) \
- bool F(1_##N)(void* w, void* x, u64 l, u64 d) { \
+ bool F(1_##N)(void* w, void* x, u64 l, u64 d) { assert(l>0); \
if (d!=0) { void* t=w; w=x; x=t; } \
u64* wp = w; T* xp = x; \
for (usz i=0; i<l; i++) if (bitp_get(wp,i)!=xp[i]) return false; \
@@ -127,7 +128,7 @@ u8 const eqFnData[] = { // for the main diagonal, amount to shift length by; oth
#define DEF_EQ_I(NAME, S, T, INIT) \
bool F(NAME)(void* w, void* x, u64 l, u64 d) { \
- INIT \
+ assert(l>0); INIT \
S* wp = w; T* xp = x; \
for (usz i=0; i<l; i++) if (wp[i]!=xp[i]) return false; \
return true; \
@@ -143,7 +144,7 @@ u8 const eqFnData[] = { // for the main diagonal, amount to shift length by; oth
#undef DEF_EQ_I
#undef DEF_EQ
#endif
-bool notEq(void* a, void* b, u64 l, u64 data) { return false; }
+bool notEq(void* a, void* b, u64 l, u64 data) { assert(l>0); return false; }
INIT_GLOBAL EqFn eqFns[] = {
F(1_1), F(1_8), F(1_16), F(1_32), F(1_f64), notEq, notEq, notEq,
F(1_8), F(8_8), F(s8_16), F(s8_32), F(s8_f64), notEq, notEq, notEq,
diff --git a/src/singeli/src/equal.singeli b/src/singeli/src/equal.singeli
index b80eb02d..3bdd7ff2 100644
--- a/src/singeli/src/equal.singeli
+++ b/src/singeli/src/equal.singeli
@@ -15,6 +15,7 @@ fn equal{W, X}(w:*void, x:*void, l:u64, d:u64) : u1 = {
def vw = arch_defvw
def bulk = vw / width{X}
if (W!=X) if (d!=0) swap{w,x}
+ assert{l>0}
if (W==u1) {
if (X==u1) { # bitarr ≡ bitarr
diff --git a/src/singeli/src/mask.singeli b/src/singeli/src/mask.singeli
index d9979b7d..adc575e2 100644
--- a/src/singeli/src/mask.singeli
+++ b/src/singeli/src/mask.singeli
@@ -103,6 +103,7 @@ def maskedLoop{bulk} = maskedLoop{bulk,0}
def maskedLoopPositive{bulk}{vars,begin==0,end:L,iter} = {
+ assert{end > 0}
i:L = 0
while(i < (end-1)/bulk) {
mlExec{i, iter, vars, bulk, maskNone}
diff --git a/src/utils/calls.h b/src/utils/calls.h
index d38cf376..137b8810 100644
--- a/src/utils/calls.h
+++ b/src/utils/calls.h
@@ -26,14 +26,13 @@ CMP_DEF(le, AS);
#define CMP_AA_IMM(FN, ELT, WHERE, WP, XP, LEN) CMP_AA_CALL(CMP_AA_FN(FN, ELT), WHERE, WP, XP, LEN)
#define CMP_AS_IMM(FN, ELT, WHERE, WP, X, LEN) CMP_AS_CALL(CMP_AS_FN(FN, ELT), WHERE, WP, X, LEN)
-// Check if the l elements starting at a and b match
typedef bool (*EqFn)(void* a, void* b, u64 l, u64 data);
extern INIT_GLOBAL EqFn eqFns[];
extern u8 const eqFnData[];
#define EQFN_INDEX(W_ELT, X_ELT) ((W_ELT)*8 + (X_ELT))
typedef struct { EqFn fn; u8 data; } EqFnObj;
#define EQFN_GET(W_ELT, X_ELT) ({ u8 eqfn_i_ = EQFN_INDEX(W_ELT, X_ELT); (EqFnObj){.fn=eqFns[eqfn_i_], .data=eqFnData[eqfn_i_]}; })
-#define EQFN_CALL(FN, W, X, L) (FN).fn(W, X, L, (FN).data)
+#define EQFN_CALL(FN, W, X, L) (FN).fn(W, X, L, (FN).data) // check if L elements starting at a and b match; assumes L≥1
typedef bool (*RangeFn)(void* xp, i64* res, u64 len); // writes min,max in res, assumes len≥1; returns 0 and leaves res undefined if either any (floor(x)≠x or abs>2⋆53), or (x≠(i64)x)
extern INIT_GLOBAL RangeFn getRange_fns[el_f64+1]; // limited to ≤el_f64