OSDN Git Service

2011-10-18 Janus Weil <janus@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / gcc.dg / strlenopt-20.c
1 /* { dg-do run } */
2 /* { dg-options "-O2 -fdump-tree-strlen" } */
3
4 #include "strlenopt.h"
5
6 __attribute__((noinline, noclone)) const char *
7 fn1 (int x, int y)
8 {
9   const char *p;
10   switch (x)
11     {
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;
26     }
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);
33 }
34
35 __attribute__((noinline, noclone)) size_t
36 fn2 (char *p, char *q)
37 {
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;
45 }
46
47 __attribute__((noinline, noclone)) char *
48 fn3 (char *p)
49 {
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;
58 }
59
60 int
61 main ()
62 {
63   int i;
64   char buf[64], buf2[64];
65   for (i = 0; i < 5; i++)
66     {
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 ();
75     }
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;
87 }
88
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" } } */