Compilers are not able to vectorise the load and store loops. Building
with -fopt-info-vec-missed with gcc 16.1:
missed: statement clobbers memory: ml_printf (".");
This can be fixed by doing the printf after the loops.
Also, autovectorisation doesn't like more than one if statement in the
loop:
missed: not vectorized: unsupported control flow in loop.
By combining them into ternary statements and one if, the loops are able
to be vectorised with both loads and stores.
The trade off is the dots are gone, and the tests no longer report fine
grained miscompares. A failure does report the number of bad elements in
a failing test loop.
Signed-off-by: Joel Stanley <[email protected]>
---
tests/tcg/multiarch/system/memory.c | 113 ++++++++++++----------------
1 file changed, 50 insertions(+), 63 deletions(-)
diff --git a/tests/tcg/multiarch/system/memory.c
b/tests/tcg/multiarch/system/memory.c
index 7508f6b916d0..6eeb738343ab 100644
--- a/tests/tcg/multiarch/system/memory.c
+++ b/tests/tcg/multiarch/system/memory.c
@@ -42,9 +42,6 @@ static void pdot(int count, bool write)
} else {
test_read_count++;
}
- if (count % 128 == 0) {
- ml_printf(".");
- }
}
/*
@@ -77,7 +74,6 @@ static void init_test_data_u8(int unused_offset)
*ptr++ = BYTE_NEXT(count);
pdot(i, true);
}
-
ml_printf("done %d @ %p\n", i, ptr);
}
@@ -127,7 +123,6 @@ static void reset_start_data(int offset)
*ptr++ = 0;
pdot(i, true);
}
-
ml_printf("done %d @ %p\n", i, ptr);
}
@@ -203,7 +198,7 @@ static void init_test_data_u64(int offset)
static bool read_test_data_u16(int offset)
{
uint16_t word, *ptr = (uint16_t *)&test_data[offset];
- int i;
+ int i, bad = 0;
const int max = (TEST_SIZE - offset) / sizeof(word);
ml_printf("Reading u16 from %#lx (offset %d):", ptr, offset);
@@ -214,12 +209,13 @@ static bool read_test_data_u16(int offset)
high = (word >> 8) & 0xff;
low = word & 0xff;
if (high < low && high != 0) {
- ml_printf("Error %d < %d\n", high, low);
- return false;
- } else {
- pdot(i, false);
+ bad++;
}
-
+ }
+ test_read_count += max;
+ if (bad) {
+ ml_printf("Error: %d bad u16 words\n", bad);
+ return false;
}
ml_printf("done %d @ %p\n", i, ptr);
return true;
@@ -228,7 +224,7 @@ static bool read_test_data_u16(int offset)
static bool read_test_data_u32(int offset)
{
uint32_t word, *ptr = (uint32_t *)&test_data[offset];
- int i;
+ int i, bad = 0;
const int max = (TEST_SIZE - offset) / sizeof(word);
ml_printf("Reading u32 from %#lx (offset %d):", ptr, offset);
@@ -247,21 +243,18 @@ static bool read_test_data_u32(int offset)
zeros += (b2 == 0 ? 1 : 0);
zeros += (b3 == 0 ? 1 : 0);
zeros += (b4 == 0 ? 1 : 0);
- if (zeros > 1) {
- ml_printf("Error @ %p, more zeros than expected: %d, %d, %d, %d",
- ptr - 1, b1, b2, b3, b4);
- return false;
- }
-
- if ((b1 < b2 && b1 != 0) ||
+ if (zeros > 1 ||
+ (b1 < b2 && b1 != 0) ||
(b2 < b3 && b2 != 0) ||
(b3 < b4 && b3 != 0)) {
- ml_printf("Error %d, %d, %d, %d", b1, b2, b3, b4);
- return false;
- } else {
- pdot(i, false);
+ bad++;
}
}
+ test_read_count += max;
+ if (bad) {
+ ml_printf("Error: %d bad u32 words\n", bad);
+ return false;
+ }
ml_printf("done %d @ %p\n", i, ptr);
return true;
}
@@ -270,7 +263,7 @@ static bool read_test_data_u32(int offset)
static bool read_test_data_u64(int offset)
{
uint64_t word, *ptr = (uint64_t *)&test_data[offset];
- int i;
+ int i, bad = 0;
const int max = (TEST_SIZE - offset) / sizeof(word);
ml_printf("Reading u64 from %#lx (offset %d):", ptr, offset);
@@ -297,26 +290,22 @@ static bool read_test_data_u64(int offset)
zeros += (b6 == 0 ? 1 : 0);
zeros += (b7 == 0 ? 1 : 0);
zeros += (b8 == 0 ? 1 : 0);
- if (zeros > 1) {
- ml_printf("Error @ %p, more zeros than expected: %d, %d, %d, %d,
%d, %d, %d, %d",
- ptr - 1, b1, b2, b3, b4, b5, b6, b7, b8);
- return false;
- }
-
- if ((b1 < b2 && b1 != 0) ||
+ if (zeros > 1 ||
+ (b1 < b2 && b1 != 0) ||
(b2 < b3 && b2 != 0) ||
(b3 < b4 && b3 != 0) ||
(b4 < b5 && b4 != 0) ||
(b5 < b6 && b5 != 0) ||
(b6 < b7 && b6 != 0) ||
(b7 < b8 && b7 != 0)) {
- ml_printf("Error %d, %d, %d, %d, %d, %d, %d, %d",
- b1, b2, b3, b4, b5, b6, b7, b8);
- return false;
- } else {
- pdot(i, false);
+ bad++;
}
}
+ test_read_count += max;
+ if (bad) {
+ ml_printf("Error: %d bad u64 words\n", bad);
+ return false;
+ }
ml_printf("done %d @ %p\n", i, ptr);
return true;
}
@@ -374,28 +363,26 @@ static bool do_unsigned_test(init_ufn fn)
static bool read_test_data_s8(int offset, bool neg_first)
{
int8_t *ptr = (int8_t *)&test_data[offset];
- int i;
+ int i, bad = 0;
const int max = (TEST_SIZE - offset) / 2;
ml_printf("Reading s8 pairs from %#lx (offset %d):", ptr, offset);
for (i = 0; i < max; i++) {
int16_t first, second;
- bool ok;
first = *ptr++;
second = *ptr++;
- if (neg_first && first < 0 && second > 0) {
- pdot(i, false);
- pdot(i, false);
- } else if (!neg_first && first > 0 && second < 0) {
- pdot(i, false);
- pdot(i, false);
- } else {
- ml_printf("Error %d %c %d\n", first, neg_first ? '<' : '>',
second);
- return false;
+ if (!(neg_first ? (first < 0 && second > 0)
+ : (first > 0 && second < 0))) {
+ bad++;
}
}
+ test_read_count += max * 2;
+ if (bad) {
+ ml_printf("Error: %d bad s8 pairs\n", bad);
+ return false;
+ }
ml_printf("done %d @ %p\n", i * 2, ptr);
return true;
}
@@ -403,7 +390,7 @@ static bool read_test_data_s8(int offset, bool neg_first)
static bool read_test_data_s16(int offset, bool neg_first)
{
int16_t *ptr = (int16_t *)&test_data[offset];
- int i;
+ int i, bad = 0;
const int max = (TEST_SIZE - offset) / (sizeof(*ptr));
ml_printf("Reading s16 from %#lx (offset %d, %s):", ptr,
@@ -420,15 +407,15 @@ static bool read_test_data_s16(int offset, bool neg_first)
for (i = 0; i < max; i++) {
int32_t data = *ptr++;
- if (neg_first && data < 0) {
- pdot(i, false);
- } else if (!neg_first && data > 0) {
- pdot(i, false);
- } else {
- ml_printf("Error %d %c 0\n", data, neg_first ? '<' : '>');
- return false;
+ if (!(neg_first ? data < 0 : data > 0)) {
+ bad++;
}
}
+ test_read_count += max;
+ if (bad) {
+ ml_printf("Error: %d bad s16 words\n", bad);
+ return false;
+ }
ml_printf("done %d @ %p\n", i, ptr);
return true;
}
@@ -436,7 +423,7 @@ static bool read_test_data_s16(int offset, bool neg_first)
static bool read_test_data_s32(int offset, bool neg_first)
{
int32_t *ptr = (int32_t *)&test_data[offset];
- int i;
+ int i, bad = 0;
const int max = (TEST_SIZE - offset) / (sizeof(int32_t));
ml_printf("Reading s32 from %#lx (offset %d, %s):",
@@ -453,15 +440,15 @@ static bool read_test_data_s32(int offset, bool neg_first)
for (i = 0; i < max; i++) {
int64_t data = *ptr++;
- if (neg_first && data < 0) {
- pdot(i, false);
- } else if (!neg_first && data > 0) {
- pdot(i, false);
- } else {
- ml_printf("Error %d %c 0\n", data, neg_first ? '<' : '>');
- return false;
+ if (!(neg_first ? data < 0 : data > 0)) {
+ bad++;
}
}
+ test_read_count += max;
+ if (bad) {
+ ml_printf("Error: %d bad s32 words\n", bad);
+ return false;
+ }
ml_printf("done %d @ %p\n", i, ptr);
return true;
}
--
2.47.3