2018-05-17 Richard Biener <rguenther@suse.de>
[official-gcc.git] / gcc / testsuite / gcc.dg / strlenopt-14g.c
blob62a83bf8fd7e08b8df2f3eb85672357933bcbcec
1 /* This test needs runtime that provides stpcpy and mempcpy functions. */
2 /* { dg-do run { target *-*-linux* *-*-gnu* } } */
3 /* { dg-options "-O2 -fdump-tree-strlen" } */
4 /* Bionic targets don't have mempcpy */
5 /* { dg-require-effective-target non_bionic } */
7 #define USE_GNU
8 #include "strlenopt.h"
10 __attribute__((noinline, noclone)) char *
11 fn1 (char *p, size_t *l1, size_t *l2)
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;
23 __attribute__((noinline, noclone)) char *
24 fn2 (char *p, const char *q, size_t *l1, size_t *l2, size_t *l3)
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;
39 __attribute__((noinline, noclone)) char *
40 fn3 (char *p, size_t *l1, size_t *l2)
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;
52 __attribute__((noinline, noclone)) char *
53 fn4 (char *p, const char *q, size_t *l1, size_t *l2, size_t *l3)
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;
68 __attribute__((noinline, noclone)) char *
69 fn5 (char *p, const char *q, size_t *l1, size_t *l2)
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;
81 int
82 main ()
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;
110 /* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen" } } */
111 /* { dg-final { scan-tree-dump-times "memcpy \\(" 1 "strlen" } } */
112 /* { dg-final { scan-tree-dump-times "mempcpy \\(" 2 "strlen" } } */
113 /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
114 /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
115 /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
116 /* { dg-final { scan-tree-dump-times "stpcpy \\(" 2 "strlen" } } */