2 /* { dg-options "-O2 -fdump-tree-strlen" } */
6 __attribute__((noinline, noclone)) const char *
14 /* Prevent cswitch optimization. */
15 asm volatile ("" : : : "memory");
28 /* strchr should be optimized into p + 4 here. */
29 return strchr (p, '\0');
31 /* and strlen into 3. */
32 return p + strlen (p + 1);
35 __attribute__((noinline, noclone)) size_t
36 fn2 (char *p, char *q)
39 /* Both strcpy calls can be optimized into memcpy, strlen needs to stay. */
47 __attribute__((noinline, noclone)) char *
51 /* The strcpy call can be optimized into memcpy, strchr needs to stay,
52 strcat is optimized into memcpy. */
64 char buf[64], buf2[64];
65 for (i = 0; i < 5; i++)
67 const char *p = "abcdefghijklmnop" + (i < 3 ? i : 3) * 4;
70 if (memcmp (q - 4, p, 4) != 0 || q[0] != '\0')
73 if (memcmp (q - 3, p, 4) != 0 || q[1] != '\0')
76 memset (buf, '\0', sizeof buf);
77 memset (buf + 4, 'z', 2);
78 if (fn2 (buf, buf2) != 6
79 || memcmp (buf, "abcdzz", 7) != 0
80 || memcmp (buf2, "abcdzz", 7) != 0)
82 memset (buf, '\0', sizeof buf);
83 memset (buf + 4, 'z', 2);
84 if (fn3 (buf) != buf + 6 || memcmp (buf, "abcdzzefgh", 11) != 0)
89 /* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */
90 /* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" } } */
91 /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
92 /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
93 /* { dg-final { scan-tree-dump-times "strchr \\(" 1 "strlen" } } */
94 /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
95 /* { dg-final { cleanup-tree-dump "strlen" } } */