Skip to content

Commit ff244c4

Browse files
authored
[HashRecognize] Add CRC optz tests with type-mismatch (#261)
1 parent eaed381 commit ff244c4

22 files changed

+482
-10
lines changed

SingleSource/UnitTests/HashRecognize/crc16.be.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ static uint16_t crc_table(uint16_t crc_initval, uint16_t data) {
2424
crc_init();
2525

2626
for (size_t i = 0; i < 2; ++i) {
27-
uint16_t pos = (crc >> 8) ^ (data << (i << 3) >> 8);
28-
crc = (crc << 8) ^ CRCTable[pos & 0xFF];
27+
uint8_t pos = (crc ^ (data << (i << 3))) >> 8;
28+
crc = (crc << 8) ^ CRCTable[pos];
2929
}
3030

3131
return crc;
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include <stdint.h>
2+
#include <stdlib.h>
3+
4+
#define GENPOLY 4129
5+
6+
static uint16_t CRCTable[256];
7+
8+
static void crc_init(void) {
9+
uint16_t crc = 0x8000;
10+
for (unsigned int i = 1; i < 256; i <<= 1) {
11+
crc = (crc << 1) ^ (crc & 0x8000 ? GENPOLY : 0);
12+
for (unsigned int j = 0; j < i; j++)
13+
CRCTable[i + j] = crc ^ CRCTable[j];
14+
}
15+
}
16+
17+
// This table-lookup should be equivalent to the code emitted when optimizing
18+
// CRC with HashRecognize. This function itself will be untouched by
19+
// HashRecognize.
20+
static uint16_t crc_table(uint16_t crc_initval, uint32_t data) {
21+
uint16_t crc = crc_initval;
22+
23+
if (CRCTable[255] == 0)
24+
crc_init();
25+
26+
for (size_t i = 0; i < 4; ++i) {
27+
uint8_t pos = (crc ^ (data << (i << 3))) >> 8;
28+
crc = (crc << 8) ^ CRCTable[pos];
29+
}
30+
31+
return crc;
32+
}
33+
34+
static uint16_t crc_loop(uint16_t crc_initval, uint32_t data) {
35+
uint16_t crc = crc_initval;
36+
37+
// This loop will be optimized by HashRecognize.
38+
for (size_t i = 0; i < 32; ++i) {
39+
uint16_t xor_crc_data = crc ^ data;
40+
uint16_t crc_shl = crc << 1;
41+
crc = (xor_crc_data & 0x8000) ? (crc_shl ^ GENPOLY) : crc_shl;
42+
data <<= 1;
43+
}
44+
return crc;
45+
}
46+
47+
int main() {
48+
// These are random hand-picked values.
49+
static const uint16_t crc_initval[8] = {0, 129, 11, 255, 16, 4129, 16384, 1};
50+
static const uint32_t data[8] = {0, 1, 11, 16, 129, 255, 4129, 16384};
51+
for (size_t i = 0; i < 8; ++i) {
52+
uint16_t actual = crc_loop(crc_initval[i], data[i]);
53+
uint16_t expected = crc_table(crc_initval[i], data[i]);
54+
if (actual != expected)
55+
return 1;
56+
}
57+
return 0;
58+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
exit 0
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include <stdint.h>
2+
#include <stdlib.h>
3+
4+
#define GENPOLY 4129
5+
6+
static uint16_t CRCTable[256];
7+
8+
static void crc_init(void) {
9+
uint16_t crc = 0x8000;
10+
for (unsigned int i = 1; i < 256; i <<= 1) {
11+
crc = (crc << 1) ^ (crc & 0x8000 ? GENPOLY : 0);
12+
for (unsigned int j = 0; j < i; j++)
13+
CRCTable[i + j] = crc ^ CRCTable[j];
14+
}
15+
}
16+
17+
// This table-lookup should be equivalent to the code emitted when optimizing
18+
// CRC with HashRecognize. This function itself will be untouched by
19+
// HashRecognize.
20+
static uint16_t crc_table(uint16_t crc_initval, uint8_t data) {
21+
uint16_t crc = crc_initval;
22+
23+
if (CRCTable[255] == 0)
24+
crc_init();
25+
26+
for (size_t i = 0; i < 1; ++i) {
27+
uint8_t pos = (crc ^ (data << (i << 3))) >> 8;
28+
crc = (crc << 8) ^ CRCTable[pos];
29+
}
30+
31+
return crc;
32+
}
33+
34+
static uint16_t crc_loop(uint16_t crc_initval, uint8_t data) {
35+
uint16_t crc = crc_initval;
36+
37+
// This loop will be optimized by HashRecognize.
38+
for (size_t i = 0; i < 8; ++i) {
39+
uint16_t xor_crc_data = crc ^ data;
40+
uint16_t crc_shl = crc << 1;
41+
crc = (xor_crc_data & 0x8000) ? (crc_shl ^ GENPOLY) : crc_shl;
42+
data <<= 1;
43+
}
44+
return crc;
45+
}
46+
47+
int main() {
48+
// These are random hand-picked values.
49+
static const uint16_t crc_initval[8] = {0, 129, 11, 255, 16, 4129, 16384, 1};
50+
static const uint8_t data[8] = {0, 1, 11, 16, 129, 255, 142, 255};
51+
for (size_t i = 0; i < 8; ++i) {
52+
uint16_t actual = crc_loop(crc_initval[i], data[i]);
53+
uint16_t expected = crc_table(crc_initval[i], data[i]);
54+
if (actual != expected)
55+
return 1;
56+
}
57+
return 0;
58+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
exit 0

SingleSource/UnitTests/HashRecognize/crc16.be.nodata.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ static uint16_t crc_table(uint16_t crc_initval) {
2424
crc_init();
2525

2626
for (size_t i = 0; i < 2; ++i) {
27-
uint16_t pos = (crc >> 8);
28-
crc = (crc << 8) ^ CRCTable[pos & 0xFF];
27+
uint8_t pos = crc >> 8;
28+
crc = (crc << 8) ^ CRCTable[pos];
2929
}
3030

3131
return crc;

SingleSource/UnitTests/HashRecognize/crc16.le.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ static uint16_t crc_table(uint16_t crc_initval, uint16_t data) {
2424
crc_init();
2525

2626
for (size_t i = 0; i < 2; ++i) {
27-
uint16_t pos = crc ^ (data >> (i << 3));
28-
crc = (crc >> 8) ^ CRCTable[pos & 0xFF];
27+
uint8_t pos = crc ^ (data >> (i << 3));
28+
crc = (crc >> 8) ^ CRCTable[pos];
2929
}
3030

3131
return crc;
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include <stdint.h>
2+
#include <stdlib.h>
3+
4+
#define GENPOLY -24575
5+
6+
static uint16_t CRCTable[256];
7+
8+
static void crc_init(void) {
9+
uint16_t crc = 1;
10+
for (unsigned int i = 128; i; i >>= 1) {
11+
crc = (crc >> 1) ^ (crc & 1 ? GENPOLY : 0);
12+
for (unsigned int j = 0; j < 256; j += 2 * i)
13+
CRCTable[i + j] = crc ^ CRCTable[j];
14+
}
15+
}
16+
17+
// This table-lookup should be equivalent to the code emitted when optimizing
18+
// CRC with HashRecognize. This function itself will be untouched by
19+
// HashRecognize.
20+
static uint16_t crc_table(uint16_t crc_initval, uint32_t data) {
21+
uint16_t crc = crc_initval;
22+
23+
if (CRCTable[255] == 0)
24+
crc_init();
25+
26+
for (size_t i = 0; i < 4; ++i) {
27+
uint8_t pos = crc ^ (data >> (i << 3));
28+
crc = (crc >> 8) ^ CRCTable[pos];
29+
}
30+
31+
return crc;
32+
}
33+
34+
static uint16_t crc_loop(uint16_t crc_initval, uint32_t data) {
35+
uint16_t crc = crc_initval;
36+
37+
// This loop will be optimized by HashRecognize.
38+
for (size_t i = 0; i < 32; ++i) {
39+
uint16_t xor_crc_data = crc ^ data;
40+
uint16_t crc_lshr = crc >> 1;
41+
crc = (xor_crc_data & 1) ? (crc_lshr ^ GENPOLY) : crc_lshr;
42+
data >>= 1;
43+
}
44+
return crc;
45+
}
46+
47+
int main() {
48+
// These are random hand-picked values.
49+
static const uint16_t crc_initval[8] = {0, 129, 11, 255, 16, 4129, 16384, 1};
50+
static const uint32_t data[8] = {0, 1, 11, 16, 129, 255, 4129, 16384};
51+
for (size_t i = 0; i < 8; ++i) {
52+
uint16_t actual = crc_loop(crc_initval[i], data[i]);
53+
uint16_t expected = crc_table(crc_initval[i], data[i]);
54+
if (actual != expected)
55+
return 1;
56+
}
57+
return 0;
58+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
exit 0
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include <stdint.h>
2+
#include <stdlib.h>
3+
4+
#define GENPOLY -24575
5+
6+
static uint16_t CRCTable[256];
7+
8+
static void crc_init(void) {
9+
uint16_t crc = 1;
10+
for (unsigned int i = 128; i; i >>= 1) {
11+
crc = (crc >> 1) ^ (crc & 1 ? GENPOLY : 0);
12+
for (unsigned int j = 0; j < 256; j += 2 * i)
13+
CRCTable[i + j] = crc ^ CRCTable[j];
14+
}
15+
}
16+
17+
// This table-lookup should be equivalent to the code emitted when optimizing
18+
// CRC with HashRecognize. This function itself will be untouched by
19+
// HashRecognize.
20+
static uint16_t crc_table(uint16_t crc_initval, uint8_t data) {
21+
uint16_t crc = crc_initval;
22+
23+
if (CRCTable[255] == 0)
24+
crc_init();
25+
26+
for (size_t i = 0; i < 1; ++i) {
27+
uint8_t pos = crc ^ (data >> (i << 3));
28+
crc = (crc >> 8) ^ CRCTable[pos];
29+
}
30+
31+
return crc;
32+
}
33+
34+
static uint16_t crc_loop(uint16_t crc_initval, uint8_t data) {
35+
uint16_t crc = crc_initval;
36+
37+
// This loop will be optimized by HashRecognize.
38+
for (size_t i = 0; i < 8; ++i) {
39+
uint16_t xor_crc_data = crc ^ data;
40+
uint16_t crc_lshr = crc >> 1;
41+
crc = (xor_crc_data & 1) ? (crc_lshr ^ GENPOLY) : crc_lshr;
42+
data >>= 1;
43+
}
44+
return crc;
45+
}
46+
47+
int main() {
48+
// These are random hand-picked values.
49+
static const uint16_t crc_initval[8] = {0, 129, 11, 255, 16, 4129, 16384, 1};
50+
static const uint8_t data[8] = {0, 1, 11, 16, 129, 255, 142, 255};
51+
for (size_t i = 0; i < 8; ++i) {
52+
uint16_t actual = crc_loop(crc_initval[i], data[i]);
53+
uint16_t expected = crc_table(crc_initval[i], data[i]);
54+
if (actual != expected)
55+
return 1;
56+
}
57+
return 0;
58+
}

0 commit comments

Comments
 (0)