1bf215546Sopenharmony_ci/**************************************************************************
2bf215546Sopenharmony_ci *
3bf215546Sopenharmony_ci * Copyright 2009 VMware, Inc.
4bf215546Sopenharmony_ci * All Rights Reserved.
5bf215546Sopenharmony_ci *
6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the
8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to
11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
12bf215546Sopenharmony_ci * the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the
15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
16bf215546Sopenharmony_ci * of the Software.
17bf215546Sopenharmony_ci *
18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25bf215546Sopenharmony_ci *
26bf215546Sopenharmony_ci **************************************************************************/
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci
29bf215546Sopenharmony_ci/**
30bf215546Sopenharmony_ci * @file
31bf215546Sopenharmony_ci * Shared testing code.
32bf215546Sopenharmony_ci *
33bf215546Sopenharmony_ci * @author Jose Fonseca <jfonseca@vmware.com>
34bf215546Sopenharmony_ci */
35bf215546Sopenharmony_ci
36bf215546Sopenharmony_ci
37bf215546Sopenharmony_ci#include "util/u_math.h"
38bf215546Sopenharmony_ci
39bf215546Sopenharmony_ci#include "gallivm/lp_bld_const.h"
40bf215546Sopenharmony_ci#include "gallivm/lp_bld_init.h"
41bf215546Sopenharmony_ci#include "gallivm/lp_bld_debug.h"
42bf215546Sopenharmony_ci#include "lp_test.h"
43bf215546Sopenharmony_ci
44bf215546Sopenharmony_ci
45bf215546Sopenharmony_civoid
46bf215546Sopenharmony_cidump_type(FILE *fp,
47bf215546Sopenharmony_ci          struct lp_type type)
48bf215546Sopenharmony_ci{
49bf215546Sopenharmony_ci   fprintf(fp, "%s%s%u%sx%u",
50bf215546Sopenharmony_ci           type.sign ? (type.floating || type.fixed ? "" : "s") : "u",
51bf215546Sopenharmony_ci           type.floating ? "f" : (type.fixed ? "h" : "i"),
52bf215546Sopenharmony_ci           type.width,
53bf215546Sopenharmony_ci           type.norm ? "n" : "",
54bf215546Sopenharmony_ci           type.length);
55bf215546Sopenharmony_ci}
56bf215546Sopenharmony_ci
57bf215546Sopenharmony_ci
58bf215546Sopenharmony_cidouble
59bf215546Sopenharmony_ciread_elem(struct lp_type type, const void *src, unsigned index)
60bf215546Sopenharmony_ci{
61bf215546Sopenharmony_ci   double scale = lp_const_scale(type);
62bf215546Sopenharmony_ci   double value;
63bf215546Sopenharmony_ci   assert(index < type.length);
64bf215546Sopenharmony_ci   if (type.floating) {
65bf215546Sopenharmony_ci      switch(type.width) {
66bf215546Sopenharmony_ci      case 32:
67bf215546Sopenharmony_ci         value = *((const float *)src + index);
68bf215546Sopenharmony_ci         break;
69bf215546Sopenharmony_ci      case 64:
70bf215546Sopenharmony_ci         value =  *((const double *)src + index);
71bf215546Sopenharmony_ci         break;
72bf215546Sopenharmony_ci      default:
73bf215546Sopenharmony_ci         assert(0);
74bf215546Sopenharmony_ci         return 0.0;
75bf215546Sopenharmony_ci      }
76bf215546Sopenharmony_ci   }
77bf215546Sopenharmony_ci   else {
78bf215546Sopenharmony_ci      if(type.sign) {
79bf215546Sopenharmony_ci         switch(type.width) {
80bf215546Sopenharmony_ci         case 8:
81bf215546Sopenharmony_ci            value = *((const int8_t *)src + index);
82bf215546Sopenharmony_ci            break;
83bf215546Sopenharmony_ci         case 16:
84bf215546Sopenharmony_ci            value = *((const int16_t *)src + index);
85bf215546Sopenharmony_ci            break;
86bf215546Sopenharmony_ci         case 32:
87bf215546Sopenharmony_ci            value = *((const int32_t *)src + index);
88bf215546Sopenharmony_ci            break;
89bf215546Sopenharmony_ci         case 64:
90bf215546Sopenharmony_ci            value = *((const int64_t *)src + index);
91bf215546Sopenharmony_ci            break;
92bf215546Sopenharmony_ci         default:
93bf215546Sopenharmony_ci            assert(0);
94bf215546Sopenharmony_ci            return 0.0;
95bf215546Sopenharmony_ci         }
96bf215546Sopenharmony_ci      }
97bf215546Sopenharmony_ci      else {
98bf215546Sopenharmony_ci         switch(type.width) {
99bf215546Sopenharmony_ci         case 8:
100bf215546Sopenharmony_ci            value = *((const uint8_t *)src + index);
101bf215546Sopenharmony_ci            break;
102bf215546Sopenharmony_ci         case 16:
103bf215546Sopenharmony_ci            value = *((const uint16_t *)src + index);
104bf215546Sopenharmony_ci            break;
105bf215546Sopenharmony_ci         case 32:
106bf215546Sopenharmony_ci            value = *((const uint32_t *)src + index);
107bf215546Sopenharmony_ci            break;
108bf215546Sopenharmony_ci         case 64:
109bf215546Sopenharmony_ci            value = *((const uint64_t *)src + index);
110bf215546Sopenharmony_ci            break;
111bf215546Sopenharmony_ci         default:
112bf215546Sopenharmony_ci            assert(0);
113bf215546Sopenharmony_ci            return 0.0;
114bf215546Sopenharmony_ci         }
115bf215546Sopenharmony_ci      }
116bf215546Sopenharmony_ci   }
117bf215546Sopenharmony_ci   return value/scale;
118bf215546Sopenharmony_ci}
119bf215546Sopenharmony_ci
120bf215546Sopenharmony_ci
121bf215546Sopenharmony_civoid
122bf215546Sopenharmony_ciwrite_elem(struct lp_type type, void *dst, unsigned index, double value)
123bf215546Sopenharmony_ci{
124bf215546Sopenharmony_ci   assert(index < type.length);
125bf215546Sopenharmony_ci   if(!type.sign && value < 0.0)
126bf215546Sopenharmony_ci      value = 0.0;
127bf215546Sopenharmony_ci   if(type.norm && value < -1.0)
128bf215546Sopenharmony_ci      value = -1.0;
129bf215546Sopenharmony_ci   if(type.norm && value > 1.0)
130bf215546Sopenharmony_ci      value = 1.0;
131bf215546Sopenharmony_ci   if (type.floating) {
132bf215546Sopenharmony_ci      switch(type.width) {
133bf215546Sopenharmony_ci      case 32:
134bf215546Sopenharmony_ci         *((float *)dst + index) = (float)(value);
135bf215546Sopenharmony_ci         break;
136bf215546Sopenharmony_ci      case 64:
137bf215546Sopenharmony_ci          *((double *)dst + index) = value;
138bf215546Sopenharmony_ci         break;
139bf215546Sopenharmony_ci      default:
140bf215546Sopenharmony_ci         assert(0);
141bf215546Sopenharmony_ci      }
142bf215546Sopenharmony_ci   }
143bf215546Sopenharmony_ci   else {
144bf215546Sopenharmony_ci      double scale = lp_const_scale(type);
145bf215546Sopenharmony_ci      value = round(value*scale);
146bf215546Sopenharmony_ci      if(type.sign) {
147bf215546Sopenharmony_ci         long long lvalue = (long long)value;
148bf215546Sopenharmony_ci         lvalue = MIN2(lvalue, ((long long)1 << (type.width - 1)) - 1);
149bf215546Sopenharmony_ci         lvalue = MAX2(lvalue, -((long long)1 << (type.width - 1)));
150bf215546Sopenharmony_ci         switch(type.width) {
151bf215546Sopenharmony_ci         case 8:
152bf215546Sopenharmony_ci            *((int8_t *)dst + index) = (int8_t)lvalue;
153bf215546Sopenharmony_ci            break;
154bf215546Sopenharmony_ci         case 16:
155bf215546Sopenharmony_ci            *((int16_t *)dst + index) = (int16_t)lvalue;
156bf215546Sopenharmony_ci            break;
157bf215546Sopenharmony_ci         case 32:
158bf215546Sopenharmony_ci            *((int32_t *)dst + index) = (int32_t)lvalue;
159bf215546Sopenharmony_ci            break;
160bf215546Sopenharmony_ci         case 64:
161bf215546Sopenharmony_ci            *((int64_t *)dst + index) = (int64_t)lvalue;
162bf215546Sopenharmony_ci            break;
163bf215546Sopenharmony_ci         default:
164bf215546Sopenharmony_ci            assert(0);
165bf215546Sopenharmony_ci         }
166bf215546Sopenharmony_ci      }
167bf215546Sopenharmony_ci      else {
168bf215546Sopenharmony_ci         unsigned long long lvalue = (long long)value;
169bf215546Sopenharmony_ci         lvalue = MIN2(lvalue, ((unsigned long long)1 << type.width) - 1);
170bf215546Sopenharmony_ci         switch(type.width) {
171bf215546Sopenharmony_ci         case 8:
172bf215546Sopenharmony_ci            *((uint8_t *)dst + index) = (uint8_t)lvalue;
173bf215546Sopenharmony_ci            break;
174bf215546Sopenharmony_ci         case 16:
175bf215546Sopenharmony_ci            *((uint16_t *)dst + index) = (uint16_t)lvalue;
176bf215546Sopenharmony_ci            break;
177bf215546Sopenharmony_ci         case 32:
178bf215546Sopenharmony_ci            *((uint32_t *)dst + index) = (uint32_t)lvalue;
179bf215546Sopenharmony_ci            break;
180bf215546Sopenharmony_ci         case 64:
181bf215546Sopenharmony_ci            *((uint64_t *)dst + index) = (uint64_t)lvalue;
182bf215546Sopenharmony_ci            break;
183bf215546Sopenharmony_ci         default:
184bf215546Sopenharmony_ci            assert(0);
185bf215546Sopenharmony_ci         }
186bf215546Sopenharmony_ci      }
187bf215546Sopenharmony_ci   }
188bf215546Sopenharmony_ci}
189bf215546Sopenharmony_ci
190bf215546Sopenharmony_ci
191bf215546Sopenharmony_civoid
192bf215546Sopenharmony_cirandom_elem(struct lp_type type, void *dst, unsigned index)
193bf215546Sopenharmony_ci{
194bf215546Sopenharmony_ci   double value;
195bf215546Sopenharmony_ci   assert(index < type.length);
196bf215546Sopenharmony_ci   value = (double)rand()/(double)RAND_MAX;
197bf215546Sopenharmony_ci   if(!type.norm) {
198bf215546Sopenharmony_ci      if (type.floating) {
199bf215546Sopenharmony_ci         value *= 2.0;
200bf215546Sopenharmony_ci      }
201bf215546Sopenharmony_ci      else {
202bf215546Sopenharmony_ci         unsigned long long mask;
203bf215546Sopenharmony_ci         if (type.fixed)
204bf215546Sopenharmony_ci            mask = ((unsigned long long)1 << (type.width / 2)) - 1;
205bf215546Sopenharmony_ci         else if (type.sign)
206bf215546Sopenharmony_ci            mask = ((unsigned long long)1 << (type.width - 1)) - 1;
207bf215546Sopenharmony_ci         else
208bf215546Sopenharmony_ci            mask = ((unsigned long long)1 << type.width) - 1;
209bf215546Sopenharmony_ci         value += (double)(mask & rand());
210bf215546Sopenharmony_ci         if (!type.fixed && !type.sign && type.width == 32) {
211bf215546Sopenharmony_ci            /*
212bf215546Sopenharmony_ci             * rand only returns half the possible range
213bf215546Sopenharmony_ci             * XXX 64bit values...
214bf215546Sopenharmony_ci             */
215bf215546Sopenharmony_ci            if(rand() & 1)
216bf215546Sopenharmony_ci               value += (double)0x80000000;
217bf215546Sopenharmony_ci         }
218bf215546Sopenharmony_ci      }
219bf215546Sopenharmony_ci   }
220bf215546Sopenharmony_ci   if(type.sign)
221bf215546Sopenharmony_ci      if(rand() & 1)
222bf215546Sopenharmony_ci         value = -value;
223bf215546Sopenharmony_ci   write_elem(type, dst, index, value);
224bf215546Sopenharmony_ci}
225bf215546Sopenharmony_ci
226bf215546Sopenharmony_ci
227bf215546Sopenharmony_civoid
228bf215546Sopenharmony_ciread_vec(struct lp_type type, const void *src, double *dst)
229bf215546Sopenharmony_ci{
230bf215546Sopenharmony_ci   unsigned i;
231bf215546Sopenharmony_ci   for (i = 0; i < type.length; ++i)
232bf215546Sopenharmony_ci      dst[i] = read_elem(type, src, i);
233bf215546Sopenharmony_ci}
234bf215546Sopenharmony_ci
235bf215546Sopenharmony_ci
236bf215546Sopenharmony_civoid
237bf215546Sopenharmony_ciwrite_vec(struct lp_type type, void *dst, const double *src)
238bf215546Sopenharmony_ci{
239bf215546Sopenharmony_ci   unsigned i;
240bf215546Sopenharmony_ci   for (i = 0; i < type.length; ++i)
241bf215546Sopenharmony_ci      write_elem(type, dst, i, src[i]);
242bf215546Sopenharmony_ci}
243bf215546Sopenharmony_ci
244bf215546Sopenharmony_ci
245bf215546Sopenharmony_cifloat
246bf215546Sopenharmony_cirandom_float(void)
247bf215546Sopenharmony_ci{
248bf215546Sopenharmony_ci    return (float)((double)rand()/(double)RAND_MAX);
249bf215546Sopenharmony_ci}
250bf215546Sopenharmony_ci
251bf215546Sopenharmony_ci
252bf215546Sopenharmony_civoid
253bf215546Sopenharmony_cirandom_vec(struct lp_type type, void *dst)
254bf215546Sopenharmony_ci{
255bf215546Sopenharmony_ci   unsigned i;
256bf215546Sopenharmony_ci   for (i = 0; i < type.length; ++i)
257bf215546Sopenharmony_ci      random_elem(type, dst, i);
258bf215546Sopenharmony_ci}
259bf215546Sopenharmony_ci
260bf215546Sopenharmony_ci
261bf215546Sopenharmony_ciboolean
262bf215546Sopenharmony_cicompare_vec_with_eps(struct lp_type type, const void *res, const void *ref, double eps)
263bf215546Sopenharmony_ci{
264bf215546Sopenharmony_ci   unsigned i;
265bf215546Sopenharmony_ci   eps *= type.floating ? 8.0 : 2.0;
266bf215546Sopenharmony_ci   for (i = 0; i < type.length; ++i) {
267bf215546Sopenharmony_ci      double res_elem = read_elem(type, res, i);
268bf215546Sopenharmony_ci      double ref_elem = read_elem(type, ref, i);
269bf215546Sopenharmony_ci      double delta = res_elem - ref_elem;
270bf215546Sopenharmony_ci      if (ref_elem < -1.0 || ref_elem > 1.0) {
271bf215546Sopenharmony_ci	 delta /= ref_elem;
272bf215546Sopenharmony_ci      }
273bf215546Sopenharmony_ci      delta = fabs(delta);
274bf215546Sopenharmony_ci      if (delta >= eps) {
275bf215546Sopenharmony_ci         return FALSE;
276bf215546Sopenharmony_ci      }
277bf215546Sopenharmony_ci   }
278bf215546Sopenharmony_ci
279bf215546Sopenharmony_ci   return TRUE;
280bf215546Sopenharmony_ci}
281bf215546Sopenharmony_ci
282bf215546Sopenharmony_ci
283bf215546Sopenharmony_ciboolean
284bf215546Sopenharmony_cicompare_vec(struct lp_type type, const void *res, const void *ref)
285bf215546Sopenharmony_ci{
286bf215546Sopenharmony_ci   double eps = lp_const_eps(type);
287bf215546Sopenharmony_ci   return compare_vec_with_eps(type, res, ref, eps);
288bf215546Sopenharmony_ci}
289bf215546Sopenharmony_ci
290bf215546Sopenharmony_ci
291bf215546Sopenharmony_civoid
292bf215546Sopenharmony_cidump_vec(FILE *fp, struct lp_type type, const void *src)
293bf215546Sopenharmony_ci{
294bf215546Sopenharmony_ci   unsigned i;
295bf215546Sopenharmony_ci   for (i = 0; i < type.length; ++i) {
296bf215546Sopenharmony_ci      if(i)
297bf215546Sopenharmony_ci         fprintf(fp, " ");
298bf215546Sopenharmony_ci      if (type.floating) {
299bf215546Sopenharmony_ci         double value;
300bf215546Sopenharmony_ci         switch(type.width) {
301bf215546Sopenharmony_ci         case 32:
302bf215546Sopenharmony_ci            value = *((const float *)src + i);
303bf215546Sopenharmony_ci            break;
304bf215546Sopenharmony_ci         case 64:
305bf215546Sopenharmony_ci            value = *((const double *)src + i);
306bf215546Sopenharmony_ci            break;
307bf215546Sopenharmony_ci         default:
308bf215546Sopenharmony_ci            assert(0);
309bf215546Sopenharmony_ci            value = 0.0;
310bf215546Sopenharmony_ci         }
311bf215546Sopenharmony_ci         fprintf(fp, "%f", value);
312bf215546Sopenharmony_ci      }
313bf215546Sopenharmony_ci      else {
314bf215546Sopenharmony_ci         if(type.sign && !type.norm) {
315bf215546Sopenharmony_ci            long long value;
316bf215546Sopenharmony_ci            const char *format;
317bf215546Sopenharmony_ci            switch(type.width) {
318bf215546Sopenharmony_ci            case 8:
319bf215546Sopenharmony_ci               value = *((const int8_t *)src + i);
320bf215546Sopenharmony_ci               format = "%3lli";
321bf215546Sopenharmony_ci               break;
322bf215546Sopenharmony_ci            case 16:
323bf215546Sopenharmony_ci               value = *((const int16_t *)src + i);
324bf215546Sopenharmony_ci               format = "%5lli";
325bf215546Sopenharmony_ci               break;
326bf215546Sopenharmony_ci            case 32:
327bf215546Sopenharmony_ci               value = *((const int32_t *)src + i);
328bf215546Sopenharmony_ci               format = "%10lli";
329bf215546Sopenharmony_ci               break;
330bf215546Sopenharmony_ci            case 64:
331bf215546Sopenharmony_ci               value = *((const int64_t *)src + i);
332bf215546Sopenharmony_ci               format = "%20lli";
333bf215546Sopenharmony_ci               break;
334bf215546Sopenharmony_ci            default:
335bf215546Sopenharmony_ci               assert(0);
336bf215546Sopenharmony_ci               value = 0.0;
337bf215546Sopenharmony_ci               format = "?";
338bf215546Sopenharmony_ci            }
339bf215546Sopenharmony_ci            fprintf(fp, format, value);
340bf215546Sopenharmony_ci         }
341bf215546Sopenharmony_ci         else {
342bf215546Sopenharmony_ci            unsigned long long value;
343bf215546Sopenharmony_ci            const char *format;
344bf215546Sopenharmony_ci            switch(type.width) {
345bf215546Sopenharmony_ci            case 8:
346bf215546Sopenharmony_ci               value = *((const uint8_t *)src + i);
347bf215546Sopenharmony_ci               format = type.norm ? "%2x" : "%4llu";
348bf215546Sopenharmony_ci               break;
349bf215546Sopenharmony_ci            case 16:
350bf215546Sopenharmony_ci               value = *((const uint16_t *)src + i);
351bf215546Sopenharmony_ci               format = type.norm ? "%4x" : "%6llx";
352bf215546Sopenharmony_ci               break;
353bf215546Sopenharmony_ci            case 32:
354bf215546Sopenharmony_ci               value = *((const uint32_t *)src + i);
355bf215546Sopenharmony_ci               format = type.norm ? "%8x" : "%11llx";
356bf215546Sopenharmony_ci               break;
357bf215546Sopenharmony_ci            case 64:
358bf215546Sopenharmony_ci               value = *((const uint64_t *)src + i);
359bf215546Sopenharmony_ci               format = type.norm ? "%16x" : "%21llx";
360bf215546Sopenharmony_ci               break;
361bf215546Sopenharmony_ci            default:
362bf215546Sopenharmony_ci               assert(0);
363bf215546Sopenharmony_ci               value = 0.0;
364bf215546Sopenharmony_ci               format = "?";
365bf215546Sopenharmony_ci            }
366bf215546Sopenharmony_ci            fprintf(fp, format, value);
367bf215546Sopenharmony_ci         }
368bf215546Sopenharmony_ci      }
369bf215546Sopenharmony_ci   }
370bf215546Sopenharmony_ci}
371bf215546Sopenharmony_ci
372bf215546Sopenharmony_ci
373bf215546Sopenharmony_ciint main(int argc, char **argv)
374bf215546Sopenharmony_ci{
375bf215546Sopenharmony_ci   unsigned verbose = 0;
376bf215546Sopenharmony_ci   FILE *fp = NULL;
377bf215546Sopenharmony_ci   unsigned long n = 1000;
378bf215546Sopenharmony_ci   unsigned i;
379bf215546Sopenharmony_ci   boolean success;
380bf215546Sopenharmony_ci   boolean single = FALSE;
381bf215546Sopenharmony_ci   unsigned fpstate;
382bf215546Sopenharmony_ci
383bf215546Sopenharmony_ci   fpstate = util_fpstate_get();
384bf215546Sopenharmony_ci   util_fpstate_set_denorms_to_zero(fpstate);
385bf215546Sopenharmony_ci
386bf215546Sopenharmony_ci   if (!lp_build_init())
387bf215546Sopenharmony_ci      return 1;
388bf215546Sopenharmony_ci
389bf215546Sopenharmony_ci   for(i = 1; i < argc; ++i) {
390bf215546Sopenharmony_ci      if(strcmp(argv[i], "-v") == 0)
391bf215546Sopenharmony_ci         ++verbose;
392bf215546Sopenharmony_ci      else if(strcmp(argv[i], "-s") == 0)
393bf215546Sopenharmony_ci         single = TRUE;
394bf215546Sopenharmony_ci      else if(strcmp(argv[i], "-o") == 0)
395bf215546Sopenharmony_ci         fp = fopen(argv[++i], "wt");
396bf215546Sopenharmony_ci      else
397bf215546Sopenharmony_ci         n = atoi(argv[i]);
398bf215546Sopenharmony_ci   }
399bf215546Sopenharmony_ci
400bf215546Sopenharmony_ci#ifdef DEBUG
401bf215546Sopenharmony_ci   if (verbose >= 2) {
402bf215546Sopenharmony_ci      gallivm_debug |= GALLIVM_DEBUG_IR;
403bf215546Sopenharmony_ci      gallivm_debug |= GALLIVM_DEBUG_ASM;
404bf215546Sopenharmony_ci   }
405bf215546Sopenharmony_ci#endif
406bf215546Sopenharmony_ci
407bf215546Sopenharmony_ci   if (fp) {
408bf215546Sopenharmony_ci      /* Warm up the caches */
409bf215546Sopenharmony_ci      test_some(0, NULL, 100);
410bf215546Sopenharmony_ci
411bf215546Sopenharmony_ci      write_tsv_header(fp);
412bf215546Sopenharmony_ci   }
413bf215546Sopenharmony_ci
414bf215546Sopenharmony_ci   if (single)
415bf215546Sopenharmony_ci      success = test_single(verbose, fp);
416bf215546Sopenharmony_ci   else if (n)
417bf215546Sopenharmony_ci      success = test_some(verbose, fp, n);
418bf215546Sopenharmony_ci   else
419bf215546Sopenharmony_ci      success = test_all(verbose, fp);
420bf215546Sopenharmony_ci
421bf215546Sopenharmony_ci   if (fp)
422bf215546Sopenharmony_ci      fclose(fp);
423bf215546Sopenharmony_ci
424bf215546Sopenharmony_ci   LLVMShutdown();
425bf215546Sopenharmony_ci
426bf215546Sopenharmony_ci   return success ? 0 : 1;
427bf215546Sopenharmony_ci}
428