Mercurial > hg > CbC > CbC_gcc
comparison gcc/testsuite/gcc.dg/strlenopt-65.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 /* PRE tree-optimization/90626 - fold strcmp(a, b) == 0 to zero when | |
2 one string length is exact and the other is unequal | |
3 { dg-do compile } | |
4 { dg-options "-O2 -Wall -Wno-string-compare -fdump-tree-optimized -ftrack-macro-expansion=0" } */ | |
5 | |
6 #include "strlenopt.h" | |
7 | |
8 #define CAT(x, y) x ## y | |
9 #define CONCAT(x, y) CAT (x, y) | |
10 #define FAILNAME(name) CONCAT (call_ ## name ##_on_line_, __LINE__) | |
11 | |
12 #define FAIL(name) do { \ | |
13 extern void FAILNAME (name) (void); \ | |
14 FAILNAME (name)(); \ | |
15 } while (0) | |
16 | |
17 /* Macro to emit a call to function named | |
18 call_in_true_branch_not_eliminated_on_line_NNN() | |
19 for each call that's expected to be eliminated. The dg-final | |
20 scan-tree-dump-time directive at the bottom of the test verifies | |
21 that no such call appears in output. */ | |
22 #define ELIM_IF_TRUE(expr) \ | |
23 if (!(expr)) FAIL (in_true_branch_not_eliminated); else (void)0 | |
24 | |
25 /* Macro to emit a call to a function named | |
26 call_made_in_{true,false}_branch_on_line_NNN() | |
27 for each call that's expected to be retained. The dg-final | |
28 scan-tree-dump-time directive at the bottom of the test verifies | |
29 that the expected number of both kinds of calls appears in output | |
30 (a pair for each line with the invocation of the KEEP() macro. */ | |
31 #define TEST_KEEP(expr) \ | |
32 if (expr) \ | |
33 FAIL (made_in_true_branch); \ | |
34 else \ | |
35 FAIL (made_in_false_branch) | |
36 | |
37 #define FOLD(init1, init2, arg1, arg2, bnd) \ | |
38 do { \ | |
39 char a[8], b[8]; \ | |
40 sink (a, b); \ | |
41 memcpy (a, init1, sizeof init1 - 1); \ | |
42 memcpy (b, init2, sizeof init2 - 1); \ | |
43 ELIM_IF_TRUE (0 != CMPFUNC (arg1, arg2, bnd)); \ | |
44 } while (0) | |
45 | |
46 #define KEEP(init1, init2, arg1, arg2, bnd) \ | |
47 do { \ | |
48 char a[8], b[8]; \ | |
49 sink (a, b); \ | |
50 memcpy (a, init1, sizeof init1 - 1); \ | |
51 memcpy (b, init2, sizeof init2 - 1); \ | |
52 TEST_KEEP (0 == CMPFUNC (arg1, arg2, bnd)); \ | |
53 } while (0) | |
54 | |
55 const char s0[1] = ""; | |
56 const char s00[2] = "\0"; | |
57 const char s10[2] = "1"; | |
58 const char s20[2] = "2"; | |
59 | |
60 void sink (void*, ...); | |
61 | |
62 void test_strcmp_elim (void) | |
63 { | |
64 #undef CMPFUNC | |
65 #define CMPFUNC(a, b, dummy) strcmp (a, b) | |
66 | |
67 FOLD (s00, s10, "\0", "1", -1); | |
68 FOLD (s00, s10, "\0", b, -1); | |
69 FOLD (s00, s10, "\0", s10, -1); | |
70 | |
71 FOLD (s00, s10, s0, "1", -1); | |
72 FOLD (s00, s10, s0, b, -1); | |
73 FOLD (s00, s10, s0, s10, -1); | |
74 | |
75 FOLD ("\0", "1", s0, "1", -1); | |
76 FOLD ("\0", "1", s0, b, -1); | |
77 FOLD ("\0", "1", s0, s10, -1); | |
78 | |
79 FOLD ("2", "\0", "2", "\0", -1); | |
80 FOLD ("2", "\0", s20, s0, -1); | |
81 | |
82 FOLD ("\0", "1", a, b, -1); | |
83 FOLD ("2", "\0", a, b, -1); | |
84 | |
85 FOLD ("4\0", "44", a, b, -1); | |
86 FOLD ("55", "5\0", a, b, -1); | |
87 | |
88 FOLD ("666\0", "6666", a, "6666", -1); | |
89 FOLD ("666\0", "6666", a, b, -1); | |
90 FOLD ("7777", "777\0", a, b, -1); | |
91 | |
92 /* Avoid testing substrings of equal length with different characters. | |
93 The optimization doesn't have access to the contents of the strings | |
94 so it can't determine whether they are equal. | |
95 | |
96 FOLD ("111\0", "112", a, b, -1); | |
97 FOLD ("112", "111\0", a, b, -1); */ | |
98 } | |
99 | |
100 const char s123[] = "123"; | |
101 const char s1230[] = "123\0"; | |
102 | |
103 const char s1234[] = "1234"; | |
104 const char s12340[] = "1234\0"; | |
105 | |
106 void test_strncmp_elim (void) | |
107 { | |
108 #undef CMPFUNC | |
109 #define CMPFUNC(a, b, n) strncmp (a, b, n) | |
110 | |
111 FOLD (s1230, s1234, "123", "1234", 4); | |
112 FOLD (s1234, s1230, "1234", "123", 4); | |
113 | |
114 FOLD (s1230, s1234, "123", s1234, 4); | |
115 FOLD (s1234, s1230, "1234", s123, 4); | |
116 | |
117 FOLD (s1230, s1234, s123, "1234", 4); | |
118 FOLD (s1234, s1230, s1234, "123", 4); | |
119 | |
120 FOLD (s1230, s1234, s123, b, 4); | |
121 FOLD (s1234, s1230, s1234, b, 4); | |
122 | |
123 FOLD (s1230, s1234, a, b, 4); | |
124 FOLD (s1234, s1230, a, b, 4); | |
125 | |
126 FOLD ("123\0", "1234", a, b, 5); | |
127 FOLD ("1234", "123\0", a, b, 5); | |
128 } | |
129 | |
130 | |
131 #line 1000 | |
132 | |
133 void test_strcmp_keep (const char *s, const char *t) | |
134 { | |
135 #undef CMPFUNC | |
136 #define CMPFUNC(a, b, dummy) strcmp (a, b) | |
137 | |
138 KEEP ("123", "123\0", a, b, /* bnd = */ -1); | |
139 KEEP ("123\0", "123", a, b, -1); | |
140 | |
141 { | |
142 char a[8], b[8]; | |
143 sink (a, b); | |
144 strcpy (a, s); | |
145 strcpy (b, t); | |
146 TEST_KEEP (0 == strcmp (a, b)); | |
147 } | |
148 } | |
149 | |
150 | |
151 void test_strncmp_keep (const char *s, const char *t) | |
152 { | |
153 #undef CMPFUNC | |
154 #define CMPFUNC(a, b, n) strncmp (a, b, n) | |
155 | |
156 KEEP ("1", "1", a, b, 2); | |
157 | |
158 KEEP ("1\0", "1", a, b, 2); | |
159 KEEP ("1", "1\0", a, b, 2); | |
160 | |
161 KEEP ("12\0", "12", a, b, 2); | |
162 KEEP ("12", "12\0", a, b, 2); | |
163 | |
164 KEEP ("111\0", "111", a, b, 3); | |
165 KEEP ("112", "112\0", a, b, 3); | |
166 | |
167 { | |
168 char a[8], b[8]; | |
169 sink (a, b); | |
170 strcpy (a, s); | |
171 strcpy (b, t); | |
172 TEST_KEEP (0 == strncmp (a, b, sizeof a)); | |
173 } | |
174 } | |
175 | |
176 /* { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated_" 0 "optimized" } } | |
177 | |
178 { dg-final { scan-tree-dump-times "call_made_in_true_branch_on_line_1\[0-9\]\[0-9\]\[0-9\]" 11 "optimized" } } | |
179 { dg-final { scan-tree-dump-times "call_made_in_false_branch_on_line_1\[0-9\]\[0-9\]\[0-9\]" 11 "optimized" } } */ |