From 59109f32930a0c163628f8087cbb0a15b19cb96b Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Tue, 5 Mar 2013 00:59:13 +0200 Subject: [PATCH] test: larger 0xFF/0x00 filled clusters in random images for blitters-test 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 */ -- 2.7.4