| 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 |