1 /* Test that __builtin_prefetch does no harm.
2
3 Check that the expression containing the address to prefetch is
4 evaluated if it has side effects, even if the target does not support
5 data prefetch. Check changes to pointers and to array indices that are
6 either global variables or arguments. */
7
8 #define ARRSIZE 100
9
10 int arr[ARRSIZE];
11 int *ptr = &arr[20];
12 int arrindex = 4;
13
14 /* Check that assignment within a prefetch argument is evaluated. */
15
16 int
assign_arg_ptr(int * p)17 assign_arg_ptr (int *p)
18 {
19 int *q;
20 __builtin_prefetch ((q = p), 0, 0);
21 return q == p;
22 }
23
24 int
assign_glob_ptr(void)25 assign_glob_ptr (void)
26 {
27 int *q;
28 __builtin_prefetch ((q = ptr), 0, 0);
29 return q == ptr;
30 }
31
32 int
assign_arg_idx(int * p,int i)33 assign_arg_idx (int *p, int i)
34 {
35 int j;
36 __builtin_prefetch (&p[j = i], 0, 0);
37 return j == i;
38 }
39
40 int
assign_glob_idx(void)41 assign_glob_idx (void)
42 {
43 int j;
44 __builtin_prefetch (&ptr[j = arrindex], 0, 0);
45 return j == arrindex;
46 }
47
48 /* Check that pre/post increment/decrement within a prefetch argument are
49 evaluated. */
50
51 int
preinc_arg_ptr(int * p)52 preinc_arg_ptr (int *p)
53 {
54 int *q;
55 q = p + 1;
56 __builtin_prefetch (++p, 0, 0);
57 return p == q;
58 }
59
60 int
preinc_glob_ptr(void)61 preinc_glob_ptr (void)
62 {
63 int *q;
64 q = ptr + 1;
65 __builtin_prefetch (++ptr, 0, 0);
66 return ptr == q;
67 }
68
69 int
postinc_arg_ptr(int * p)70 postinc_arg_ptr (int *p)
71 {
72 int *q;
73 q = p + 1;
74 __builtin_prefetch (p++, 0, 0);
75 return p == q;
76 }
77
78 int
postinc_glob_ptr(void)79 postinc_glob_ptr (void)
80 {
81 int *q;
82 q = ptr + 1;
83 __builtin_prefetch (ptr++, 0, 0);
84 return ptr == q;
85 }
86
87 int
predec_arg_ptr(int * p)88 predec_arg_ptr (int *p)
89 {
90 int *q;
91 q = p - 1;
92 __builtin_prefetch (--p, 0, 0);
93 return p == q;
94 }
95
96 int
predec_glob_ptr(void)97 predec_glob_ptr (void)
98 {
99 int *q;
100 q = ptr - 1;
101 __builtin_prefetch (--ptr, 0, 0);
102 return ptr == q;
103 }
104
105 int
postdec_arg_ptr(int * p)106 postdec_arg_ptr (int *p)
107 {
108 int *q;
109 q = p - 1;
110 __builtin_prefetch (p--, 0, 0);
111 return p == q;
112 }
113
114 int
postdec_glob_ptr(void)115 postdec_glob_ptr (void)
116 {
117 int *q;
118 q = ptr - 1;
119 __builtin_prefetch (ptr--, 0, 0);
120 return ptr == q;
121 }
122
123 int
preinc_arg_idx(int * p,int i)124 preinc_arg_idx (int *p, int i)
125 {
126 int j = i + 1;
127 __builtin_prefetch (&p[++i], 0, 0);
128 return i == j;
129 }
130
131
132 int
preinc_glob_idx(void)133 preinc_glob_idx (void)
134 {
135 int j = arrindex + 1;
136 __builtin_prefetch (&ptr[++arrindex], 0, 0);
137 return arrindex == j;
138 }
139
140 int
postinc_arg_idx(int * p,int i)141 postinc_arg_idx (int *p, int i)
142 {
143 int j = i + 1;
144 __builtin_prefetch (&p[i++], 0, 0);
145 return i == j;
146 }
147
148 int
postinc_glob_idx(void)149 postinc_glob_idx (void)
150 {
151 int j = arrindex + 1;
152 __builtin_prefetch (&ptr[arrindex++], 0, 0);
153 return arrindex == j;
154 }
155
156 int
predec_arg_idx(int * p,int i)157 predec_arg_idx (int *p, int i)
158 {
159 int j = i - 1;
160 __builtin_prefetch (&p[--i], 0, 0);
161 return i == j;
162 }
163
164 int
predec_glob_idx(void)165 predec_glob_idx (void)
166 {
167 int j = arrindex - 1;
168 __builtin_prefetch (&ptr[--arrindex], 0, 0);
169 return arrindex == j;
170 }
171
172 int
postdec_arg_idx(int * p,int i)173 postdec_arg_idx (int *p, int i)
174 {
175 int j = i - 1;
176 __builtin_prefetch (&p[i--], 0, 0);
177 return i == j;
178 }
179
180 int
postdec_glob_idx(void)181 postdec_glob_idx (void)
182 {
183 int j = arrindex - 1;
184 __builtin_prefetch (&ptr[arrindex--], 0, 0);
185 return arrindex == j;
186 }
187
188 /* Check that function calls within the first prefetch argument are
189 evaluated. */
190
191 int getptrcnt = 0;
192
193 int *
getptr(int * p)194 getptr (int *p)
195 {
196 getptrcnt++;
197 return p + 1;
198 }
199
200 int
funccall_arg_ptr(int * p)201 funccall_arg_ptr (int *p)
202 {
203 __builtin_prefetch (getptr (p), 0, 0);
204 return getptrcnt == 1;
205 }
206
207 int getintcnt = 0;
208
209 int
getint(int i)210 getint (int i)
211 {
212 getintcnt++;
213 return i + 1;
214 }
215
216 int
funccall_arg_idx(int * p,int i)217 funccall_arg_idx (int *p, int i)
218 {
219 __builtin_prefetch (&p[getint (i)], 0, 0);
220 return getintcnt == 1;
221 }
222
223 int
main()224 main ()
225 {
226 if (!assign_arg_ptr (ptr))
227 abort ();
228 if (!assign_glob_ptr ())
229 abort ();
230 if (!assign_arg_idx (ptr, 4))
231 abort ();
232 if (!assign_glob_idx ())
233 abort ();
234 if (!preinc_arg_ptr (ptr))
235 abort ();
236 if (!preinc_glob_ptr ())
237 abort ();
238 if (!postinc_arg_ptr (ptr))
239 abort ();
240 if (!postinc_glob_ptr ())
241 abort ();
242 if (!predec_arg_ptr (ptr))
243 abort ();
244 if (!predec_glob_ptr ())
245 abort ();
246 if (!postdec_arg_ptr (ptr))
247 abort ();
248 if (!postdec_glob_ptr ())
249 abort ();
250 if (!preinc_arg_idx (ptr, 3))
251 abort ();
252 if (!preinc_glob_idx ())
253 abort ();
254 if (!postinc_arg_idx (ptr, 3))
255 abort ();
256 if (!postinc_glob_idx ())
257 abort ();
258 if (!predec_arg_idx (ptr, 3))
259 abort ();
260 if (!predec_glob_idx ())
261 abort ();
262 if (!postdec_arg_idx (ptr, 3))
263 abort ();
264 if (!postdec_glob_idx ())
265 abort ();
266 if (!funccall_arg_ptr (ptr))
267 abort ();
268 if (!funccall_arg_idx (ptr, 3))
269 abort ();
270 exit (0);
271 }
272