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