2014-07-29 Ed Smith-Rowland <3dw4rd@verizon.net>
[official-gcc.git] / gcc / testsuite / gcc.dg / strlenopt-20.c
blob6fe99a422e9e411de37156b562615bc18c164800
1 /* { dg-do run } */
2 /* { dg-options "-O2 -fdump-tree-strlen" } */
4 #include "strlenopt.h"
6 __attribute__((noinline, noclone)) const char *
7 fn1 (int x, int y)
9 const char *p;
10 switch (x)
12 case 0:
13 p = "abcd";
14 /* Prevent cswitch optimization. */
15 asm volatile ("" : : : "memory");
16 break;
17 case 1:
18 p = "efgh";
19 break;
20 case 2:
21 p = "ijkl";
22 break;
23 default:
24 p = "mnop";
25 break;
27 if (y)
28 /* strchr should be optimized into p + 4 here. */
29 return strchr (p, '\0');
30 else
31 /* and strlen into 3. */
32 return p + strlen (p + 1);
35 __attribute__((noinline, noclone)) size_t
36 fn2 (char *p, char *q)
38 size_t l;
39 /* Both strcpy calls can be optimized into memcpy, strlen needs to stay. */
40 strcpy (p, "abc");
41 p[3] = 'd';
42 l = strlen (p);
43 strcpy (q, p);
44 return l;
47 __attribute__((noinline, noclone)) char *
48 fn3 (char *p)
50 char *c;
51 /* The strcpy call can be optimized into memcpy, strchr needs to stay,
52 strcat is optimized into memcpy. */
53 strcpy (p, "abc");
54 p[3] = 'd';
55 c = strchr (p, '\0');
56 strcat (p, "efgh");
57 return c;
60 int
61 main ()
63 int i;
64 char buf[64], buf2[64];
65 for (i = 0; i < 5; i++)
67 const char *p = "abcdefghijklmnop" + (i < 3 ? i : 3) * 4;
68 const char *q;
69 q = fn1 (i, 1);
70 if (memcmp (q - 4, p, 4) != 0 || q[0] != '\0')
71 abort ();
72 q = fn1 (i, 0);
73 if (memcmp (q - 3, p, 4) != 0 || q[1] != '\0')
74 abort ();
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)
81 abort ();
82 memset (buf, '\0', sizeof buf);
83 memset (buf + 4, 'z', 2);
84 if (fn3 (buf) != buf + 6 || memcmp (buf, "abcdzzefgh", 11) != 0)
85 abort ();
86 return 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" } } */