mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-11-16 01:12:15 +03:00
Fix double shufti's vector end false positive (#325)
* Add regression test for double shufti It tests for false positive at vector edges. Signed-off-by: Yoan Picchi <yoan.picchi@arm.com> * Fix double shufti reporting false positives Double shufti used to offset one vector, resulting in losing one character at the end of every vector. This was replaced by a magic value indicating a match. This meant that if the first char of a pattern fell on the last char of a vector, double shufti would assume the second character is present and report a match. This patch fixes it by keeping the previous vector and feeding its data to the new one when we shift it, preventing any loss of data. Signed-off-by: Yoan Picchi <yoan.picchi@arm.com> * vshl() will call the correct implementation * implement missing vshr_512_imm(), simplifies caller x86 code * Fix x86 case, use alignr instead * it's the reverse, the avx512 alignr is incorrect, need to fix * Make shufti's OR reduce size agnostic Signed-off-by: Yoan Picchi <yoan.picchi@arm.com> * Fix test's array size Signed-off-by: Yoan Picchi <yoan.picchi@arm.com> * Fix AVX2/AVX512 alignr implementations and unit tests * Fix Power VSX alignr --------- Signed-off-by: Yoan Picchi <yoan.picchi@arm.com> Co-authored-by: Konstantinos Margaritis <konstantinos@vectorcamp.gr>
This commit is contained in:
@@ -899,7 +899,40 @@ TEST(DoubleShufti, ExecMatchMixed3) {
|
||||
const u8 *rv = shuftiDoubleExec(lo1, hi1, lo2, hi2,
|
||||
reinterpret_cast<u8 *>(t2), reinterpret_cast<u8 *>(t2) + len);
|
||||
|
||||
ASSERT_EQ(reinterpret_cast<const u8 *>(&t2[len - i]), rv);
|
||||
if(i < 2) {
|
||||
// i=0 is "xy" out of buffer. i=1 is "x" in buffer but not "y"
|
||||
ASSERT_EQ(reinterpret_cast<const u8 *>(t2 + len), rv);
|
||||
}else {
|
||||
ASSERT_EQ(reinterpret_cast<const u8 *>(&t2[len - i]), rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Double shufti used to report matches when the first char of a pair landed at
|
||||
// the end of a vector. This test check for the regression.
|
||||
TEST(DoubleShufti, ExecNoMatchVectorEdge) {
|
||||
m128 lo1, hi1, lo2, hi2;
|
||||
|
||||
flat_set<pair<u8, u8>> lits;
|
||||
|
||||
lits.insert(make_pair('a','c'));
|
||||
|
||||
bool ret = shuftiBuildDoubleMasks(CharReach(), lits, reinterpret_cast<u8 *>(&lo1), reinterpret_cast<u8 *>(&hi1),
|
||||
reinterpret_cast<u8 *>(&lo2), reinterpret_cast<u8 *>(&hi2));
|
||||
ASSERT_TRUE(ret);
|
||||
|
||||
const int len = 80;
|
||||
char t1[len + 2];
|
||||
memset(t1, 'b', len);
|
||||
|
||||
for (size_t i = 0; i < 70; i++) {
|
||||
t1[len - i] = 'a';
|
||||
t1[len - i + 1] = 'b';
|
||||
DEBUG_PRINTF("i = %ld\n", i);
|
||||
const u8 *rv = shuftiDoubleExec(lo1, hi1, lo2, hi2,
|
||||
reinterpret_cast<u8 *>(t1), reinterpret_cast<u8 *>(t1) + len);
|
||||
|
||||
ASSERT_EQ(reinterpret_cast<const u8 *>(t1 + len), rv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -697,7 +697,6 @@ TEST(SuperVectorUtilsTest,RShift128_256c){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*Define ALIGNR256 macro*/
|
||||
#define TEST_ALIGNR256(v1, v2, buf, l) { \
|
||||
auto v_aligned = v2.alignr(v1, l); \
|
||||
@@ -706,6 +705,7 @@ TEST(SuperVectorUtilsTest,RShift128_256c){
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
TEST(SuperVectorUtilsTest,Alignr256c){
|
||||
u8 vec[64];
|
||||
for (int i=0; i<64; i++) {
|
||||
@@ -713,7 +713,7 @@ TEST(SuperVectorUtilsTest,Alignr256c){
|
||||
}
|
||||
auto SP1 = SuperVector<32>::loadu(vec);
|
||||
auto SP2 = SuperVector<32>::loadu(vec+32);
|
||||
for(int j=0; j<32; j++) {
|
||||
for(size_t j=0; j<32; j++) {
|
||||
TEST_ALIGNR256(SP1, SP2, vec, j);
|
||||
}
|
||||
}
|
||||
@@ -1045,10 +1045,9 @@ TEST(SuperVectorUtilsTest,LShift128_512c){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*Define ALIGNR512 macro*/
|
||||
#define TEST_ALIGNR512(v1, v2, buf, l) { \
|
||||
auto v_aligned = v1.alignr(v2, l); \
|
||||
auto v_aligned = v2.alignr(v1, l); \
|
||||
for (size_t i=0; i<64; i++) { \
|
||||
ASSERT_EQ(v_aligned.u.u8[i], vec[i + l]); \
|
||||
} \
|
||||
@@ -1061,7 +1060,7 @@ TEST(SuperVectorUtilsTest,Alignr512c){
|
||||
}
|
||||
auto SP1 = SuperVector<64>::loadu(vec);
|
||||
auto SP2 = SuperVector<64>::loadu(vec+64);
|
||||
for(int j=0; j<64; j++){
|
||||
for(size_t j=0; j<64; j++){
|
||||
TEST_ALIGNR512(SP1, SP2, vec, j);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user