OLD | NEW |
1 //===- subzero/crosstest/test_arith_main.cpp - Driver for tests -----------===// | 1 //===- subzero/crosstest/test_arith_main.cpp - Driver for tests -----------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // Driver for crosstesting arithmetic operations | 10 // Driver for crosstesting arithmetic operations |
11 // | 11 // |
12 //===----------------------------------------------------------------------===// | 12 //===----------------------------------------------------------------------===// |
13 | 13 |
14 /* crosstest.py --test=test_arith.cpp --test=test_arith_frem.ll \ | 14 /* crosstest.py --test=test_arith.cpp --test=test_arith_bool.ll \ |
15 --test=test_arith_sqrt.ll --driver=test_arith_main.cpp \ | 15 --test=test_arith_frem.ll --test=test_arith_sqrt.ll \ |
| 16 --driver=test_arith_main.cpp \ |
16 --prefix=Subzero_ --output=test_arith */ | 17 --prefix=Subzero_ --output=test_arith */ |
17 | 18 |
18 #include <stdint.h> | 19 #include <stdint.h> |
19 | 20 |
20 #include <climits> // CHAR_BIT | 21 #include <climits> // CHAR_BIT |
21 #include <limits> | 22 #include <limits> |
22 #include <cfloat> | 23 #include <cfloat> |
23 #include <cmath> // fmodf | 24 #include <cmath> // fmodf |
24 #include <cstring> // memcmp | 25 #include <cstring> // memcmp |
25 #include <iostream> | 26 #include <iostream> |
26 | 27 |
27 // Include test_arith.h twice - once normally, and once within the | 28 // Include test_arith.h twice - once normally, and once within the |
28 // Subzero_ namespace, corresponding to the llc and Subzero translated | 29 // Subzero_ namespace, corresponding to the llc and Subzero translated |
29 // object files, respectively. | 30 // object files, respectively. |
30 #include "test_arith.h" | 31 #include "test_arith.h" |
31 namespace Subzero_ { | 32 namespace Subzero_ { |
32 #include "test_arith.h" | 33 #include "test_arith.h" |
33 } | 34 } |
34 | 35 |
35 template <class T> bool inputsMayTriggerException(T Value1, T Value2) { | 36 template <class T> |
| 37 bool inputsMayTriggerException(T Value1, T Value2, bool IsReallyBool = false) { |
| 38 if (IsReallyBool) { |
| 39 Value1 &= 1; |
| 40 Value2 &= 1; |
| 41 } |
36 // Avoid HW divide-by-zero exception. | 42 // Avoid HW divide-by-zero exception. |
37 if (Value2 == 0) | 43 if (Value2 == 0) |
38 return true; | 44 return true; |
39 // Avoid HW overflow exception (on x86-32). TODO: adjust | 45 // Avoid HW overflow exception (on x86-32). TODO: adjust |
40 // for other architecture. | 46 // for other architecture. |
41 if (Value1 == std::numeric_limits<T>::min() && Value2 == -1) | 47 if (Value1 == std::numeric_limits<T>::min() && Value2 == -1) |
42 return true; | 48 return true; |
43 return false; | 49 return false; |
44 } | 50 } |
45 | 51 |
46 template <typename TypeUnsigned, typename TypeSigned> | 52 template <typename TypeUnsigned, typename TypeSigned> |
47 void testsInt(size_t &TotalTests, size_t &Passes, size_t &Failures) { | 53 void testsInt(size_t &TotalTests, size_t &Passes, size_t &Failures) { |
48 typedef TypeUnsigned (*FuncTypeUnsigned)(TypeUnsigned, TypeUnsigned); | 54 typedef TypeUnsigned (*FuncTypeUnsigned)(TypeUnsigned, TypeUnsigned); |
49 typedef TypeSigned (*FuncTypeSigned)(TypeSigned, TypeSigned); | 55 typedef TypeSigned (*FuncTypeSigned)(TypeSigned, TypeSigned); |
50 volatile unsigned Values[] = INT_VALUE_ARRAY; | 56 volatile unsigned Values[] = INT_VALUE_ARRAY; |
51 const static size_t NumValues = sizeof(Values) / sizeof(*Values); | 57 const static size_t NumValues = sizeof(Values) / sizeof(*Values); |
52 static struct { | 58 static struct { |
53 // For functions that operate on unsigned values, the | 59 // For functions that operate on unsigned values, the |
54 // FuncLlcSigned and FuncSzSigned fields are NULL. For functions | 60 // FuncLlcSigned and FuncSzSigned fields are NULL. For functions |
55 // that operate on signed values, the FuncLlcUnsigned and | 61 // that operate on signed values, the FuncLlcUnsigned and |
56 // FuncSzUnsigned fields are NULL. | 62 // FuncSzUnsigned fields are NULL. |
57 const char *Name; | 63 const char *Name; |
58 FuncTypeUnsigned FuncLlcUnsigned; | 64 FuncTypeUnsigned FuncLlcUnsigned; |
59 FuncTypeUnsigned FuncSzUnsigned; | 65 FuncTypeUnsigned FuncSzUnsigned; |
60 FuncTypeSigned FuncLlcSigned; | 66 FuncTypeSigned FuncLlcSigned; |
61 FuncTypeSigned FuncSzSigned; | 67 FuncTypeSigned FuncSzSigned; |
62 bool ExcludeDivExceptions; // for divide related tests | 68 bool ExcludeDivExceptions; // for divide related tests |
| 69 bool IsReallyBool; |
63 } Funcs[] = { | 70 } Funcs[] = { |
64 #define X(inst, op, isdiv, isshift) \ | 71 #define X(inst, op, isdiv, isshift) \ |
65 { STR(inst), test##inst, Subzero_::test##inst, NULL, NULL, isdiv } \ | 72 { \ |
66 , | 73 "Bool" STR(inst), testBool##inst, Subzero_::testBool##inst, NULL, NULL, \ |
| 74 isdiv, true \ |
| 75 } \ |
| 76 , { STR(inst), test##inst, Subzero_::test##inst, NULL, NULL, isdiv, false }, |
67 UINTOP_TABLE | 77 UINTOP_TABLE |
68 #undef X | 78 #undef X |
69 #define X(inst, op, isdiv, isshift) \ | 79 #define X(inst, op, isdiv, isshift) \ |
70 { STR(inst), NULL, NULL, test##inst, Subzero_::test##inst, isdiv } \ | 80 { STR(inst), NULL, NULL, test##inst, Subzero_::test##inst, isdiv, false } \ |
71 , | 81 , |
72 SINTOP_TABLE | 82 SINTOP_TABLE |
73 #undef X | 83 #undef X |
74 }; | 84 }; |
75 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs); | 85 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs); |
76 | 86 |
77 if (sizeof(TypeUnsigned) <= sizeof(uint32_t)) { | 87 if (sizeof(TypeUnsigned) <= sizeof(uint32_t)) { |
78 // This is the "normal" version of the loop nest, for 32-bit or | 88 // This is the "normal" version of the loop nest, for 32-bit or |
79 // narrower types. | 89 // narrower types. |
80 for (size_t f = 0; f < NumFuncs; ++f) { | 90 for (size_t f = 0; f < NumFuncs; ++f) { |
81 for (size_t i = 0; i < NumValues; ++i) { | 91 for (size_t i = 0; i < NumValues; ++i) { |
82 for (size_t j = 0; j < NumValues; ++j) { | 92 for (size_t j = 0; j < NumValues; ++j) { |
83 TypeUnsigned Value1 = Values[i]; | 93 TypeUnsigned Value1 = Values[i]; |
84 TypeUnsigned Value2 = Values[j]; | 94 TypeUnsigned Value2 = Values[j]; |
85 // Avoid HW divide-by-zero exception. | 95 // Avoid HW divide-by-zero exception. |
86 if (Funcs[f].ExcludeDivExceptions && | 96 if (Funcs[f].ExcludeDivExceptions && |
87 inputsMayTriggerException<TypeSigned>(Value1, Value2)) | 97 inputsMayTriggerException<TypeSigned>(Value1, Value2, |
| 98 Funcs[f].IsReallyBool)) |
88 continue; | 99 continue; |
89 ++TotalTests; | 100 ++TotalTests; |
90 TypeUnsigned ResultSz, ResultLlc; | 101 TypeUnsigned ResultSz, ResultLlc; |
91 if (Funcs[f].FuncSzUnsigned) { | 102 if (Funcs[f].FuncSzUnsigned) { |
| 103 ResultLlc = Funcs[f].FuncLlcUnsigned(Value1, Value2); |
92 ResultSz = Funcs[f].FuncSzUnsigned(Value1, Value2); | 104 ResultSz = Funcs[f].FuncSzUnsigned(Value1, Value2); |
93 ResultLlc = Funcs[f].FuncLlcUnsigned(Value1, Value2); | |
94 } else { | 105 } else { |
95 ResultSz = Funcs[f].FuncSzSigned(Value1, Value2); | 106 ResultSz = Funcs[f].FuncSzSigned(Value1, Value2); |
96 ResultLlc = Funcs[f].FuncLlcSigned(Value1, Value2); | 107 ResultLlc = Funcs[f].FuncLlcSigned(Value1, Value2); |
97 } | 108 } |
98 if (ResultSz == ResultLlc) { | 109 if (ResultSz == ResultLlc) { |
99 ++Passes; | 110 ++Passes; |
100 } else { | 111 } else { |
101 ++Failures; | 112 ++Failures; |
102 std::cout << "test" << Funcs[f].Name | 113 std::cout << "test" << Funcs[f].Name |
103 << (CHAR_BIT * sizeof(TypeUnsigned)) << "(" << Value1 | 114 << (CHAR_BIT * sizeof(TypeUnsigned)) << "(" |
104 << ", " << Value2 << "): sz=" << (unsigned)ResultSz | 115 << (unsigned)Value1 << ", " << (unsigned)Value2 |
| 116 << "): sz=" << (unsigned)ResultSz |
105 << " llc=" << (unsigned)ResultLlc << "\n"; | 117 << " llc=" << (unsigned)ResultLlc << "\n"; |
106 } | 118 } |
107 } | 119 } |
108 } | 120 } |
109 } | 121 } |
110 } else { | 122 } else { |
111 // This is the 64-bit version. Test values are synthesized from | 123 // This is the 64-bit version. Test values are synthesized from |
112 // the 32-bit values in Values[]. | 124 // the 32-bit values in Values[]. |
113 for (size_t f = 0; f < NumFuncs; ++f) { | 125 for (size_t f = 0; f < NumFuncs; ++f) { |
114 for (size_t iLo = 0; iLo < NumValues; ++iLo) { | 126 for (size_t iLo = 0; iLo < NumValues; ++iLo) { |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 testsVecInt<v16ui8, v16si8>(TotalTests, Passes, Failures); | 368 testsVecInt<v16ui8, v16si8>(TotalTests, Passes, Failures); |
357 testsFp<float>(TotalTests, Passes, Failures); | 369 testsFp<float>(TotalTests, Passes, Failures); |
358 testsFp<double>(TotalTests, Passes, Failures); | 370 testsFp<double>(TotalTests, Passes, Failures); |
359 testsVecFp(TotalTests, Passes, Failures); | 371 testsVecFp(TotalTests, Passes, Failures); |
360 | 372 |
361 std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes | 373 std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes |
362 << " Failures=" << Failures << "\n"; | 374 << " Failures=" << Failures << "\n"; |
363 return Failures; | 375 return Failures; |
364 } | 376 } |
365 | 377 |
OLD | NEW |