This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
New tests for memcpy/memset/strlen/strcmp/strncmp
- From: Michael Meissner <meissner at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 9 Mar 2002 15:23:43 -0500
- Subject: New tests for memcpy/memset/strlen/strcmp/strncmp
I was optimizing the string functions in newlib to speed up some
common cases on the MIPS, and wrote the following tests to make sure
that all combnations likely to be optimized of alignments and lengths
are done. I added this to the torture test suite.
2002-03-09 Michael Meissner <meissner@redhat.com>
* gcc.c-torture/execute/memcpy-2.c: New test.
* gcc.c-torture/execute/memset-1.c: New test.
* gcc.c-torture/execute/strlen-1.c: New test.
* gcc.c-torture/execute/strcmp-1.c: New test.
* gcc.c-torture/execute/strncmp-1.c: New test.
*** gcc/testsuite/gcc.c-torture/execute/memcpy-2.c.~1~ Sat Mar 9 15:18:57 2002
--- gcc/testsuite/gcc.c-torture/execute/memcpy-2.c Sat Mar 9 15:05:54 2002
***************
*** 0 ****
--- 1,64 ----
+ /* Copyright (C) 2002 Free Software Foundation.
+
+ Test memcpy with various combinations of pointer alignments and lengths to
+ make sure any optimizations in the library are correct.
+
+ Written by Michael Meissner, March 9, 2002. */
+
+ #include <string.h>
+
+ #ifndef MAX_OFFSET
+ #define MAX_OFFSET (sizeof (long long))
+ #endif
+
+ #ifndef MAX_COPY
+ #define MAX_COPY (8 * sizeof (long long))
+ #endif
+
+ #ifndef MAX_EXTRA
+ #define MAX_EXTRA (sizeof (long long))
+ #endif
+
+ #define MAX_LENGTH (MAX_OFFSET + MAX_COPY + MAX_EXTRA)
+
+ static union {
+ char buf[MAX_LENGTH];
+ long long align_int;
+ long double align_fp;
+ } u1, u2;
+
+ main ()
+ {
+ int off1, off2, len, i;
+ char *p, *q;
+
+ for (off1 = 0; off1 < MAX_OFFSET; off1++)
+ for (off2 = 0; off2 < MAX_OFFSET; off2++)
+ for (len = 1; len < MAX_COPY; len++)
+ {
+ for (i = 0; i < MAX_LENGTH; i++)
+ {
+ u1.buf[i] = 'a';
+ u2.buf[i] = 'A';
+ }
+
+ p = memcpy (u1.buf + off1, u2.buf + off2, len);
+ if (p != u1.buf + off1)
+ abort ();
+
+ q = u1.buf;
+ for (i = 0; i < off1; i++, q++)
+ if (*q != 'a')
+ abort ();
+
+ for (i = 0; i < len; i++, q++)
+ if (*q != 'A')
+ abort ();
+
+ for (i = 0; i < MAX_EXTRA; i++, q++)
+ if (*q != 'a')
+ abort ();
+ }
+
+ exit (0);
+ }
*** gcc/testsuite/gcc.c-torture/execute/memset-1.c.~1~ Sat Mar 9 15:18:57 2002
--- gcc/testsuite/gcc.c-torture/execute/memset-1.c Sat Mar 9 15:06:35 2002
***************
*** 0 ****
--- 1,96 ----
+ /* Copyright (C) 2002 Free Software Foundation.
+
+ Test memset with various combinations of pointer alignments and lengths to
+ make sure any optimizations in the library are correct.
+
+ Written by Michael Meissner, March 9, 2002. */
+
+ #include <string.h>
+
+ #ifndef MAX_OFFSET
+ #define MAX_OFFSET (sizeof (long long))
+ #endif
+
+ #ifndef MAX_COPY
+ #define MAX_COPY (8 * sizeof (long long))
+ #endif
+
+ #ifndef MAX_EXTRA
+ #define MAX_EXTRA (sizeof (long long))
+ #endif
+
+ #define MAX_LENGTH (MAX_OFFSET + MAX_COPY + MAX_EXTRA)
+
+ static union {
+ char buf[MAX_LENGTH];
+ long long align_int;
+ long double align_fp;
+ } u;
+
+ char A = 'A';
+
+ main ()
+ {
+ int off, len, i;
+ char *p, *q;
+
+ for (off = 0; off < MAX_OFFSET; off++)
+ for (len = 1; len < MAX_COPY; len++)
+ {
+ for (i = 0; i < MAX_LENGTH; i++)
+ u.buf[i] = 'a';
+
+ p = memset (u.buf + off, '\0', len);
+ if (p != u.buf + off)
+ abort ();
+
+ q = u.buf;
+ for (i = 0; i < off; i++, q++)
+ if (*q != 'a')
+ abort ();
+
+ for (i = 0; i < len; i++, q++)
+ if (*q != '\0')
+ abort ();
+
+ for (i = 0; i < MAX_EXTRA; i++, q++)
+ if (*q != 'a')
+ abort ();
+
+ p = memset (u.buf + off, A, len);
+ if (p != u.buf + off)
+ abort ();
+
+ q = u.buf;
+ for (i = 0; i < off; i++, q++)
+ if (*q != 'a')
+ abort ();
+
+ for (i = 0; i < len; i++, q++)
+ if (*q != 'A')
+ abort ();
+
+ for (i = 0; i < MAX_EXTRA; i++, q++)
+ if (*q != 'a')
+ abort ();
+
+ p = memset (u.buf + off, 'B', len);
+ if (p != u.buf + off)
+ abort ();
+
+ q = u.buf;
+ for (i = 0; i < off; i++, q++)
+ if (*q != 'a')
+ abort ();
+
+ for (i = 0; i < len; i++, q++)
+ if (*q != 'B')
+ abort ();
+
+ for (i = 0; i < MAX_EXTRA; i++, q++)
+ if (*q != 'a')
+ abort ();
+ }
+
+ exit (0);
+ }
*** gcc/testsuite/gcc.c-torture/execute/strlen-1.c.~1~ Sat Mar 9 15:18:57 2002
--- gcc/testsuite/gcc.c-torture/execute/strlen-1.c Sat Mar 9 15:09:07 2002
***************
*** 0 ****
--- 1,57 ----
+ /* Copyright (C) 2002 Free Software Foundation.
+
+ Test strlen with various combinations of pointer alignments and lengths to
+ make sure any optimizations in the library are correct.
+
+ Written by Michael Meissner, March 9, 2002. */
+
+ #include <string.h>
+ #include <stddef.h>
+
+ #ifndef MAX_OFFSET
+ #define MAX_OFFSET (sizeof (long long))
+ #endif
+
+ #ifndef MAX_TEST
+ #define MAX_TEST (8 * sizeof (long long))
+ #endif
+
+ #ifndef MAX_EXTRA
+ #define MAX_EXTRA (sizeof (long long))
+ #endif
+
+ #define MAX_LENGTH (MAX_OFFSET + MAX_TEST + MAX_EXTRA + 1)
+
+ static union {
+ char buf[MAX_LENGTH];
+ long long align_int;
+ long double align_fp;
+ } u;
+
+ main ()
+ {
+ size_t off, len, len2, i;
+ char *p;
+
+ for (off = 0; off < MAX_OFFSET; off++)
+ for (len = 0; len < MAX_TEST; len++)
+ {
+ p = u.buf;
+ for (i = 0; i < off; i++)
+ *p++ = '\0';
+
+ for (i = 0; i < len; i++)
+ *p++ = 'a';
+
+ *p++ = '\0';
+ for (i = 0; i < MAX_EXTRA; i++)
+ *p++ = 'b';
+
+ p = u.buf + off;
+ len2 = strlen (p);
+ if (len != len2)
+ abort ();
+ }
+
+ exit (0);
+ }
*** gcc/testsuite/gcc.c-torture/execute/strcmp-1.c.~1~ Sat Mar 9 15:18:57 2002
--- gcc/testsuite/gcc.c-torture/execute/strcmp-1.c Sat Mar 9 15:11:08 2002
***************
*** 0 ****
--- 1,131 ----
+ /* Copyright (C) 2002 Free Software Foundation.
+
+ Test strcmp with various combinations of pointer alignments and lengths to
+ make sure any optimizations in the library are correct.
+
+ Written by Michael Meissner, March 9, 2002. */
+
+ #include <string.h>
+ #include <stddef.h>
+
+ #ifndef MAX_OFFSET
+ #define MAX_OFFSET (sizeof (long long))
+ #endif
+
+ #ifndef MAX_TEST
+ #define MAX_TEST (8 * sizeof (long long))
+ #endif
+
+ #ifndef MAX_EXTRA
+ #define MAX_EXTRA (sizeof (long long))
+ #endif
+
+ #define MAX_LENGTH (MAX_OFFSET + MAX_TEST + MAX_EXTRA + 2)
+
+ static union {
+ unsigned char buf[MAX_LENGTH];
+ long long align_int;
+ long double align_fp;
+ } u1, u2;
+
+ void
+ test (const unsigned char *s1, const unsigned char *s2, int expected)
+ {
+ int value = strcmp ((char *) s1, (char *) s2);
+
+ if (expected < 0 && value >= 0)
+ abort ();
+ else if (expected == 0 && value != 0)
+ abort ();
+ else if (expected > 0 && value <= 0)
+ abort ();
+ }
+
+ main ()
+ {
+ size_t off1, off2, len, i;
+ unsigned char *buf1, *buf2;
+ unsigned char *mod1, *mod2;
+ unsigned char *p1, *p2;
+
+ for (off1 = 0; off1 < MAX_OFFSET; off1++)
+ for (off2 = 0; off2 < MAX_OFFSET; off2++)
+ for (len = 0; len < MAX_TEST; len++)
+ {
+ p1 = u1.buf;
+ for (i = 0; i < off1; i++)
+ *p1++ = '\0';
+
+ buf1 = p1;
+ for (i = 0; i < len; i++)
+ *p1++ = 'a';
+
+ mod1 = p1;
+ for (i = 0; i < MAX_EXTRA+2; i++)
+ *p1++ = 'x';
+
+ p2 = u2.buf;
+ for (i = 0; i < off2; i++)
+ *p2++ = '\0';
+
+ buf2 = p2;
+ for (i = 0; i < len; i++)
+ *p2++ = 'a';
+
+ mod2 = p2;
+ for (i = 0; i < MAX_EXTRA+2; i++)
+ *p2++ = 'x';
+
+ mod1[0] = '\0';
+ mod2[0] = '\0';
+ test (buf1, buf2, 0);
+
+ mod1[0] = 'a';
+ mod1[1] = '\0';
+ mod2[0] = '\0';
+ test (buf1, buf2, +1);
+
+ mod1[0] = '\0';
+ mod2[0] = 'a';
+ mod2[1] = '\0';
+ test (buf1, buf2, -1);
+
+ mod1[0] = 'b';
+ mod1[1] = '\0';
+ mod2[0] = 'c';
+ mod2[1] = '\0';
+ test (buf1, buf2, -1);
+
+ mod1[0] = 'c';
+ mod1[1] = '\0';
+ mod2[0] = 'b';
+ mod2[1] = '\0';
+ test (buf1, buf2, +1);
+
+ mod1[0] = 'b';
+ mod1[1] = '\0';
+ mod2[0] = (unsigned char)'\251';
+ mod2[1] = '\0';
+ test (buf1, buf2, -1);
+
+ mod1[0] = (unsigned char)'\251';
+ mod1[1] = '\0';
+ mod2[0] = 'b';
+ mod2[1] = '\0';
+ test (buf1, buf2, +1);
+
+ mod1[0] = (unsigned char)'\251';
+ mod1[1] = '\0';
+ mod2[0] = (unsigned char)'\252';
+ mod2[1] = '\0';
+ test (buf1, buf2, -1);
+
+ mod1[0] = (unsigned char)'\252';
+ mod1[1] = '\0';
+ mod2[0] = (unsigned char)'\251';
+ mod2[1] = '\0';
+ test (buf1, buf2, +1);
+ }
+
+ exit (0);
+ }
*** gcc/testsuite/gcc.c-torture/execute/strncmp-1.c.~1~ Sat Mar 9 15:18:57 2002
--- gcc/testsuite/gcc.c-torture/execute/strncmp-1.c Sat Mar 9 15:14:16 2002
***************
*** 0 ****
--- 1,140 ----
+ /* Copyright (C) 2002 Free Software Foundation.
+
+ Test strncmp with various combinations of pointer alignments and lengths to
+ make sure any optimizations in the library are correct.
+
+ Written by Michael Meissner, March 9, 2002. */
+
+ #include <string.h>
+ #include <stddef.h>
+
+ #ifndef MAX_OFFSET
+ #define MAX_OFFSET (sizeof (long long))
+ #endif
+
+ #ifndef MAX_TEST
+ #define MAX_TEST (8 * sizeof (long long))
+ #endif
+
+ #ifndef MAX_EXTRA
+ #define MAX_EXTRA (sizeof (long long))
+ #endif
+
+ #define MAX_LENGTH (MAX_OFFSET + MAX_TEST + MAX_EXTRA)
+
+ static union {
+ unsigned char buf[MAX_LENGTH];
+ long long align_int;
+ long double align_fp;
+ } u1, u2;
+
+ void
+ test (const unsigned char *s1, const unsigned char *s2, size_t len, int expected)
+ {
+ int value = strncmp ((char *) s1, (char *) s2, len);
+
+ if (expected < 0 && value >= 0)
+ abort ();
+ else if (expected == 0 && value != 0)
+ abort ();
+ else if (expected > 0 && value <= 0)
+ abort ();
+ }
+
+ main ()
+ {
+ size_t off1, off2, len, i;
+ unsigned char *buf1, *buf2;
+ unsigned char *mod1, *mod2;
+ unsigned char *p1, *p2;
+
+ for (off1 = 0; off1 < MAX_OFFSET; off1++)
+ for (off2 = 0; off2 < MAX_OFFSET; off2++)
+ for (len = 0; len < MAX_TEST; len++)
+ {
+ p1 = u1.buf;
+ for (i = 0; i < off1; i++)
+ *p1++ = '\0';
+
+ buf1 = p1;
+ for (i = 0; i < len; i++)
+ *p1++ = 'a';
+
+ mod1 = p1;
+ for (i = 0; i < MAX_EXTRA; i++)
+ *p1++ = 'x';
+
+ p2 = u2.buf;
+ for (i = 0; i < off2; i++)
+ *p2++ = '\0';
+
+ buf2 = p2;
+ for (i = 0; i < len; i++)
+ *p2++ = 'a';
+
+ mod2 = p2;
+ for (i = 0; i < MAX_EXTRA; i++)
+ *p2++ = 'x';
+
+ mod1[0] = '\0';
+ mod2[0] = '\0';
+ test (buf1, buf2, MAX_LENGTH, 0);
+ test (buf1, buf2, len, 0);
+
+ mod1[0] = 'a';
+ mod1[1] = '\0';
+ mod2[0] = '\0';
+ test (buf1, buf2, MAX_LENGTH, +1);
+ test (buf1, buf2, len, 0);
+
+ mod1[0] = '\0';
+ mod2[0] = 'a';
+ mod2[1] = '\0';
+ test (buf1, buf2, MAX_LENGTH, -1);
+ test (buf1, buf2, len, 0);
+
+ mod1[0] = 'b';
+ mod1[1] = '\0';
+ mod2[0] = 'c';
+ mod2[1] = '\0';
+ test (buf1, buf2, MAX_LENGTH, -1);
+ test (buf1, buf2, len, 0);
+
+ mod1[0] = 'c';
+ mod1[1] = '\0';
+ mod2[0] = 'b';
+ mod2[1] = '\0';
+ test (buf1, buf2, MAX_LENGTH, +1);
+ test (buf1, buf2, len, 0);
+
+ mod1[0] = 'b';
+ mod1[1] = '\0';
+ mod2[0] = (unsigned char)'\251';
+ mod2[1] = '\0';
+ test (buf1, buf2, MAX_LENGTH, -1);
+ test (buf1, buf2, len, 0);
+
+ mod1[0] = (unsigned char)'\251';
+ mod1[1] = '\0';
+ mod2[0] = 'b';
+ mod2[1] = '\0';
+ test (buf1, buf2, MAX_LENGTH, +1);
+ test (buf1, buf2, len, 0);
+
+ mod1[0] = (unsigned char)'\251';
+ mod1[1] = '\0';
+ mod2[0] = (unsigned char)'\252';
+ mod2[1] = '\0';
+ test (buf1, buf2, MAX_LENGTH, -1);
+ test (buf1, buf2, len, 0);
+
+ mod1[0] = (unsigned char)'\252';
+ mod1[1] = '\0';
+ mod2[0] = (unsigned char)'\251';
+ mod2[1] = '\0';
+ test (buf1, buf2, MAX_LENGTH, +1);
+ test (buf1, buf2, len, 0);
+ }
+
+ exit (0);
+ }
--
Michael Meissner, Red Hat, Inc. (GCC group)
PMB 198, 174 Littleton Road #3, Westford, Massachusetts 01886, USA
Work: meissner@redhat.com phone: +1 978-486-9304
Non-work: meissner@the-meissners.org fax: +1 978-692-4482