1 //===- subzero/crosstest/test_cast_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 crosstesting cast operations.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 /* crosstest.py --test=test_cast.cpp --test=test_cast_to_u1.ll \
15    --test=test_cast_vectors.ll \
16    --driver=test_cast_main.cpp --prefix=Subzero_ --output=test_cast */
17 
18 #include <cfloat>
19 #include <cstring>
20 #include <iostream>
21 #include <stdint.h>
22 
23 #include "test_arith.def"
24 #include "vectors.h"
25 #include "xdefs.h"
26 
27 // Include test_cast.h twice - once normally, and once within the
28 // Subzero_ namespace, corresponding to the llc and Subzero translated
29 // object files, respectively.
30 #include "test_cast.h"
31 namespace Subzero_ {
32 #include "test_cast.h"
33 }
34 
35 #define XSTR(s) STR(s)
36 #define STR(s) #s
37 #define COMPARE(Func, FromCName, ToCName, Input, FromString)                   \
38   do {                                                                         \
39     ToCName ResultSz, ResultLlc;                                               \
40     ResultLlc = Func<FromCName, ToCName>(Input);                               \
41     ResultSz = Subzero_::Func<FromCName, ToCName>(Input);                      \
42     ++TotalTests;                                                              \
43     if (!memcmp(&ResultLlc, &ResultSz, sizeof(ToCName))) {                     \
44       ++Passes;                                                                \
45     } else {                                                                   \
46       ++Failures;                                                              \
47       std::cout << std::fixed << XSTR(Func) << "<" << FromString               \
48                 << ", " XSTR(ToCName) ">(" << Input << "): ";                  \
49       if (sizeof(ToCName) == 1)                                                \
50         std::cout << "sz=" << (int)ResultSz << " llc=" << (int)ResultLlc;      \
51       else                                                                     \
52         std::cout << "sz=" << ResultSz << " llc=" << ResultLlc;                \
53       std::cout << "\n";                                                       \
54     }                                                                          \
55   } while (0)
56 
57 #define COMPARE_ARG(Func, FromCName, ToCName, Input, FromString)               \
58   do {                                                                         \
59     ToCName ResultSz, ResultLlc;                                               \
60     ResultLlc = Func<FromCName, ToCName>(1, Input, 2);                         \
61     ResultSz = Subzero_::Func<FromCName, ToCName>(1, Input, 2);                \
62     ++TotalTests;                                                              \
63     if (!memcmp(&ResultLlc, &ResultSz, sizeof(ToCName))) {                     \
64       ++Passes;                                                                \
65     } else {                                                                   \
66       ++Failures;                                                              \
67       std::cout << std::fixed << XSTR(Func) << "<" << FromString               \
68                 << ", " XSTR(ToCName) ">(" << Input << "): ";                  \
69       if (sizeof(ToCName) == 1)                                                \
70         std::cout << "sz=" << (int)ResultSz << " llc=" << (int)ResultLlc;      \
71       else                                                                     \
72         std::cout << "sz=" << ResultSz << " llc=" << ResultLlc;                \
73       std::cout << "\n";                                                       \
74     }                                                                          \
75   } while (0)
76 
77 #define COMPARE_VEC(Func, FromCName, ToCName, Input, FromString, ToString)     \
78   do {                                                                         \
79     ToCName ResultSz, ResultLlc;                                               \
80     ResultLlc = Func<FromCName, ToCName>(Input);                               \
81     ResultSz = Subzero_::Func<FromCName, ToCName>(Input);                      \
82     ++TotalTests;                                                              \
83     if (!memcmp(&ResultLlc, &ResultSz, sizeof(ToCName))) {                     \
84       ++Passes;                                                                \
85     } else {                                                                   \
86       ++Failures;                                                              \
87       std::cout << std::fixed << XSTR(Func) << "<" << FromString << ", "       \
88                 << ToString << ">(" << vectAsString<FromCName>(Input)          \
89                 << "): ";                                                      \
90       std::cout << "sz=" << vectAsString<ToCName>(ResultSz)                    \
91                 << " llc=" << vectAsString<ToCName>(ResultLlc);                \
92       std::cout << "\n";                                                       \
93     }                                                                          \
94   } while (0)
95 
96 template <typename FromType>
testValue(FromType Val,size_t & TotalTests,size_t & Passes,size_t & Failures,const char * FromTypeString)97 void testValue(FromType Val, size_t &TotalTests, size_t &Passes,
98                size_t &Failures, const char *FromTypeString) {
99   COMPARE(cast, FromType, bool, Val, FromTypeString);
100   COMPARE(cast, FromType, uint8_t, Val, FromTypeString);
101   COMPARE(cast, FromType, myint8_t, Val, FromTypeString);
102   COMPARE(cast, FromType, uint16_t, Val, FromTypeString);
103   COMPARE(cast, FromType, int16_t, Val, FromTypeString);
104   COMPARE(cast, FromType, uint32_t, Val, FromTypeString);
105   COMPARE(cast, FromType, int32_t, Val, FromTypeString);
106   COMPARE(cast, FromType, uint64, Val, FromTypeString);
107   COMPARE(cast, FromType, int64, Val, FromTypeString);
108   COMPARE(cast, FromType, float, Val, FromTypeString);
109   COMPARE(cast, FromType, double, Val, FromTypeString);
110   COMPARE_ARG(cast, FromType, bool, Val, FromTypeString);
111   COMPARE_ARG(cast, FromType, uint8_t, Val, FromTypeString);
112   COMPARE_ARG(cast, FromType, myint8_t, Val, FromTypeString);
113   COMPARE_ARG(cast, FromType, uint16_t, Val, FromTypeString);
114   COMPARE_ARG(cast, FromType, int16_t, Val, FromTypeString);
115   COMPARE_ARG(cast, FromType, uint32_t, Val, FromTypeString);
116   COMPARE_ARG(cast, FromType, int32_t, Val, FromTypeString);
117   COMPARE_ARG(cast, FromType, uint64, Val, FromTypeString);
118   COMPARE_ARG(cast, FromType, int64, Val, FromTypeString);
119   COMPARE_ARG(cast, FromType, float, Val, FromTypeString);
120   COMPARE_ARG(cast, FromType, double, Val, FromTypeString);
121 }
122 
123 template <typename FromType, typename ToType>
testVector(size_t & TotalTests,size_t & Passes,size_t & Failures,const char * FromTypeString,const char * ToTypeString)124 void testVector(size_t &TotalTests, size_t &Passes, size_t &Failures,
125                 const char *FromTypeString, const char *ToTypeString) {
126   const static size_t NumElementsInType = Vectors<FromType>::NumElements;
127   PRNG Index;
128   static const float NegInf = -1.0 / 0.0;
129   static const float PosInf = 1.0 / 0.0;
130   static const float Nan = 0.0 / 0.0;
131   static const float NegNan = -0.0 / 0.0;
132   volatile float Values[] = FP_VALUE_ARRAY(NegInf, PosInf, NegNan, Nan);
133   static const size_t NumValues = sizeof(Values) / sizeof(*Values);
134   const size_t MaxTestsPerFunc = 20000;
135   for (size_t i = 0; i < MaxTestsPerFunc; ++i) {
136     // Initialize the test vectors.
137     FromType Value;
138     for (size_t j = 0; j < NumElementsInType; ++j) {
139       Value[j] = Values[Index() % NumValues];
140     }
141     COMPARE_VEC(cast, FromType, ToType, Value, FromTypeString, ToTypeString);
142   }
143 }
144 
main(int argc,char * argv[])145 int main(int argc, char *argv[]) {
146   size_t TotalTests = 0;
147   size_t Passes = 0;
148   size_t Failures = 0;
149 
150   volatile bool ValsUi1[] = {false, true};
151   static const size_t NumValsUi1 = sizeof(ValsUi1) / sizeof(*ValsUi1);
152   volatile uint8_t ValsUi8[] = {0, 1, 0x7e, 0x7f, 0x80, 0x81, 0xfe, 0xff};
153   static const size_t NumValsUi8 = sizeof(ValsUi8) / sizeof(*ValsUi8);
154 
155   volatile myint8_t ValsSi8[] = {0, 1, 0x7e, 0x7f, 0x80, 0x81, 0xfe, 0xff};
156   static const size_t NumValsSi8 = sizeof(ValsSi8) / sizeof(*ValsSi8);
157 
158   volatile uint16_t ValsUi16[] = {0,      1,      0x7e,   0x7f,   0x80,
159                                   0x81,   0xfe,   0xff,   0x7ffe, 0x7fff,
160                                   0x8000, 0x8001, 0xfffe, 0xffff};
161   static const size_t NumValsUi16 = sizeof(ValsUi16) / sizeof(*ValsUi16);
162 
163   volatile int16_t ValsSi16[] = {0,      1,      0x7e,   0x7f,   0x80,
164                                  0x81,   0xfe,   0xff,   0x7ffe, 0x7fff,
165                                  0x8000, 0x8001, 0xfffe, 0xffff};
166   static const size_t NumValsSi16 = sizeof(ValsSi16) / sizeof(*ValsSi16);
167 
168   volatile size_t ValsUi32[] = {0,          1,          0x7e,       0x7f,
169                                 0x80,       0x81,       0xfe,       0xff,
170                                 0x7ffe,     0x7fff,     0x8000,     0x8001,
171                                 0xfffe,     0xffff,     0x7ffffffe, 0x7fffffff,
172                                 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff};
173   static const size_t NumValsUi32 = sizeof(ValsUi32) / sizeof(*ValsUi32);
174 
175   volatile size_t ValsSi32[] = {0,          1,          0x7e,       0x7f,
176                                 0x80,       0x81,       0xfe,       0xff,
177                                 0x7ffe,     0x7fff,     0x8000,     0x8001,
178                                 0xfffe,     0xffff,     0x7ffffffe, 0x7fffffff,
179                                 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff};
180   static const size_t NumValsSi32 = sizeof(ValsSi32) / sizeof(*ValsSi32);
181 
182   volatile uint64 ValsUi64[] = {
183       0, 1, 0x7e, 0x7f, 0x80, 0x81, 0xfe, 0xff, 0x7ffe, 0x7fff, 0x8000, 0x8001,
184       0xfffe, 0xffff, 0x7ffffffe, 0x7fffffff, 0x80000000, 0x80000001,
185       0xfffffffe, 0xffffffff, 0x100000000ull, 0x100000001ull,
186       0x7ffffffffffffffeull, 0x7fffffffffffffffull, 0x8000000000000000ull,
187       0x8000000000000001ull, 0xfffffffffffffffeull, 0xffffffffffffffffull};
188   static const size_t NumValsUi64 = sizeof(ValsUi64) / sizeof(*ValsUi64);
189 
190   volatile int64 ValsSi64[] = {
191       0, 1, 0x7e, 0x7f, 0x80, 0x81, 0xfe, 0xff, 0x7ffe, 0x7fff, 0x8000, 0x8001,
192       0xfffe, 0xffff, 0x7ffffffe, 0x7fffffff, 0x80000000, 0x80000001,
193       0xfffffffe, 0xffffffff, 0x100000000ll, 0x100000001ll,
194       0x7ffffffffffffffell, 0x7fffffffffffffffll, 0x8000000000000000ll,
195       0x8000000000000001ll, 0xfffffffffffffffell, 0xffffffffffffffffll};
196   static const size_t NumValsSi64 = sizeof(ValsSi64) / sizeof(*ValsSi64);
197 
198   static const double NegInf = -1.0 / 0.0;
199   static const double PosInf = 1.0 / 0.0;
200   static const double Nan = 0.0 / 0.0;
201   static const double NegNan = -0.0 / 0.0;
202   volatile float ValsF32[] = FP_VALUE_ARRAY(NegInf, PosInf, NegNan, Nan);
203   static const size_t NumValsF32 = sizeof(ValsF32) / sizeof(*ValsF32);
204 
205   volatile double ValsF64[] = FP_VALUE_ARRAY(NegInf, PosInf, NegNan, Nan);
206   static const size_t NumValsF64 = sizeof(ValsF64) / sizeof(*ValsF64);
207 
208   for (size_t i = 0; i < NumValsUi1; ++i) {
209     bool Val = ValsUi1[i];
210     testValue<bool>(Val, TotalTests, Passes, Failures, "bool");
211   }
212   for (size_t i = 0; i < NumValsUi8; ++i) {
213     uint8_t Val = ValsUi8[i];
214     testValue<uint8_t>(Val, TotalTests, Passes, Failures, "uint8_t");
215   }
216   for (size_t i = 0; i < NumValsSi8; ++i) {
217     myint8_t Val = ValsSi8[i];
218     testValue<myint8_t>(Val, TotalTests, Passes, Failures, "int8_t");
219   }
220   for (size_t i = 0; i < NumValsUi16; ++i) {
221     uint16_t Val = ValsUi16[i];
222     testValue<uint16_t>(Val, TotalTests, Passes, Failures, "uint16_t");
223   }
224   for (size_t i = 0; i < NumValsSi16; ++i) {
225     int16_t Val = ValsSi16[i];
226     testValue<int16_t>(Val, TotalTests, Passes, Failures, "int16_t");
227   }
228   for (size_t i = 0; i < NumValsUi32; ++i) {
229     uint32_t Val = ValsUi32[i];
230     testValue<uint32_t>(Val, TotalTests, Passes, Failures, "uint32_t");
231     COMPARE(castBits, uint32_t, float, Val, "uint32_t");
232     COMPARE_ARG(castBits, uint32_t, float, Val, "uint32_t");
233   }
234   for (size_t i = 0; i < NumValsSi32; ++i) {
235     int32_t Val = ValsSi32[i];
236     testValue<int32_t>(Val, TotalTests, Passes, Failures, "int32_t");
237   }
238   for (size_t i = 0; i < NumValsUi64; ++i) {
239     uint64 Val = ValsUi64[i];
240     testValue<uint64>(Val, TotalTests, Passes, Failures, "uint64");
241     COMPARE(castBits, uint64, double, Val, "uint64");
242     COMPARE_ARG(castBits, uint64, double, Val, "uint64");
243   }
244   for (size_t i = 0; i < NumValsSi64; ++i) {
245     int64 Val = ValsSi64[i];
246     testValue<int64>(Val, TotalTests, Passes, Failures, "int64");
247   }
248   for (size_t i = 0; i < NumValsF32; ++i) {
249     for (unsigned j = 0; j < 2; ++j) {
250       float Val = ValsF32[i];
251       if (j > 0)
252         Val = -Val;
253       testValue<float>(Val, TotalTests, Passes, Failures, "float");
254       COMPARE(castBits, float, uint32_t, Val, "float");
255       COMPARE_ARG(castBits, float, uint32_t, Val, "float");
256     }
257   }
258   for (size_t i = 0; i < NumValsF64; ++i) {
259     for (unsigned j = 0; j < 2; ++j) {
260       double Val = ValsF64[i];
261       if (j > 0)
262         Val = -Val;
263       testValue<double>(Val, TotalTests, Passes, Failures, "double");
264       COMPARE(castBits, double, uint64, Val, "double");
265       COMPARE_ARG(castBits, double, uint64, Val, "double");
266     }
267   }
268 
269   testVector<v4ui32, v4f32>(TotalTests, Passes, Failures, "v4ui32", "v4f32");
270   testVector<v4si32, v4f32>(TotalTests, Passes, Failures, "v4si32", "v4f32");
271   testVector<v4f32, v4si32>(TotalTests, Passes, Failures, "v4f32", "v4si32");
272   testVector<v4f32, v4ui32>(TotalTests, Passes, Failures, "v4f32", "v4ui32");
273 
274   std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes
275             << " Failures=" << Failures << "\n";
276   return Failures;
277 }
278