OLD | NEW |
| 1 //===- subzero/crosstest/test_fcmp_main.cpp - Driver for tests ------------===// |
| 2 // |
| 3 // The Subzero Code Generator |
| 4 // |
| 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. |
| 7 // |
| 8 //===----------------------------------------------------------------------===// |
| 9 // |
| 10 // Driver for cross testing the fcmp bitcode instruction |
| 11 // |
| 12 //===----------------------------------------------------------------------===// |
| 13 |
1 /* crosstest.py --test=test_fcmp.pnacl.ll --driver=test_fcmp_main.cpp \ | 14 /* crosstest.py --test=test_fcmp.pnacl.ll --driver=test_fcmp_main.cpp \ |
2 --prefix=Subzero_ --output=test_fcmp */ | 15 --prefix=Subzero_ --output=test_fcmp */ |
3 | 16 |
4 #include <cassert> | 17 #include <cassert> |
5 #include <cfloat> | 18 #include <cfloat> |
6 #include <cmath> | 19 #include <cmath> |
| 20 #include <cstring> |
7 #include <iostream> | 21 #include <iostream> |
8 | 22 |
| 23 #include "vectors.h" |
9 #include "test_fcmp.def" | 24 #include "test_fcmp.def" |
10 | 25 |
11 #define X(cmp) \ | 26 #define X(cmp) \ |
12 extern "C" bool fcmp##cmp##Float(float a, float b); \ | 27 extern "C" bool fcmp##cmp##Float(float a, float b); \ |
13 extern "C" bool fcmp##cmp##Double(double a, double b); \ | 28 extern "C" bool fcmp##cmp##Double(double a, double b); \ |
| 29 extern "C" v4si32 fcmp##cmp##Vector(v4f32 a, v4f32 b); \ |
14 extern "C" bool Subzero_fcmp##cmp##Float(float a, float b); \ | 30 extern "C" bool Subzero_fcmp##cmp##Float(float a, float b); \ |
15 extern "C" bool Subzero_fcmp##cmp##Double(double a, double b); | 31 extern "C" bool Subzero_fcmp##cmp##Double(double a, double b); \ |
| 32 extern "C" v4si32 Subzero_fcmp##cmp##Vector(v4f32 a, v4f32 b); |
16 FCMP_TABLE; | 33 FCMP_TABLE; |
17 #undef X | 34 #undef X |
18 | 35 |
19 int main(int argc, char **argv) { | 36 volatile double *Values; |
| 37 size_t NumValues; |
| 38 |
| 39 void initializeValues() { |
20 static const double NegInf = -1.0 / 0.0; | 40 static const double NegInf = -1.0 / 0.0; |
21 static const double Zero = 0.0; | 41 static const double Zero = 0.0; |
22 static const double Ten = 10.0; | 42 static const double Ten = 10.0; |
23 static const double PosInf = 1.0 / 0.0; | 43 static const double PosInf = 1.0 / 0.0; |
24 static const double Nan = 0.0 / 0.0; | 44 static const double Nan = 0.0 / 0.0; |
25 static const double NegNan = -0.0 / 0.0; | 45 static const double NegNan = -0.0 / 0.0; |
26 assert(std::fpclassify(NegInf) == FP_INFINITE); | 46 assert(std::fpclassify(NegInf) == FP_INFINITE); |
27 assert(std::fpclassify(PosInf) == FP_INFINITE); | 47 assert(std::fpclassify(PosInf) == FP_INFINITE); |
28 assert(std::fpclassify(Nan) == FP_NAN); | 48 assert(std::fpclassify(Nan) == FP_NAN); |
29 assert(std::fpclassify(NegNan) == FP_NAN); | 49 assert(std::fpclassify(NegNan) == FP_NAN); |
30 assert(NegInf < Zero); | 50 assert(NegInf < Zero); |
31 assert(NegInf < PosInf); | 51 assert(NegInf < PosInf); |
32 assert(Zero < PosInf); | 52 assert(Zero < PosInf); |
| 53 static volatile double InitValues[] = {NegInf, -Zero, Zero, DBL_MIN, |
| 54 FLT_MIN, Ten, FLT_MAX, DBL_MAX, |
| 55 PosInf, Nan, NegNan}; |
| 56 NumValues = sizeof(InitValues) / sizeof(*InitValues); |
| 57 Values = InitValues; |
| 58 } |
33 | 59 |
34 volatile double Values[] = { NegInf, -Zero, Zero, DBL_MIN, FLT_MIN, | 60 void testsScalar(size_t &TotalTests, size_t &Passes, size_t &Failures) { |
35 Ten, FLT_MAX, DBL_MAX, PosInf, Nan, | |
36 NegNan }; | |
37 const static size_t NumValues = sizeof(Values) / sizeof(*Values); | |
38 | |
39 typedef bool (*FuncTypeFloat)(float, float); | 61 typedef bool (*FuncTypeFloat)(float, float); |
40 typedef bool (*FuncTypeDouble)(double, double); | 62 typedef bool (*FuncTypeDouble)(double, double); |
41 static struct { | 63 static struct { |
42 const char *Name; | 64 const char *Name; |
43 FuncTypeFloat FuncFloatSz; | 65 FuncTypeFloat FuncFloatSz; |
44 FuncTypeFloat FuncFloatLlc; | 66 FuncTypeFloat FuncFloatLlc; |
45 FuncTypeDouble FuncDoubleSz; | 67 FuncTypeDouble FuncDoubleSz; |
46 FuncTypeDouble FuncDoubleLlc; | 68 FuncTypeDouble FuncDoubleLlc; |
47 } Funcs[] = { | 69 } Funcs[] = { |
48 #define X(cmp) \ | 70 #define X(cmp) \ |
49 { \ | 71 { \ |
50 "fcmp" STR(cmp), Subzero_fcmp##cmp##Float, fcmp##cmp##Float, \ | 72 "fcmp" STR(cmp), Subzero_fcmp##cmp##Float, fcmp##cmp##Float, \ |
51 Subzero_fcmp##cmp##Double, fcmp##cmp##Double \ | 73 Subzero_fcmp##cmp##Double, fcmp##cmp##Double \ |
52 } \ | 74 } \ |
53 , | 75 , |
54 FCMP_TABLE | 76 FCMP_TABLE |
55 #undef X | 77 #undef X |
56 }; | 78 }; |
57 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs); | 79 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs); |
58 | 80 |
59 bool ResultSz, ResultLlc; | 81 bool ResultSz, ResultLlc; |
60 | 82 |
61 size_t TotalTests = 0; | 83 assert(Values && NumValues); |
62 size_t Passes = 0; | |
63 size_t Failures = 0; | |
64 | 84 |
65 for (size_t f = 0; f < NumFuncs; ++f) { | 85 for (size_t f = 0; f < NumFuncs; ++f) { |
66 for (size_t i = 0; i < NumValues; ++i) { | 86 for (size_t i = 0; i < NumValues; ++i) { |
67 for (size_t j = 0; j < NumValues; ++j) { | 87 for (size_t j = 0; j < NumValues; ++j) { |
68 ++TotalTests; | 88 ++TotalTests; |
69 float Value1Float = Values[i]; | 89 float Value1Float = Values[i]; |
70 float Value2Float = Values[j]; | 90 float Value2Float = Values[j]; |
71 ResultSz = Funcs[f].FuncFloatSz(Value1Float, Value2Float); | 91 ResultSz = Funcs[f].FuncFloatSz(Value1Float, Value2Float); |
72 ResultLlc = Funcs[f].FuncFloatLlc(Value1Float, Value2Float); | 92 ResultLlc = Funcs[f].FuncFloatLlc(Value1Float, Value2Float); |
73 if (ResultSz == ResultLlc) { | 93 if (ResultSz == ResultLlc) { |
74 ++Passes; | 94 ++Passes; |
75 } else { | 95 } else { |
76 ++Failures; | 96 ++Failures; |
77 std::cout << Funcs[f].Name << "Float(" << Value1Float << ", " | 97 std::cout << Funcs[f].Name << "Float(" << Value1Float << ", " |
78 << Value2Float << "): sz=" << ResultSz | 98 << Value2Float << "): sz=" << ResultSz |
79 << " llc=" << ResultLlc << std::endl; | 99 << " llc=" << ResultLlc << "\n"; |
80 } | 100 } |
81 ++TotalTests; | 101 ++TotalTests; |
82 double Value1Double = Values[i]; | 102 double Value1Double = Values[i]; |
83 double Value2Double = Values[j]; | 103 double Value2Double = Values[j]; |
84 ResultSz = Funcs[f].FuncDoubleSz(Value1Double, Value2Double); | 104 ResultSz = Funcs[f].FuncDoubleSz(Value1Double, Value2Double); |
85 ResultLlc = Funcs[f].FuncDoubleLlc(Value1Double, Value2Double); | 105 ResultLlc = Funcs[f].FuncDoubleLlc(Value1Double, Value2Double); |
86 if (ResultSz == ResultLlc) { | 106 if (ResultSz == ResultLlc) { |
87 ++Passes; | 107 ++Passes; |
88 } else { | 108 } else { |
89 ++Failures; | 109 ++Failures; |
90 std::cout << Funcs[f].Name << "Double(" << Value1Double << ", " | 110 std::cout << Funcs[f].Name << "Double(" << Value1Double << ", " |
91 << Value2Double << "): sz=" << ResultSz | 111 << Value2Double << "): sz=" << ResultSz |
92 << " llc=" << ResultLlc << std::endl; | 112 << " llc=" << ResultLlc << "\n"; |
93 } | 113 } |
94 } | 114 } |
95 } | 115 } |
96 } | 116 } |
| 117 } |
| 118 |
| 119 void testsVector(size_t &TotalTests, size_t &Passes, size_t &Failures) { |
| 120 typedef v4si32 (*FuncTypeVector)(v4f32, v4f32); |
| 121 static struct { |
| 122 const char *Name; |
| 123 FuncTypeVector FuncVectorSz; |
| 124 FuncTypeVector FuncVectorLlc; |
| 125 } Funcs[] = { |
| 126 #define X(cmp) \ |
| 127 { "fcmp" STR(cmp), Subzero_fcmp##cmp##Vector, fcmp##cmp##Vector } \ |
| 128 , |
| 129 FCMP_TABLE |
| 130 #undef X |
| 131 }; |
| 132 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs); |
| 133 const static size_t NumElementsInType = 4; |
| 134 const static size_t MaxTestsPerFunc = 100000; |
| 135 |
| 136 assert(Values && NumValues); |
| 137 |
| 138 for (size_t f = 0; f < NumFuncs; ++f) { |
| 139 PRNG Index; |
| 140 for (size_t i = 0; i < MaxTestsPerFunc; ++i) { |
| 141 v4f32 Value1, Value2; |
| 142 for (size_t j = 0; j < NumElementsInType; ++j) { |
| 143 Value1[j] = Values[Index() % NumValues]; |
| 144 Value2[j] = Values[Index() % NumValues]; |
| 145 } |
| 146 ++TotalTests; |
| 147 v4si32 ResultSz, ResultLlc; |
| 148 ResultSz = Funcs[f].FuncVectorSz(Value1, Value2); |
| 149 ResultLlc = Funcs[f].FuncVectorLlc(Value1, Value2); |
| 150 if (!memcmp(&ResultSz, &ResultLlc, sizeof(ResultSz))) { |
| 151 ++Passes; |
| 152 } else { |
| 153 ++Failures; |
| 154 std::cout << Funcs[f].Name << "Vector(" << vectAsString<v4f32>(Value1) |
| 155 << ", " << vectAsString<v4f32>(Value2) |
| 156 << "): sz=" << vectAsString<v4si32>(ResultSz) |
| 157 << " llc=" << vectAsString<v4si32>(ResultLlc) << "\n"; |
| 158 } |
| 159 } |
| 160 } |
| 161 } |
| 162 |
| 163 int main(int argc, char **argv) { |
| 164 size_t TotalTests = 0; |
| 165 size_t Passes = 0; |
| 166 size_t Failures = 0; |
| 167 |
| 168 initializeValues(); |
| 169 |
| 170 testsScalar(TotalTests, Passes, Failures); |
| 171 testsVector(TotalTests, Passes, Failures); |
97 | 172 |
98 std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes | 173 std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes |
99 << " Failures=" << Failures << "\n"; | 174 << " Failures=" << Failures << "\n"; |
100 return Failures; | 175 return Failures; |
101 } | 176 } |
OLD | NEW |