111
|
1 /* { dg-do run } */
|
|
2 /* { dg-options "-O2 -fno-code-hoisting -fdump-tree-strlen -fdump-tree-optimized" } */
|
|
3
|
|
4 #include "strlenopt.h"
|
|
5
|
|
6 __attribute__((noinline, noclone)) char *
|
|
7 fn1 (int r)
|
|
8 {
|
|
9 char *p = r ? "a" : "bc";
|
|
10 /* String length for p varies, therefore strchr below isn't
|
|
11 optimized away. */
|
|
12 return strchr (p, '\0');
|
|
13 }
|
|
14
|
|
15 __attribute__((noinline, noclone)) size_t
|
|
16 fn2 (int r)
|
|
17 {
|
|
18 char *p, q[10];
|
|
19 strcpy (q, "abc");
|
|
20 p = r ? "a" : q;
|
|
21 /* String length is constant for both alternatives, and strlen is
|
|
22 optimized away. */
|
|
23 return strlen (p);
|
|
24 }
|
|
25
|
|
26 __attribute__((noinline, noclone)) size_t
|
|
27 fn3 (char *p, int n)
|
|
28 {
|
|
29 int i;
|
|
30 p = strchr (p, '\0');
|
|
31 /* strcat here can be optimized into memcpy. */
|
|
32 strcat (p, "abcd");
|
|
33 for (i = 0; i < n; i++)
|
|
34 if ((i % 123) == 53)
|
|
35 /* strcat here is optimized into strlen and memcpy. */
|
|
36 strcat (p, "efg");
|
|
37 /* The strlen here can't be optimized away, as in the loop string
|
|
38 length of p might change. */
|
|
39 return strlen (p);
|
|
40 }
|
|
41
|
|
42 char buf[64];
|
|
43
|
|
44 __attribute__((noinline, noclone)) size_t
|
|
45 fn4 (char *x, int n)
|
|
46 {
|
|
47 int i;
|
|
48 size_t l;
|
|
49 char a[64];
|
|
50 char *p = strchr (x, '\0');
|
|
51 /* strcpy here is optimized into memcpy, length computed as p - x + 1. */
|
|
52 strcpy (a, x);
|
|
53 /* strcat here is optimized into memcpy. */
|
|
54 strcat (p, "abcd");
|
|
55 for (i = 0; i < n; i++)
|
|
56 if ((i % 123) == 53)
|
|
57 /* strcat here is optimized into strlen and memcpy. */
|
|
58 strcat (a, "efg");
|
|
59 /* The strlen should be optimized here into 4. */
|
|
60 l = strlen (p);
|
|
61 /* This stays strcpy. */
|
|
62 strcpy (buf, a);
|
|
63 return l;
|
|
64 }
|
|
65
|
|
66 int
|
|
67 main ()
|
|
68 {
|
|
69 volatile int l = 1;
|
|
70 char b[64];
|
|
71
|
|
72 if (memcmp (fn1 (l) - 1, "a", 2) != 0)
|
|
73 abort ();
|
|
74 if (memcmp (fn1 (!l) - 2, "bc", 3) != 0)
|
|
75 abort ();
|
|
76 if (fn2 (l) != 1 || fn2 (!l) != 3)
|
|
77 abort ();
|
|
78 memset (b, '\0', sizeof b);
|
|
79 memset (b, 'a', 3);
|
|
80 if (fn3 (b, 10) != 4 || memcmp (b, "aaaabcd", 8) != 0)
|
|
81 abort ();
|
|
82 if (fn3 (b, 128) != 7 || memcmp (b, "aaaabcdabcdefg", 15) != 0)
|
|
83 abort ();
|
|
84 if (fn3 (b, 256) != 10 || memcmp (b, "aaaabcdabcdefgabcdefgefg", 25) != 0)
|
|
85 abort ();
|
|
86 if (fn4 (b, 10) != 4
|
|
87 || memcmp (b, "aaaabcdabcdefgabcdefgefgabcd", 29) != 0
|
|
88 || memcmp (buf, "aaaabcdabcdefgabcdefgefg", 25) != 0)
|
|
89 abort ();
|
|
90 if (fn4 (b, 128) != 4
|
|
91 || memcmp (b, "aaaabcdabcdefgabcdefgefgabcdabcd", 33) != 0
|
|
92 || memcmp (buf, "aaaabcdabcdefgabcdefgefgabcdefg", 32) != 0)
|
|
93 abort ();
|
|
94 if (fn4 (b, 256) != 4
|
|
95 || memcmp (b, "aaaabcdabcdefgabcdefgefgabcdabcdabcd", 37) != 0
|
|
96 || memcmp (buf, "aaaabcdabcdefgabcdefgefgabcdabcdefgefg", 39) != 0)
|
|
97 abort ();
|
|
98 return 0;
|
|
99 }
|
|
100
|
145
|
101 /* { dg-final { scan-tree-dump-times "strlen \\(" 5 "strlen1" } } */
|
|
102 /* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen1" } } */
|
|
103 /* { dg-final { scan-tree-dump-times "strcpy \\(" 1 "strlen1" } } */
|
|
104 /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
|
|
105 /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
|
|
106 /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
|
111
|
107 /* { dg-final { scan-tree-dump-times "return 4;" 1 "optimized" } } */
|