111
|
1 /* This test needs runtime that provides stpcpy and mempcpy functions. */
|
145
|
2 /* { dg-do run { target *-*-linux* *-*-gnu* *-*-uclinux* } } */
|
111
|
3 /* { dg-options "-O2 -fdump-tree-strlen" } */
|
|
4 /* Bionic targets don't have mempcpy */
|
|
5 /* { dg-require-effective-target non_bionic } */
|
|
6
|
|
7 #define USE_GNU
|
|
8 #include "strlenopt.h"
|
|
9
|
|
10 __attribute__((noinline, noclone)) char *
|
|
11 fn1 (char *p, size_t *l1, size_t *l2)
|
|
12 {
|
|
13 char *a = mempcpy (p, "abcde", 6);
|
|
14 /* This strlen needs to stay. */
|
|
15 size_t la = strlen (a);
|
|
16 /* This strlen can be optimized into 5. */
|
|
17 size_t lp = strlen (p);
|
|
18 *l1 = la;
|
|
19 *l2 = lp;
|
|
20 return a;
|
|
21 }
|
|
22
|
|
23 __attribute__((noinline, noclone)) char *
|
|
24 fn2 (char *p, const char *q, size_t *l1, size_t *l2, size_t *l3)
|
|
25 {
|
|
26 /* This strlen needs to stay. */
|
|
27 size_t lq = strlen (q);
|
|
28 char *a = mempcpy (p, q, lq + 1);
|
|
29 /* This strlen needs to stay. */
|
|
30 size_t la = strlen (a);
|
|
31 /* This strlen can be optimized into lq. */
|
|
32 size_t lp = strlen (p);
|
|
33 *l1 = lq;
|
|
34 *l2 = la;
|
|
35 *l3 = lp;
|
|
36 return a;
|
|
37 }
|
|
38
|
|
39 __attribute__((noinline, noclone)) char *
|
|
40 fn3 (char *p, size_t *l1, size_t *l2)
|
|
41 {
|
|
42 char *a = stpcpy (p, "abcde");
|
|
43 /* This strlen can be optimized into 0. */
|
|
44 size_t la = strlen (a);
|
|
45 /* This strlen can be optimized into 5. */
|
|
46 size_t lp = strlen (p);
|
|
47 *l1 = la;
|
|
48 *l2 = lp;
|
|
49 return a;
|
|
50 }
|
|
51
|
|
52 __attribute__((noinline, noclone)) char *
|
|
53 fn4 (char *p, const char *q, size_t *l1, size_t *l2, size_t *l3)
|
|
54 {
|
|
55 /* This strlen needs to stay. */
|
|
56 size_t lq = strlen (q);
|
|
57 char *a = stpcpy (p, q);
|
|
58 /* This strlen can be optimized into 0. */
|
|
59 size_t la = strlen (a);
|
|
60 /* This strlen can be optimized into lq. */
|
|
61 size_t lp = strlen (p);
|
|
62 *l1 = lq;
|
|
63 *l2 = la;
|
|
64 *l3 = lp;
|
|
65 return a;
|
|
66 }
|
|
67
|
|
68 __attribute__((noinline, noclone)) char *
|
|
69 fn5 (char *p, const char *q, size_t *l1, size_t *l2)
|
|
70 {
|
|
71 char *a = stpcpy (p, q);
|
|
72 /* This strlen can be optimized into 0. */
|
|
73 size_t la = strlen (a);
|
|
74 /* This strlen can be optimized into a - p. */
|
|
75 size_t lp = strlen (p);
|
|
76 *l1 = la;
|
|
77 *l2 = lp;
|
|
78 return a;
|
|
79 }
|
|
80
|
|
81 int
|
|
82 main ()
|
|
83 {
|
|
84 char buf[64];
|
|
85 const char *volatile q = "ABCDEFGH";
|
|
86 size_t l1, l2, l3;
|
|
87 memset (buf, '\0', sizeof buf);
|
|
88 memset (buf + 6, 'z', 7);
|
|
89 if (fn1 (buf, &l1, &l2) != buf + 6 || l1 != 7 || l2 != 5
|
|
90 || memcmp (buf, "abcde\0zzzzzzz", 14) != 0)
|
|
91 abort ();
|
|
92 if (fn2 (buf, q, &l1, &l2, &l3) != buf + 9 || l1 != 8 || l2 != 4 || l3 != 8
|
|
93 || memcmp (buf, "ABCDEFGH\0zzzz", 14) != 0)
|
|
94 abort ();
|
|
95 if (fn3 (buf, &l1, &l2) != buf + 5 || l1 != 0 || l2 != 5
|
|
96 || memcmp (buf, "abcde\0GH\0zzzz", 14) != 0)
|
|
97 abort ();
|
|
98 l3 = 0;
|
|
99 memset (buf, 'n', 9);
|
|
100 if (fn4 (buf, q, &l1, &l2, &l3) != buf + 8 || l1 != 8 || l2 != 0 || l3 != 8
|
|
101 || memcmp (buf, "ABCDEFGH\0zzzz", 14) != 0)
|
|
102 abort ();
|
|
103 memset (buf, 'm', 9);
|
|
104 if (fn5 (buf, q, &l1, &l2) != buf + 8 || l1 != 0 || l2 != 8
|
|
105 || memcmp (buf, "ABCDEFGH\0zzzz", 14) != 0)
|
|
106 abort ();
|
|
107 return 0;
|
|
108 }
|
|
109
|
145
|
110 /* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen1" } } */
|
|
111 /* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen1" } } */
|
|
112 /* { dg-final { scan-tree-dump-times "mempcpy \\(" 2 "strlen1" } } */
|
|
113 /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
|
|
114 /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
|
|
115 /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
|
|
116 /* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen1" } } */
|