[Pixman] [PATCH] test: larger 0xFF/0x00 filled clusters in random images for blitters-test
Siarhei Siamashka
siarhei.siamashka at gmail.com
Mon Mar 4 20:34:49 PST 2013
Current blitters-test program had difficulties detecting a bug in
over_n_8888_8888_ca implementation for MIPS DSPr2:
http://lists.freedesktop.org/archives/pixman/2013-March/002645.html
In order to hit the buggy code path, two consecutive mask values had
to be equal to 0xFFFFFFFF because of loop unrolling. The current
blitters-test generates random images in such a way that each byte
has 25% probability for having 0xFF value. Hence each 32-bit mask
value has ~0.4% probability for 0xFFFFFFFF. Because we are testing
many compositing operations with many pixels, encountering at least
one 0xFFFFFFFF mask value reasonably fast is not a problem. If a
bug related to 0xFFFFFFFF mask value is artificialy introduced into
over_n_8888_8888_ca generic C function, it gets detected on 675591
iteration in blitters-test (out of 2000000).
However two consecutive 0xFFFFFFFF mask values are much less likely
to be generated, so the bug was missed by blitters-test.
This patch addresses the problem by also randomly setting the 32-bit
values in images to either 0xFFFFFFFF or 0x00000000 (also with 25%
probability). It allows to have larger clusters of consecutive 0x00
or 0xFF bytes in images which may have special shortcuts for handling
them in unrolled or SIMD optimized code.
---
test/blitters-test.c | 13 ++++++++++--
test/prng-test.c | 5 ++++-
test/utils-prng.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++-----
test/utils-prng.h | 5 ++++-
4 files changed, 72 insertions(+), 9 deletions(-)
diff --git a/test/blitters-test.c b/test/blitters-test.c
index 8766fa8..a2c6ff4 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -46,7 +46,16 @@ create_random_image (pixman_format_code_t *allowed_formats,
/* do the allocation */
buf = aligned_malloc (64, stride * height);
- prng_randmemset (buf, stride * height, RANDMEMSET_MORE_00_AND_FF);
+ if (prng_rand_n (4) == 0)
+ {
+ /* uniform distribution */
+ prng_randmemset (buf, stride * height, 0);
+ }
+ else
+ {
+ /* significantly increased probability for 0x00 and 0xFF */
+ prng_randmemset (buf, stride * height, RANDMEMSET_MORE_00_AND_FF);
+ }
img = pixman_image_create_bits (fmt, width, height, buf, stride);
@@ -393,6 +402,6 @@ main (int argc, const char *argv[])
}
return fuzzer_test_main("blitters", 2000000,
- 0xD8265D5E,
+ 0x0CF3283B,
test_composite, argc, argv);
}
diff --git a/test/prng-test.c b/test/prng-test.c
index 0a3ad5e..c1d9320 100644
--- a/test/prng-test.c
+++ b/test/prng-test.c
@@ -106,7 +106,10 @@ int main (int argc, char *argv[])
{
const uint32_t ref_crc[RANDMEMSET_MORE_00_AND_FF + 1] =
{
- 0xBA06763D, 0x103FC550, 0x8B59ABA5, 0xD82A0F39
+ 0xBA06763D, 0x103FC550, 0x8B59ABA5, 0xD82A0F39,
+ 0xD2321099, 0xFD8C5420, 0xD3B7C42A, 0xFC098093,
+ 0x85E01DE0, 0x6680F8F7, 0x4D32DD3C, 0xAE52382B,
+ 0x149E6CB5, 0x8B336987, 0x15DCB2B3, 0x8A71B781
};
uint32_t crc1, crc2;
uint32_t ref, seed, seed0, seed1, seed2, seed3;
diff --git a/test/utils-prng.c b/test/utils-prng.c
index 967b898..7b32e35 100644
--- a/test/utils-prng.c
+++ b/test/utils-prng.c
@@ -107,6 +107,7 @@ randmemset_internal (prng_t *prng,
{
prng_t local_prng = *prng;
prng_rand_128_data_t randdata;
+ size_t i;
while (size >= 16)
{
@@ -138,6 +139,22 @@ randmemset_internal (prng_t *prng,
};
randdata.vb &= (t.vb >= const_40);
}
+ if (flags & RANDMEMSET_MORE_FFFFFFFF)
+ {
+ const uint32x4 const_C0000000 =
+ {
+ 0xC0000000, 0xC0000000, 0xC0000000, 0xC0000000
+ };
+ randdata.vw |= ((t.vw << 30) >= const_C0000000);
+ }
+ if (flags & RANDMEMSET_MORE_00000000)
+ {
+ const uint32x4 const_40000000 =
+ {
+ 0x40000000, 0x40000000, 0x40000000, 0x40000000
+ };
+ randdata.vw &= ((t.vw << 30) >= const_40000000);
+ }
#else
#define PROCESS_ONE_LANE(i) \
if (flags & RANDMEMSET_MORE_FF) \
@@ -155,6 +172,18 @@ randmemset_internal (prng_t *prng,
mask_00 |= mask_00 >> 2; \
mask_00 |= mask_00 >> 4; \
randdata.w[i] &= mask_00; \
+ } \
+ if (flags & RANDMEMSET_MORE_FFFFFFFF) \
+ { \
+ int32_t mask_ff = ((t.w[i] << 30) & (t.w[i] << 31)) & \
+ 0x80000000; \
+ randdata.w[i] |= mask_ff >> 31; \
+ } \
+ if (flags & RANDMEMSET_MORE_00000000) \
+ { \
+ int32_t mask_00 = ((t.w[i] << 30) | (t.w[i] << 31)) & \
+ 0x80000000; \
+ randdata.w[i] &= mask_00 >> 31; \
}
PROCESS_ONE_LANE (0)
@@ -198,7 +227,8 @@ randmemset_internal (prng_t *prng,
}
size -= 16;
}
- while (size > 0)
+ i = 0;
+ while (i < size)
{
uint8_t randbyte = prng_rand_r (&local_prng) & 0xFF;
if (flags != 0)
@@ -208,9 +238,25 @@ randmemset_internal (prng_t *prng,
randbyte = 0xFF;
if ((flags & RANDMEMSET_MORE_00) && (t < 0x40))
randbyte = 0x00;
+ if (i % 4 == 0 && i + 4 <= size)
+ {
+ t = prng_rand_r (&local_prng) & 0xFF;
+ if ((flags & RANDMEMSET_MORE_FFFFFFFF) && (t >= 0xC0))
+ {
+ memset(&buf[i], 0xFF, 4);
+ i += 4;
+ continue;
+ }
+ if ((flags & RANDMEMSET_MORE_00000000) && (t < 0x40))
+ {
+ memset(&buf[i], 0x00, 4);
+ i += 4;
+ continue;
+ }
+ }
}
- *buf++ = randbyte;
- size--;
+ buf[i] = randbyte;
+ i++;
}
*prng = local_prng;
}
@@ -218,8 +264,10 @@ randmemset_internal (prng_t *prng,
/*
* Fill memory buffer with random data. Flags argument may be used
* to tweak some statistics properties:
- * RANDMEMSET_MORE_00 - set ~25% of bytes to 0x00
- * RANDMEMSET_MORE_FF - set ~25% of bytes to 0xFF
+ * RANDMEMSET_MORE_00 - set ~25% of bytes to 0x00
+ * RANDMEMSET_MORE_FF - set ~25% of bytes to 0xFF
+ * RANDMEMSET_MORE_00000000 - ~25% chance for 00000000 4-byte clusters
+ * RANDMEMSET_MORE_FFFFFFFF - ~25% chance for FFFFFFFF 4-byte clusters
*/
void prng_randmemset_r (prng_t *prng,
void *voidbuf,
diff --git a/test/utils-prng.h b/test/utils-prng.h
index 285107f..564ffce 100644
--- a/test/utils-prng.h
+++ b/test/utils-prng.h
@@ -153,7 +153,10 @@ typedef enum
{
RANDMEMSET_MORE_00 = 1, /* ~25% chance for 0x00 bytes */
RANDMEMSET_MORE_FF = 2, /* ~25% chance for 0xFF bytes */
- RANDMEMSET_MORE_00_AND_FF = (RANDMEMSET_MORE_00 | RANDMEMSET_MORE_FF)
+ RANDMEMSET_MORE_00000000 = 4, /* ~25% chance for 0x00000000 clusters */
+ RANDMEMSET_MORE_FFFFFFFF = 8, /* ~25% chance for 0xFFFFFFFF clusters */
+ RANDMEMSET_MORE_00_AND_FF = (RANDMEMSET_MORE_00 | RANDMEMSET_MORE_00000000 |
+ RANDMEMSET_MORE_FF | RANDMEMSET_MORE_FFFFFFFF)
} prng_randmemset_flags_t;
/* Set the 32-bit seed for PRNG */
--
1.7.12.4
More information about the Pixman
mailing list