From f2d52e0042fb5027ae6f8af48e39071648c6b65e Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 25 Jul 2019 19:03:00 +0000 Subject: [PATCH] re PR tree-optimization/91183 (strlen of a strcpy result with a conditional source not folded) PR tree-optimization/91183 PR tree-optimization/86688 gcc/testsuite/ChangeLog: * gcc.dg/strlenopt-70.c: Fix bugs. * gcc.dg/strlenopt-71.c: Same. * gcc.dg/strlenopt-72.c: Same. From-SVN: r273812 --- gcc/testsuite/ChangeLog | 8 + gcc/testsuite/gcc.dg/strlenopt-70.c | 438 +++++++++++++++------------- gcc/testsuite/gcc.dg/strlenopt-71.c | 91 +++--- gcc/testsuite/gcc.dg/strlenopt-72.c | 7 +- 4 files changed, 300 insertions(+), 244 deletions(-) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0ff528b87b3..b395a9afff1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2019-07-25 Martin Sebor + + PR tree-optimization/91183 + PR tree-optimization/86688 + * gcc.dg/strlenopt-70.c: Fix bugs. + * gcc.dg/strlenopt-71.c: Same. + * gcc.dg/strlenopt-72.c: Same. + 2019-07-25 Vladimir Makarov PR rtl-optimization/91223 diff --git a/gcc/testsuite/gcc.dg/strlenopt-70.c b/gcc/testsuite/gcc.dg/strlenopt-70.c index 2dc42d6e26e..97ba1408f10 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-70.c +++ b/gcc/testsuite/gcc.dg/strlenopt-70.c @@ -11,10 +11,10 @@ #define CHAR_BIT __CHAR_BIT__ -typedef __INT16_TYPE__ int16_t; -typedef __INT32_TYPE__ int32_t; -typedef __INT64_TYPE__ int64_t; -typedef __UINT64_TYPE__ uint64_t; +typedef __UINT16_TYPE__ uint16_t; +typedef __UINT32_TYPE__ uint32_t; +typedef __UINT64_TYPE__ uint64_t; +typedef __UINT64_TYPE__ uint64_t; #define CAT(x, y) x ## y #define CONCAT(x, y) CAT (x, y) @@ -43,16 +43,6 @@ typedef __UINT64_TYPE__ uint64_t; ELIM (!(strlen (a) expect)); \ } while (0) -/* Same as above but the assignment consisting of the two quadwords - QW1 and QW2 to support int128_t. */ -#define T2(init, type, off, qw0, qw1, expect) do { \ - char a[32]; \ - memcpy (a, init ? init : "", init ? sizeof init - 1: 0); \ - type assign = ((type)qw0 << (sizeof (type) * CHAR_BIT / 2)) | (type)qw1; \ - *(type*)(a + off) = assign; \ - ELIM (!(strlen (a) expect)); \ - } while (0) - /* Same as T but works around the optimizer dropping the initializing store before the assignment and defeating the strlen optimization. */ #define TX(init, type, off, assign, expect) do { \ @@ -63,231 +53,273 @@ typedef __UINT64_TYPE__ uint64_t; ELIM (!(strlen (a) expect)); \ } while (0) +/* Evaluates to an element at index I of the literal S padded with nuls + on the right. */ +#define ELT(s, i) ((s "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")[i]) #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -# define I16(s) ((s[0] << 8) + s[1]) -# define I32(s) ((s[0] << 24) + (s[1] << 16) + (s[2] << 8) + s[3]) -# define I64(s) \ - (((uint64_t)s[0] << 56) \ - + ((uint64_t)s[1] << 48) \ - + ((uint64_t)s[2] << 40) \ - + ((uint64_t)s[3] << 32) \ - + ((uint64_t)s[4] << 24) \ - + ((uint64_t)s[5] << 16) \ - + ((uint64_t)s[6] << 8) \ - + s[7]) +/* Form a big-endian 16, 32, 64, and 128-byte integer from a string. */ +# define I16(s) (((uint16_t)ELT (s, 0) << 8) + (uint16_t)ELT (s, 1)) +# define I32(s) \ + (((uint32_t)ELT (s, 0) << 24) \ + + ((uint32_t)ELT (s, 1) << 16) \ + + ((uint32_t)ELT (s, 2) << 8) \ + + (uint32_t)ELT (s, 3)) +# define I64(s) \ + (((uint64_t)ELT (s, 0) << 56) \ + + ((uint64_t)ELT (s, 1) << 48) \ + + ((uint64_t)ELT (s, 2) << 40) \ + + ((uint64_t)ELT (s, 3) << 32) \ + + ((uint64_t)ELT (s, 4) << 24) \ + + ((uint64_t)ELT (s, 5) << 16) \ + + ((uint64_t)ELT (s, 6) << 8) \ + + ELT (s, 7)) +# define I128(s) \ + (((uint128_t)ELT (s, 0) << (64 + 56)) \ + + ((uint128_t)ELT (s, 1) << (64 + 48)) \ + + ((uint128_t)ELT (s, 2) << (64 + 40)) \ + + ((uint128_t)ELT (s, 3) << (64 + 32)) \ + + ((uint128_t)ELT (s, 4) << (64 + 24)) \ + + ((uint128_t)ELT (s, 5) << (64 + 16)) \ + + ((uint128_t)ELT (s, 6) << (64 + 8)) \ + + ((uint128_t)ELT (s, 7) << 64) \ + + ((uint128_t)ELT (s, 8) << 56) \ + + ((uint128_t)ELT (s, 9) << 48) \ + + ((uint128_t)ELT (s, 10) << 40) \ + + ((uint128_t)ELT (s, 11) << 32) \ + + ((uint128_t)ELT (s, 12) << 24) \ + + ((uint128_t)ELT (s, 13) << 16) \ + + ((uint128_t)ELT (s, 14) << 8) \ + + (uint128_t)ELT (s, 15)) + #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -# define I16(s) ((s[1] << 8) + s[0]) -# define I32(s) ((s[3] << 24) + (s[2] << 16) + (s[1] << 8) + s[0]) -# define I64(s) \ - (((uint64_t)s[7] << 56) \ - + ((uint64_t)s[6] << 48) \ - + ((uint64_t)s[5] << 40) \ - + ((uint64_t)s[4] << 32) \ - + ((uint64_t)s[3] << 24) \ - + ((uint64_t)s[2] << 16) \ - + ((uint64_t)s[1] << 8) \ - + s[0]) +/* Form a little-endian 16, 32, 64, and 128-byte integer from a string. */ +# define I16(s) (((uint16_t)ELT (s, 1) << 8) + (uint16_t)ELT (s, 0)) +# define I32(s) \ + (((uint32_t)ELT (s, 3) << 24) \ + + ((uint32_t)ELT (s, 2) << 16) \ + + ((uint32_t)ELT (s, 1) << 8) \ + + (uint32_t)ELT (s, 0)) +# define I64(s) \ + (((uint64_t)ELT (s, 7) << 56) \ + + ((uint64_t)ELT (s, 6) << 48) \ + + ((uint64_t)ELT (s, 5) << 40) \ + + ((uint64_t)ELT (s, 4) << 32) \ + + ((uint64_t)ELT (s, 3) << 24) \ + + ((uint64_t)ELT (s, 2) << 16) \ + + ((uint64_t)ELT (s, 1) << 8) \ + + ELT (s, 0)) +# define I128(s) \ + (((uint128_t)ELT (s, 15) << (64 + 56)) \ + + ((uint128_t)ELT (s, 14) << (64 + 48)) \ + + ((uint128_t)ELT (s, 13) << (64 + 40)) \ + + ((uint128_t)ELT (s, 12) << (64 + 32)) \ + + ((uint128_t)ELT (s, 11) << (64 + 24)) \ + + ((uint128_t)ELT (s, 10) << (64 + 16)) \ + + ((uint128_t)ELT (s, 9) << (64 + 8)) \ + + ((uint128_t)ELT (s, 8) << 64) \ + + ((uint128_t)ELT (s, 7) << 56) \ + + ((uint128_t)ELT (s, 6) << 48) \ + + ((uint128_t)ELT (s, 5) << 40) \ + + ((uint128_t)ELT (s, 4) << 32) \ + + ((uint128_t)ELT (s, 3) << 24) \ + + ((uint128_t)ELT (s, 2) << 16) \ + + ((uint128_t)ELT (s, 1) << 8) \ + + (uint128_t)ELT (s, 0)) #endif #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ void store_16bit_be (void) { - T ("xxx", int16_t, 0, 0x0001, == 0); - T ("xxx", int16_t, 0, 0x0010, == 0); - T ("xxx", int16_t, 0, 0x0011, == 0); - T ("xxx", int16_t, 0, 0x0100, == 1); - T ("xxx", int16_t, 0, 0x1000, == 1); - T ("xxx", int16_t, 0, 0x1100, == 1); + T ("xxx", uint16_t, 0, 0x0001, == 0); + T ("xxx", uint16_t, 0, 0x0010, == 0); + T ("xxx", uint16_t, 0, 0x0011, == 0); + T ("xxx", uint16_t, 0, 0x0100, == 1); + T ("xxx", uint16_t, 0, 0x1000, == 1); + T ("xxx", uint16_t, 0, 0x1100, == 1); } #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ void store_16bit_le (int i) { - int16_t x0000 = I16 ("\0\0"); - int16_t x0001 = 0x0001; - int16_t x0010 = 0x0010; - int16_t x0011 = 0x0011; - int16_t x0100 = 0x0100; - int16_t x1000 = 0x1000; - int16_t x1100 = 0x1100; - - T (0, int16_t, 0, x0000, == 0); - T ("x", int16_t, 0, x0000, == 0); - T ("xx", int16_t, 0, x0000, == 0); - T ("xxxx", int16_t, 0, x0000, == 0); - T (0, int16_t, 0, x0001, == 1); - T ("\0\0\0", int16_t, 0, x0001, == 1); - T (0, int16_t, 0, x0010, == 1); - T ("x\0\0", int16_t, 0, x0010, == 1); - T (0, int16_t, 0, x0011, == 1); - T ("xx\0", int16_t, 0, x0011, == 1); - T (0, int16_t, 0, x0100, == 0); - T ("\0\0\0", int16_t, 0, x0100, == 0); - T (0, int16_t, 0, x1000, == 0); - T ("x\0\0", int16_t, 0, x1000, == 0); - T (0, int16_t, 0, x1100, == 0); - T ("xx\0", int16_t, 0, x1100, == 0); + uint16_t x0000 = I16 ("\0\0"); + uint16_t x0001 = 0x0001; + uint16_t x0010 = 0x0010; + uint16_t x0011 = 0x0011; + uint16_t x0100 = 0x0100; + uint16_t x1000 = 0x1000; + uint16_t x1100 = 0x1100; + + T (0, uint16_t, 0, x0000, == 0); + T ("x", uint16_t, 0, x0000, == 0); + T ("xx", uint16_t, 0, x0000, == 0); + T ("xxxx", uint16_t, 0, x0000, == 0); + T (0, uint16_t, 0, x0001, == 1); + T ("\0\0\0", uint16_t, 0, x0001, == 1); + T (0, uint16_t, 0, x0010, == 1); + T ("x\0\0", uint16_t, 0, x0010, == 1); + T (0, uint16_t, 0, x0011, == 1); + T ("xx\0", uint16_t, 0, x0011, == 1); + T (0, uint16_t, 0, x0100, == 0); + T ("\0\0\0", uint16_t, 0, x0100, == 0); + T (0, uint16_t, 0, x1000, == 0); + T ("x\0\0", uint16_t, 0, x1000, == 0); + T (0, uint16_t, 0, x1100, == 0); + T ("xx\0", uint16_t, 0, x1100, == 0); // FIXME: This fails because of the next test but succeeds on its own. - // T (0, int16_t, 0, i ? x0001 : x0010, == 1); - T ("xxx", int16_t, 0, i ? x0100 : x1100, == 0); + // T (0, uint16_t, 0, i ? x0001 : x0010, == 1); + T ("xxx", uint16_t, 0, i ? x0100 : x1100, == 0); } #endif void store_32bit (volatile int i) { - T (0, int32_t, 0, 0, == 0); - T ("x", int32_t, 0, 0, == 0); - T ("xx", int32_t, 0, 0, == 0); - T ("xxx", int32_t, 0, 0, == 0); - T ("xxxx", int32_t, 0, 0, == 0); - - T ("\0", int32_t, 1, 0, == 0); - T ("x", int32_t, 1, 0, == 1); - T ("xx", int32_t, 2, 0, == 2); - T ("xxx", int32_t, 3, 0, == 3); - - T ("xxx", int32_t, 0, I32 ("\01\0\0\0"), == 1); - T ("xxx", int32_t, 0, I32 ("\0\01\0\0"), == 0); - T ("xxx", int32_t, 0, I32 ("\0\0\01\0"), == 0); - T ("xxx", int32_t, 0, I32 ("\0\0\0\01"), == 0); - - T ("xxx", int32_t, 0, I32 ("\1\2\0\0"), == 2); - T ("xxx", int32_t, 0, I32 ("\0\1\2\0"), == 0); - T ("xxx", int32_t, 0, I32 ("\0\0\1\2"), == 0); - - T ("xxx", int32_t, 0, I32 ("\1\2\3\0"), == 3); - T ("xxx", int32_t, 0, I32 ("\0\1\2\3"), == 0); - - int32_t x00332211 = I32 ("123\0"); - int32_t x00002211 = I32 ("12\0\0"); - int32_t x00000011 = I32 ("1\0\0\0"); - - T ("xxxx", int32_t, 0, i ? x00332211 : x00002211, <= 3); - T ("xxxx", int32_t, 0, i ? x00332211 : x00002211, >= 2); - T ("xxxx", int32_t, 0, i ? x00332211 : x00000011, <= 3); - T ("xxxx", int32_t, 0, i ? x00332211 : x00000011, >= 1); - - TX ("abcde", int32_t, 0, i ? I32 ("1234") : I32 ("1235"), == 5); - TX ("abcde", int32_t, 1, i ? I32 ("1234") : I32 ("1235"), == 5); - - TX ("abcdef", int32_t, 0, i ? I32 ("1235") : I32 ("1234"), == 6); - TX ("abcdef", int32_t, 1, i ? I32 ("1235") : I32 ("1234"), == 6); - TX ("abcdef", int32_t, 2, i ? I32 ("1235") : I32 ("1234"), == 6); - TX ("abcdef", int32_t, 3, i ? I32 ("124\0") : I32 ("123\0"), == 6); - TX ("abcdef", int32_t, 3, i ? I32 ("12\0\0") : I32 ("13\0\0"), == 5); - - TX ("abcdef", int32_t, 3, i ? I32 ("12\0\0") : I32 ("123\0"), >= 5); - TX ("abcdef", int32_t, 3, i ? I32 ("12\0\0") : I32 ("123\0"), < 7); + T (0, uint32_t, 0, 0, == 0); + T ("x", uint32_t, 0, 0, == 0); + T ("xx", uint32_t, 0, 0, == 0); + T ("xxx", uint32_t, 0, 0, == 0); + T ("xxxx", uint32_t, 0, 0, == 0); + + T ("\0", uint32_t, 1, 0, == 0); + T ("x", uint32_t, 1, 0, == 1); + T ("xx", uint32_t, 2, 0, == 2); + T ("xxx", uint32_t, 3, 0, == 3); + + T ("xxx", uint32_t, 0, I32 ("\1\0\0\0"), == 1); + T ("xxx", uint32_t, 0, I32 ("\0\1\0\0"), == 0); + T ("xxx", uint32_t, 0, I32 ("\0\0\1\0"), == 0); + T ("xxx", uint32_t, 0, I32 ("\0\0\0\1"), == 0); + + T ("xxx", uint32_t, 0, I32 ("\1\2\0\0"), == 2); + T ("xxx", uint32_t, 0, I32 ("\0\1\2\0"), == 0); + T ("xxx", uint32_t, 0, I32 ("\0\0\1\2"), == 0); + + T ("xxx", uint32_t, 0, I32 ("\1\2\3\0"), == 3); + T ("xxx", uint32_t, 0, I32 ("\0\1\2\3"), == 0); + + uint32_t x00332211 = I32 ("123\0"); + uint32_t x00002211 = I32 ("12\0\0"); + uint32_t x00000011 = I32 ("1\0\0\0"); + + T ("xxxx", uint32_t, 0, i ? x00332211 : x00002211, <= 3); + T ("xxxx", uint32_t, 0, i ? x00332211 : x00002211, >= 2); + T ("xxxx", uint32_t, 0, i ? x00332211 : x00000011, <= 3); + T ("xxxx", uint32_t, 0, i ? x00332211 : x00000011, >= 1); + + TX ("abcde", uint32_t, 0, i ? I32 ("1234") : I32 ("1235"), == 5); + TX ("abcde", uint32_t, 1, i ? I32 ("1234") : I32 ("1235"), == 5); + + TX ("abcdef", uint32_t, 0, i ? I32 ("1235") : I32 ("1234"), == 6); + TX ("abcdef", uint32_t, 1, i ? I32 ("1235") : I32 ("1234"), == 6); + TX ("abcdef", uint32_t, 2, i ? I32 ("1235") : I32 ("1234"), == 6); + TX ("abcdef", uint32_t, 3, i ? I32 ("124\0") : I32 ("123\0"), == 6); + TX ("abcdef", uint32_t, 3, i ? I32 ("12\0\0") : I32 ("13\0\0"), == 5); + + TX ("abcdef", uint32_t, 3, i ? I32 ("12\0\0") : I32 ("123\0"), >= 5); + TX ("abcdef", uint32_t, 3, i ? I32 ("12\0\0") : I32 ("123\0"), < 7); } void store_64bit (int i) { - T2 ("xxxxxxx", int64_t, 0, 0, I32 ("\1\0\0\0"), == 1); - T2 ("xxxxxxx", int64_t, 0, 0, I32 ("\0\1\0\0"), == 0); - T2 ("xxxxxxx", int64_t, 0, 0, I32 ("\0\0\1\0"), == 0); - T2 ("xxxxxxx", int64_t, 0, 0, I32 ("\0\00\0\1"), == 0); - T2 ("xxxxxxx", int64_t, 0, I32 ("\1\0\0\0"), 0, == 0); - T2 ("xxxxxxx", int64_t, 0, I32 ("\0\1\0\0"), 0, == 0); - T2 ("xxxxxxx", int64_t, 0, I32 ("\0\0\1\0"), 0, == 0); - T2 ("xxxxxxx", int64_t, 0, I32 ("\0\0\0\1"), 0, == 0); - - T2 ("xxxxxxx", int64_t, 0, 0, I32 ("\1\2\0\0"), == 2); - T2 ("xxxxxxx", int64_t, 0, 0, I32 ("\0\1\2\0"), == 0); - T2 ("xxxxxxx", int64_t, 0, 0, I32 ("\0\0\1\2"), == 0); - - T2 ("xxxxxxx", int64_t, 0, 0, I32 ("\1\2\3\0"), == 3); - T2 ("xxxxxxx", int64_t, 0, 0, I32 ("\0\1\2\3"), == 0); - - T2 ("xxxxxxx", int64_t, 0, 0, I32 ("\1\2\3\4"), == 4); - T2 ("xxxxxxx", int64_t, 0, I32 ("\5\0\0\0"), I32 ("\1\2\3\4"), == 5); - T2 ("xxxxxxx", int64_t, 0, I32 ("\5\6\0\0"), I32 ("\1\2\3\4"), == 6); - T2 ("xxxxxxx", int64_t, 0, I32 ("\5\6\7\0"), I32 ("\1\2\3\4"), == 7); - - int64_t x7777777 = I64 ("\7\7\7\7\7\7\7"); - int64_t x666666 = I64 ("\6\6\6\6\6\6\0"); - int64_t x4444 = I64 ("\4\4\4\4\0\0\0"); - int64_t x3333 = I64 ("\3\3\3\3\0\0\0"); - int64_t x1 = I64 ("\1\0\0\0\0\0\0"); - - T ("x\0xxxxxx", int64_t, 0, i ? x7777777 : x666666, <= 7); - T ("xx\0xxxxx", int64_t, 0, i ? x7777777 : x666666, >= 6); - T ("xxx\0xxxx", int64_t, 0, i ? x666666 : x1, <= 6); - T ("xxxx\0xxx", int64_t, 0, i ? x666666 : x1, >= 1); - T ("xxxxxx\0x", int64_t, 0, i ? x4444 : x3333, == 4); + T ("xxxxxxx", uint64_t, 0, I64 ("\1\0\0\0\0\0\0\0\0"), == 1); + T ("xxxxxxx", uint64_t, 0, I64 ("\0\1\0\0\0\0\0\0\0"), == 0); + T ("xxxxxxx", uint64_t, 0, I64 ("\0\0\1\0\0\0\0\0\0"), == 0); + T ("xxxxxxx", uint64_t, 0, I64 ("\0\0\0\1\0\0\0\0\0"), == 0); + T ("xxxxxxx", uint64_t, 0, I64 ("\0\0\0\0\1\0\0\0\0"), == 0); + T ("xxxxxxx", uint64_t, 0, I64 ("\0\0\0\0\0\1\0\0\0"), == 0); + T ("xxxxxxx", uint64_t, 0, I64 ("\0\0\0\0\0\0\1\0\0"), == 0); + T ("xxxxxxx", uint64_t, 0, I64 ("\0\0\0\0\0\0\0\1\0"), == 0); + + T ("xxxxxxx", uint64_t, 0, I64 ("\1\2\0\0\0\0\0\0\0"), == 2); + T ("xxxxxxx", uint64_t, 0, I64 ("\0\1\2\0\0\0\0\0\0"), == 0); + T ("xxxxxxx", uint64_t, 0, I64 ("\0\0\1\2\0\0\0\0\0"), == 0); + + T ("xxxxxxx", uint64_t, 0, I64 ("\1\2\3\0\0\0\0\0\0"), == 3); + T ("xxxxxxx", uint64_t, 0, I64 ("\0\1\2\3\0\0\0\0\0"), == 0); + + T ("xxxxxxx", uint64_t, 0, I64 ("\1\2\3\4\0\0\0\0\0"), == 4); + T ("xxxxxxx", uint64_t, 0, I64 ("\1\2\3\4\5\0\0\0\0"), == 5); + T ("xxxxxxx", uint64_t, 0, I64 ("\1\2\3\4\5\6\0\0\0"), == 6); + T ("xxxxxxx", uint64_t, 0, I64 ("\1\2\3\4\5\6\7\0\0"), == 7); + + uint64_t x7777777 = I64 ("\7\7\7\7\7\7\7"); + uint64_t x666666 = I64 ("\6\6\6\6\6\6\0"); + uint64_t x4444 = I64 ("\4\4\4\4\0\0\0"); + uint64_t x3333 = I64 ("\3\3\3\3\0\0\0"); + uint64_t x1 = I64 ("\1\0\0\0\0\0\0"); + + T ("x\0xxxxxx", uint64_t, 0, i ? x7777777 : x666666, <= 7); + T ("xx\0xxxxx", uint64_t, 0, i ? x7777777 : x666666, >= 6); + T ("xxx\0xxxx", uint64_t, 0, i ? x666666 : x1, <= 6); + T ("xxxx\0xxx", uint64_t, 0, i ? x666666 : x1, >= 1); + T ("xxxxxx\0x", uint64_t, 0, i ? x4444 : x3333, == 4); } -#ifdef __uint128_t +#if __SIZEOF_INT128__ typedef __uint128_t uint128_t; void store_128bit (void) { - uint64_t x1 = I64 ("\1\0\0\0\0\0\0\0"); - uint64_t x01 = I64 ("\0\1\0\0\0\0\0\0"); - uint64_t x001 = I64 ("\0\0\1\0\0\0\0\0"); - uint64_t x0001 = I64 ("\0\0\0\1\0\0\0\0"); - uint64_t x00001 = I64 ("\0\0\0\0\1\0\0\0"); - uint64_t x000001 = I64 ("\0\0\0\0\0\1\0\0"); - uint64_t x0000001 = I64 ("\0\0\0\0\0\0\1\0"); - uint64_t x00000001 = I64 ("\0\0\0\0\0\0\0\1"); - - T2 ("xxxxxxx", uint128_t, 0, 0, x1, == 1); - T2 ("xxxxxxx", uint128_t, 0, 0, x01, == 0); - T2 ("xxxxxxx", uint128_t, 0, 0, x001, == 0); - T2 ("xxxxxxx", uint128_t, 0, 0, x0001, == 0); - T2 ("xxxxxxx", uint128_t, 0, 0, x00001, == 0); - T2 ("xxxxxxx", uint128_t, 0, 0, x000001, == 0); - T2 ("xxxxxxx", uint128_t, 0, 0, x0000001, == 0); - T2 ("xxxxxxx", uint128_t, 0, 0, x00000001, == 0); - - T2 ("xxxxxxx", uint128_t, 0, x1, 0, == 0); - T2 ("xxxxxxx", uint128_t, 0, x01, 0, == 0); - T2 ("xxxxxxx", uint128_t, 0, x001, 0, == 0); - T2 ("xxxxxxx", uint128_t, 0, x0001, 0, == 0); - T2 ("xxxxxxx", uint128_t, 0, x00001, 0, == 0); - T2 ("xxxxxxx", uint128_t, 0, x000001, 0, == 0); - T2 ("xxxxxxx", uint128_t, 0, x0000001, 0, == 0); - T2 ("xxxxxxx", uint128_t, 0, x00000001, 0, == 0); - - T2 ("xxxxxxx", uint128_t, 0, 0, I64 ("\2\1\0\0\0\0\0\0"), == 2); - T2 ("xxxxxxx", uint128_t, 0, 0, I64 ("\0\2\1\0\0\0\0\0"), == 0); - - T2 ("xxxxxxx", uint128_t, 0, 0, I64 ("\3\2\1\0\0\0\0\0"), == 3); - T2 ("xxxxxxx", uint128_t, 0, 0, I64 ("\0\3\2\1\0\0\0\0"), == 0); - - uint64_t x4321 = I64 ("\4\3\2\1\0\0\0\0"); - uint64_t x54321 = I64 ("\5\4\3\2\1\0\0\0"); - uint64_t x654321 = I64 ("\6\5\4\3\2\1\0\0"); - uint64_t x7654321 = I64 ("\7\6\5\4\3\2\1\0"); - uint64_t x87654321 = I64 ("8\7\6\5\4\3\2\1"); - uint64_t x9 = I64 ("9\0\0\0\0\0\0\0"); - uint64_t xa9 = I64 ("a9\0\0\0\0\0\0"); - uint64_t xba9 = I64 ("ba9\0\0\0\0\0\0"); - uint64_t xcba9 = I64 ("cba9\0\0\0\0\0"); - uint64_t xdcba9 = I64 ("dcba9\0\0\0\0"); - uint64_t xedcba9 = I64 ("edcba9\0\0\0\0"); - uint64_t xfedcba9 = I64 ("fedcba9\0\0\0"); - - T2 (0, uint128_t, 0, 0, x4321, == 4); - T2 (0, uint128_t, 0, 0, x54321, == 5); - T2 (0, uint128_t, 0, 0, x654321, == 6); - T2 (0, uint128_t, 0, 0, x7654321, == 7); - T2 (0, uint128_t, 0, 0, x87654321, == 8); - T2 (0, uint128_t, 0, x9, x87654321, == 9); - T2 (0, uint128_t, 0, xa9, x87654321, == 10); - T2 (0, uint128_t, 0, xba9, x87654321, == 11); - T2 (0, uint128_t, 0, xcba9, x87654321, == 12); - T2 (0, uint128_t, 0, xdcba9, x87654321, == 13); - T2 (0, uint128_t, 0, xedcba9, x87654321, == 14); - T2 (0, uint128_t, 0, xfedcba9, x87654321, == 15); + uint128_t x1 = I128 ("\1"); + uint128_t x1z1 = I128 ("\0\1"); + uint128_t x2z1 = I128 ("\0\0\1"); + uint128_t x3z1 = I128 ("\0\0\0\1"); + uint128_t x4z1 = I128 ("\0\0\0\0\1"); + uint128_t x5z1 = I128 ("\0\0\0\0\0\1"); + uint128_t x6z1 = I128 ("\0\0\0\0\0\0\1"); + uint128_t x7z1 = I128 ("\0\0\0\0\0\0\0\1"); + uint128_t x8z1 = I128 ("\0\0\0\0\0\0\0\0\1"); + uint128_t x9z1 = I128 ("\0\0\0\0\0\0\0\0\0\1"); + uint128_t x10z1 = I128 ("\0\0\0\0\0\0\0\0\0\0\1"); + uint128_t x11z1 = I128 ("\0\0\0\0\0\0\0\0\0\0\0\1"); + uint128_t x12z1 = I128 ("\0\0\0\0\0\0\0\0\0\0\0\0\1"); + uint128_t x13z1 = I128 ("\0\0\0\0\0\0\0\0\0\0\0\0\0\1"); + uint128_t x14z1 = I128 ("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1"); + uint128_t x15z1 = I128 ("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1"); + + T ("xxxxxxx", uint128_t, 0, x1, == 1); + T ("xxxxxxx", uint128_t, 0, x1z1, == 0); + T ("xxxxxxx", uint128_t, 0, x2z1, == 0); + T ("xxxxxxx", uint128_t, 0, x3z1, == 0); + T ("xxxxxxx", uint128_t, 0, x4z1, == 0); + T ("xxxxxxx", uint128_t, 0, x5z1, == 0); + T ("xxxxxxx", uint128_t, 0, x6z1, == 0); + T ("xxxxxxx", uint128_t, 0, x7z1, == 0); + T ("xxxxxxx", uint128_t, 0, x8z1, == 0); + T ("xxxxxxx", uint128_t, 0, x9z1, == 0); + T ("xxxxxxx", uint128_t, 0, x10z1, == 0); + T ("xxxxxxx", uint128_t, 0, x11z1, == 0); + T ("xxxxxxx", uint128_t, 0, x12z1, == 0); + T ("xxxxxxx", uint128_t, 0, x13z1, == 0); + T ("xxxxxxx", uint128_t, 0, x14z1, == 0); + T ("xxxxxxx", uint128_t, 0, x15z1, == 0); + + T ("xxxxxxx", uint128_t, 0, I128 ("\2\1"), == 2); + T ("xxxxxxx", uint128_t, 0, I128 ("\0\2\1"), == 0); + + T ("xxxxxxx", uint128_t, 0, I128 ("\3\2\1"), == 3); + T ("xxxxxxx", uint128_t, 0, I128 ("\0\3\2\1"), == 0); + + T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4"), == 4); + T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5"), == 5); + T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5\6"), == 6); + T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5\6\7"), == 7); + T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5\6\7\10"), == 8); + T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5\6\7\10\11"), == 9); + T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5\6\7\10\11\12"), == 10); + T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5\6\7\10\11\12\13"), == 11); + T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5\6\7\10\11\12\13\14"), == 12); + T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5\6\7\10\11\12\13\14\15"), == 13); + T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5\6\7\10\11\12\13\14\15\16"), == 14); + T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17"), == 15); } -#endif // __uint128_t +#endif // __SIZEOF_INT128__ /* { dg-final { scan-tree-dump-times "strlen" 0 "optimized" } } { dg-final { scan-tree-dump-times "_not_eliminated_" 0 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-71.c b/gcc/testsuite/gcc.dg/strlenopt-71.c index 19055198142..fd4c4a9e1f6 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-71.c +++ b/gcc/testsuite/gcc.dg/strlenopt-71.c @@ -8,8 +8,8 @@ #define CHAR_BIT __CHAR_BIT__ -typedef __INT16_TYPE__ int16_t; -typedef __INT32_TYPE__ int32_t; +typedef __UINT16_TYPE__ uint16_t; +typedef __UINT32_TYPE__ uint32_t; #define NOIPA __attribute__ ((noclone, noinline, noipa)) @@ -40,12 +40,23 @@ NOIPA void terminate (void) } \ } while (0) + +#define ELT(s, i) ((s "\0\0\0\0")[i]) + #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -# define I16(s) ((s[0] << 8) + s[1]) -# define I32(s) ((s[0] << 24) + (s[1] << 16) + (s[2] << 8) + s[3]) +# define I16(s) (((uint16_t)ELT (s, 0) << 8) + (uint16_t)ELT (s, 1)) +# define I32(s) \ + (((uint32_t)ELT (s, 0) << 24) \ + + ((uint32_t)ELT (s, 1) << 16) \ + + ((uint32_t)ELT (s, 2) << 8) \ + + (uint32_t)ELT (s, 3)) #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -# define I16(s) ((s[1] << 8) + s[0]) -# define I32(s) ((s[3] << 24) + (s[2] << 16) + (s[1] << 8) + s[0]) +# define I16(s) (((uint16_t)ELT (s, 1) << 8) + (uint16_t)ELT (s, 0)) +# define I32(s) \ + (((uint32_t)ELT (s, 3) << 24) \ + + ((uint32_t)ELT (s, 2) << 16) \ + + ((uint32_t)ELT (s, 1) << 8) \ + + (uint32_t)ELT (s, 0)) #endif char a[32]; @@ -53,21 +64,21 @@ char a[32]; NOIPA void i16_1 (void) { - *(int16_t*)a = I16 ("12"); - *(int16_t*)(a + 2) = I16 ("3"); + *(uint16_t*)a = I16 ("12"); + *(uint16_t*)(a + 2) = I16 ("3"); VERIFY (a, "123"); - *(int16_t*)(a + 1) = I16 ("23"); + *(uint16_t*)(a + 1) = I16 ("23"); VERIFY (a, "123"); - *(int16_t*)(a) = I16 ("12"); + *(uint16_t*)(a) = I16 ("12"); VERIFY (a, "123"); - *(int16_t*)(a + 1) = I16 ("2"); + *(uint16_t*)(a + 1) = I16 ("2"); VERIFY (a, "12"); - *(int16_t*)(a + 3) = I16 ("45"); - *(int16_t*)(a + 2) = I16 ("34"); + *(uint16_t*)(a + 3) = I16 ("45"); + *(uint16_t*)(a + 2) = I16 ("34"); VERIFY (a, "12345"); } @@ -77,19 +88,19 @@ i16_2 (void) strcpy (a, "12"); strcat (a, "34"); - *(int16_t*)a = I16 ("12"); + *(uint16_t*)a = I16 ("12"); VERIFY (a, "1234"); - *(int16_t*)(a + 1) = I16 ("12"); + *(uint16_t*)(a + 1) = I16 ("12"); VERIFY (a, "1124"); - *(int16_t*)(a + 2) = I16 ("12"); + *(uint16_t*)(a + 2) = I16 ("12"); VERIFY (a, "1112"); - *(int16_t*)(a + 3) = I16 ("12"); + *(uint16_t*)(a + 3) = I16 ("12"); VERIFY (a, "11112"); - *(int16_t*)(a + 4) = I16 ("12"); + *(uint16_t*)(a + 4) = I16 ("12"); VERIFY (a, "111112"); } @@ -97,10 +108,10 @@ i16_2 (void) NOIPA void i32_1 (void) { - *(int32_t*)a = I32 ("1234"); + *(uint32_t*)a = I32 ("1234"); VERIFY (a, "1234"); - *(int32_t*)(a + 1) = I32 ("2345"); + *(uint32_t*)(a + 1) = I32 ("2345"); VERIFY (a, "12345"); } @@ -110,22 +121,22 @@ i32_2 (void) strcpy (a, "12"); strcat (a, "34"); - *(int32_t*)a = I32 ("1234"); + *(uint32_t*)a = I32 ("1234"); VERIFY (a, "1234"); - *(int32_t*)(a + 4) = I32 ("567"); + *(uint32_t*)(a + 4) = I32 ("567"); VERIFY (a, "1234567"); - *(int32_t*)(a + 7) = I32 ("89\0"); + *(uint32_t*)(a + 7) = I32 ("89\0"); VERIFY (a, "123456789"); - *(int32_t*)(a + 3) = I32 ("4567"); + *(uint32_t*)(a + 3) = I32 ("4567"); VERIFY (a, "123456789"); - *(int32_t*)(a + 2) = I32 ("3456"); + *(uint32_t*)(a + 2) = I32 ("3456"); VERIFY (a, "123456789"); - *(int32_t*)(a + 1) = I32 ("2345"); + *(uint32_t*)(a + 1) = I32 ("2345"); VERIFY (a, "123456789"); } @@ -136,25 +147,25 @@ i32_3 (void) strcpy (a, "1234"); strcat (a, "5678"); - *(int32_t*)a = I32 ("1234"); + *(uint32_t*)a = I32 ("1234"); VERIFY (a, "12345678"); - *(int32_t*)(a + 1) = I32 ("234"); + *(uint32_t*)(a + 1) = I32 ("234"); VERIFY (a, "1234"); - *(int32_t*)(a + 2) = I32 ("3456"); + *(uint32_t*)(a + 2) = I32 ("3456"); VERIFY (a, "12345678"); - *(int32_t*)(a + 3) = I32 ("4567"); + *(uint32_t*)(a + 3) = I32 ("4567"); VERIFY (a, "12345678"); - *(int32_t*)(a + 4) = I32 ("5678"); + *(uint32_t*)(a + 4) = I32 ("5678"); VERIFY (a, "12345678"); - *(int32_t*)(a + 5) = I32 ("6789"); + *(uint32_t*)(a + 5) = I32 ("6789"); VERIFY (a, "123456789"); - *(int32_t*)(a + 6) = I32 ("789A"); + *(uint32_t*)(a + 6) = I32 ("789A"); VERIFY (a, "123456789A"); } @@ -166,25 +177,25 @@ i32_4 (void) strcpy (a, "1234"); strcat (a, "5678"); - *(int32_t*)a = vzero ? I32 ("1\0\0\0") : I32 ("1234"); + *(uint32_t*)a = vzero ? I32 ("1\0\0\0") : I32 ("1234"); VERIFY (a, "12345678"); - *(int32_t*)a = vzero ? I32 ("12\0\0") : I32 ("1234"); + *(uint32_t*)a = vzero ? I32 ("12\0\0") : I32 ("1234"); VERIFY (a, "12345678"); - *(int32_t*)a = vzero ? I32 ("123\0") : I32 ("1234"); + *(uint32_t*)a = vzero ? I32 ("123\0") : I32 ("1234"); VERIFY (a, "12345678"); - *(int32_t*)a = vzero ? I32 ("1234") : I32 ("1234"); + *(uint32_t*)a = vzero ? I32 ("1234") : I32 ("1234"); VERIFY (a, "12345678"); - *(int32_t*)a = vzero ? I32 ("1235") : I32 ("1234"); + *(uint32_t*)a = vzero ? I32 ("1235") : I32 ("1234"); VERIFY (a, "12345678"); - *(int32_t*)a = vzero ? I32 ("1234") : I32 ("123\0"); + *(uint32_t*)a = vzero ? I32 ("1234") : I32 ("123\0"); VERIFY (a, "123"); - *(int32_t*)(a + 3) = vzero ? I32 ("456\0") : I32 ("4567"); + *(uint32_t*)(a + 3) = vzero ? I32 ("456\0") : I32 ("4567"); VERIFY (a, "12345678"); } diff --git a/gcc/testsuite/gcc.dg/strlenopt-72.c b/gcc/testsuite/gcc.dg/strlenopt-72.c index a06cc4f9cde..9c00a95162f 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-72.c +++ b/gcc/testsuite/gcc.dg/strlenopt-72.c @@ -5,7 +5,12 @@ unaligned stores and where GCC lowers multi-character stores into smaller numbers of wider stores. { dg-do compile } - { dg-options "-O2 -fdump-tree-optimized" } */ + { dg-options "-O2 -fdump-tree-optimized" } + On strictly aligned targets the consecutive char assignments used + by the test aren't merged. When they involve multiple trailing nuls + these assignments then defeat the strlen optimization as a result of + pr83821. When the bug is resolved the directive below can be removed. + { dg-require-effective-target non_strict_align } */ #include "strlenopt.h" -- 2.30.2