Message ID | CAGWvnym-Y8jhpZ8xpEsdbsRp9FKZMk+KfBVeYrGOcwVN7sNf_g@mail.gmail.com |
---|---|
State | New |
Headers | show |
Series | [testsuite] memchr-1.c wide char and AIX | expand |
On 10/05/2018 12:54 PM, David Edelsohn wrote: > memchr-1.c tests for char (test_narrow) and wchar (test_wide). The > wide character test assumes 32 bit wide character, while 32 bit AIX > uses 16 bit wide character. This assumption causes the wide character > part of the test to fail in 32 bit mode on AIX (it succeeds on 64 bit > AIX). > > The testcase already includes ifdefs for endianness. The "narrow" > part of the test succeeds and is a useful test on AIX. Me proposed > solution adds an AIX-specific ifdef in the testcase to avoid the > compile-time errors in 32 bit mode. > > Because of the structure of the testcase, I need to #ifdef test_wide() > and its constants, and separately it's invocation in main(), as > opposed to making test_wide() a no-op that is called. > > Another alternative is to split memchr-1.c into memchr-1.c for > test_narrow and memchr-2.c for test_wide, with the latter skipped on > AIX using a DejaGNU directive. > > Is the #ifdef okay or would others prefer that I split the testcase? > No solution is particularly elegant. That's my bad for hardwiring 4 as the wchar_t size. Sorry about the breakage. I can't think of any better solutions than what you covered above. It would be nice to exercise this optimization with 16-bit wchar_t. It looks like GCC has a -fshort-wchar option to force wchar_t to be 2 bytes wide that I didn't know about. That will make the problem easier to solve without necessarily having to build all of GCC on AIX. Let me take care of it. Martin > > Thanks, David > > * gcc.c-torture/execute/memchr-1.c (test_wide): Skip on 32 bit AIX. > > Index: memchr-1.c > =================================================================== > --- memchr-1.c (revision 264869) > +++ memchr-1.c (working copy) > @@ -106,6 +106,7 @@ > A (memchr (&s5_3[1][i0], 0, sizeof s5_3[1] - i0) == &s5_3[1][4]); > } > > +#if !defined(_AIX) || defined(__64BIT__) > static const wchar_t wc = L'1'; > static const wchar_t ws1[] = L"1"; > static const wchar_t ws4[] = L"\x00123456\x12005678\x12340078\x12345600"; > @@ -144,10 +145,13 @@ > A (memchr (&ws4[3], 0, nb - 3 * nwb) == pws4 + 3 * nwb + 3); > #endif > } > +#endif > > > int main () > { > test_narrow (); > +#if !defined(_AIX) || defined(__64BIT__) > test_wide (); > +#endif > } >
David, Attached is a patch to conditionalize the memchr-1.c test to pass even with 2-byte wchar_t's. It also adds a compile only test to verify memchr with -fnarrow-wchar. I verified the changes on LE x86_64-linux and BE powerpc64-linux but if you could confirm they also work on AIX that would be great. Unless some concerns come up I will plan to commit these changes sometime next week. Thanks Martin On 10/05/2018 02:10 PM, Martin Sebor wrote: > On 10/05/2018 12:54 PM, David Edelsohn wrote: >> memchr-1.c tests for char (test_narrow) and wchar (test_wide). The >> wide character test assumes 32 bit wide character, while 32 bit AIX >> uses 16 bit wide character. This assumption causes the wide character >> part of the test to fail in 32 bit mode on AIX (it succeeds on 64 bit >> AIX). >> >> The testcase already includes ifdefs for endianness. The "narrow" >> part of the test succeeds and is a useful test on AIX. Me proposed >> solution adds an AIX-specific ifdef in the testcase to avoid the >> compile-time errors in 32 bit mode. >> >> Because of the structure of the testcase, I need to #ifdef test_wide() >> and its constants, and separately it's invocation in main(), as >> opposed to making test_wide() a no-op that is called. >> >> Another alternative is to split memchr-1.c into memchr-1.c for >> test_narrow and memchr-2.c for test_wide, with the latter skipped on >> AIX using a DejaGNU directive. >> >> Is the #ifdef okay or would others prefer that I split the testcase? >> No solution is particularly elegant. > > That's my bad for hardwiring 4 as the wchar_t size. Sorry about > the breakage. I can't think of any better solutions than what > you covered above. It would be nice to exercise this optimization > with 16-bit wchar_t. It looks like GCC has a -fshort-wchar option > to force wchar_t to be 2 bytes wide that I didn't know about. > That will make the problem easier to solve without necessarily > having to build all of GCC on AIX. Let me take care of it. > > Martin > >> >> Thanks, David >> >> * gcc.c-torture/execute/memchr-1.c (test_wide): Skip on 32 bit AIX. >> >> Index: memchr-1.c >> =================================================================== >> --- memchr-1.c (revision 264869) >> +++ memchr-1.c (working copy) >> @@ -106,6 +106,7 @@ >> A (memchr (&s5_3[1][i0], 0, sizeof s5_3[1] - i0) == &s5_3[1][4]); >> } >> >> +#if !defined(_AIX) || defined(__64BIT__) >> static const wchar_t wc = L'1'; >> static const wchar_t ws1[] = L"1"; >> static const wchar_t ws4[] = >> L"\x00123456\x12005678\x12340078\x12345600"; >> @@ -144,10 +145,13 @@ >> A (memchr (&ws4[3], 0, nb - 3 * nwb) == pws4 + 3 * nwb + 3); >> #endif >> } >> +#endif >> >> >> int main () >> { >> test_narrow (); >> +#if !defined(_AIX) || defined(__64BIT__) >> test_wide (); >> +#endif >> } >> > gcc/tewstsuite/ChangeLog: * gcc.c-torture/execute/memchr-1.c: Avoid assuming 4-byte wchar_t. Add a test for 2-byte wchar_t. * gcc.dg/builtin-memchr.c: New test. Index: gcc/testsuite/gcc.c-torture/execute/memchr-1.c =================================================================== --- gcc/testsuite/gcc.c-torture/execute/memchr-1.c (revision 264875) +++ gcc/testsuite/gcc.c-torture/execute/memchr-1.c (working copy) @@ -106,6 +106,8 @@ void test_narrow (void) A (memchr (&s5_3[1][i0], 0, sizeof s5_3[1] - i0) == &s5_3[1][4]); } +#if 4 == __WCHAR_WIDTH__ + static const wchar_t wc = L'1'; static const wchar_t ws1[] = L"1"; static const wchar_t ws4[] = L"\x00123456\x12005678\x12340078\x12345600"; @@ -145,7 +147,59 @@ void test_wide (void) #endif } +#elif 2 == __WCHAR_WIDTH__ +static const wchar_t wc = L'1'; +static const wchar_t ws1[] = L"1"; +static const wchar_t ws2[2] = L"\x1234\x5678"; /* no terminating nul */ +static const wchar_t ws4[] = L"\x0012\x1200\x1234"; + +void test_wide (void) +{ + int i0 = 0; + int i1 = i0 + 1; + int i2 = i1 + 1; + + A (sizeof (wchar_t) == 2); + + A (memchr (L"" + 1, 0, 0) == 0); + A (memchr (&wc + 1, 0, 0) == 0); + A (memchr (L"\x1234", 0, sizeof (wchar_t)) == 0); + + A (memchr (L"" + i1, i0, i0) == 0); + A (memchr (&wc + i1, i0, i0) == 0); + A (memchr (L"\x1234", i0, sizeof (wchar_t)) == 0); + + A (memchr (ws2, 0, sizeof ws2) == 0); + A (memchr (ws2, i0, sizeof ws2) == 0); + + const size_t nb = sizeof ws4; + const size_t nwb = sizeof (wchar_t); + + const char *pws1 = (const char*)ws1; + const char *pws4 = (const char*)ws4; + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + A (memchr (ws1, i0, sizeof ws1) == pws1 + 1); + + A (memchr (&ws4[0], i0, nb) == pws4 + i1); + A (memchr (&ws4[1], i0, nb - i1 * nwb) == pws4 + i1 * nwb); + A (memchr (&ws4[2], i0, nb - i2 * nwb) == pws4 + i2 * nwb + i2); +#else + A (memchr (ws1, i0, sizeof ws1) == pws1 + 0); + + A (memchr (&ws4[0], i0, nb) == pws4 + 0); + A (memchr (&ws4[1], i0, nb - i1 * nwb) == pws4 + i1 * nwb + i1); + A (memchr (&ws4[2], i0, nb - i2 * nwb) == pws4 + i2 * nwb + i2); +#endif +} + +#else + +void test_wide (void) { } + +#endif + int main () { test_narrow (); Index: gcc/testsuite/gcc.dg/builtin-memchr.c =================================================================== --- gcc/testsuite/gcc.dg/builtin-memchr.c (nonexistent) +++ gcc/testsuite/gcc.dg/builtin-memchr.c (working copy) @@ -0,0 +1,68 @@ +/* PR tree-optimization/86711 - wrong folding of memchr + + Verify that memchr() of arrays initialized with 16-bit wide string + literals finds the nul only when it is present in the wide string. + + { dg-do compile } + { dg-options "-O1 -Wall -fshort-wchar -fdump-tree-optimized" } */ + +typedef __SIZE_TYPE__ size_t; +typedef __WCHAR_TYPE__ wchar_t; + +extern void* memchr (const void*, int, size_t); +extern int printf (const char*, ...); +extern void abort (void); + +#define A(expr) \ + ((expr) \ + ? (void)0 \ + : (printf ("assertion failed on line %i: %s\n", \ + __LINE__, #expr), \ + abort ())) + +static const wchar_t wc = L'1'; +static const wchar_t ws1[] = L"1"; +static const wchar_t ws2[2] = L"\x1234\x5678"; /* no terminating nul */ +static const wchar_t ws4[] = L"\x0012\x1200\x1234"; + +void test_wide (void) +{ + int i0 = 0; + int i1 = i0 + 1; + int i2 = i1 + 1; + + A (sizeof (wchar_t) == 2); + + A (memchr (L"" + 1, 0, 0) == 0); + A (memchr (&wc + 1, 0, 0) == 0); + A (memchr (L"\x1234", 0, sizeof (wchar_t)) == 0); + + A (memchr (L"" + i1, i0, i0) == 0); + A (memchr (&wc + i1, i0, i0) == 0); + A (memchr (L"\x1234", i0, sizeof (wchar_t)) == 0); + + A (memchr (ws2, 0, sizeof ws2) == 0); + A (memchr (ws2, i0, sizeof ws2) == 0); + + const size_t nb = sizeof ws4; + const size_t nwb = sizeof (wchar_t); + + const char *pws1 = (const char*)ws1; + const char *pws4 = (const char*)ws4; + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + A (memchr (ws1, i0, sizeof ws1) == pws1 + 1); + + A (memchr (&ws4[0], i0, nb) == pws4 + i1); + A (memchr (&ws4[1], i0, nb - i1 * nwb) == pws4 + i1 * nwb); + A (memchr (&ws4[2], i0, nb - i2 * nwb) == pws4 + i2 * nwb + i2); +#else + A (memchr (ws1, i0, sizeof ws1) == pws1 + 0); + + A (memchr (&ws4[0], i0, nb) == pws4 + 0); + A (memchr (&ws4[1], i0, nb - i1 * nwb) == pws4 + i1 * nwb + i1); + A (memchr (&ws4[2], i0, nb - i2 * nwb) == pws4 + i2 * nwb + i2); +#endif +} + +/* { dg-final { scan-tree-dump-not "abort" "optimized" } } */
On Fri, Oct 5, 2018 at 5:47 PM Martin Sebor <msebor@gmail.com> wrote: > > David, > > Attached is a patch to conditionalize the memchr-1.c test > to pass even with 2-byte wchar_t's. It also adds a compile > only test to verify memchr with -fnarrow-wchar. I verified > the changes on LE x86_64-linux and BE powerpc64-linux but > if you could confirm they also work on AIX that would be > great. With the patch, the memchr failures on AIX are fixed. Thanks, David
On 10/06/2018 04:13 PM, David Edelsohn wrote: > On Fri, Oct 5, 2018 at 5:47 PM Martin Sebor <msebor@gmail.com> wrote: >> >> David, >> >> Attached is a patch to conditionalize the memchr-1.c test >> to pass even with 2-byte wchar_t's. It also adds a compile >> only test to verify memchr with -fnarrow-wchar. I verified >> the changes on LE x86_64-linux and BE powerpc64-linux but >> if you could confirm they also work on AIX that would be >> great. > > With the patch, the memchr failures on AIX are fixed. Thanks! I've checked it in as r265020. Martin
Index: memchr-1.c =================================================================== --- memchr-1.c (revision 264869) +++ memchr-1.c (working copy) @@ -106,6 +106,7 @@ A (memchr (&s5_3[1][i0], 0, sizeof s5_3[1] - i0) == &s5_3[1][4]); } +#if !defined(_AIX) || defined(__64BIT__) static const wchar_t wc = L'1'; static const wchar_t ws1[] = L"1"; static const wchar_t ws4[] = L"\x00123456\x12005678\x12340078\x12345600"; @@ -144,10 +145,13 @@ A (memchr (&ws4[3], 0, nb - 3 * nwb) == pws4 + 3 * nwb + 3); #endif } +#endif int main () { test_narrow (); +#if !defined(_AIX) || defined(__64BIT__) test_wide (); +#endif }