blob: 1279f8d7d775e5955d721be5cb0918663c59b080 [file] [log] [blame]
Matt Wala9a0168a2014-07-23 14:56:10 -07001//===- subzero/crosstest/test_icmp_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 icmp bitcode instruction
11//
12//===----------------------------------------------------------------------===//
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070013
Matt Wala9a0168a2014-07-23 14:56:10 -070014/* crosstest.py --test=test_icmp.cpp --test=test_icmp_i1vec.ll \
15 --driver=test_icmp_main.cpp --prefix=Subzero_ --output=test_icmp */
16
17#include <climits> // CHAR_BIT
18#include <cstring> // memcmp, memset
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070019#include <iostream>
Antonio Maioranoca8a16e2020-11-10 16:56:20 -050020#include <stdint.h>
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070021
22// Include test_icmp.h twice - once normally, and once within the
23// Subzero_ namespace, corresponding to the llc and Subzero translated
24// object files, respectively.
25#include "test_icmp.h"
John Porto1d235422015-08-12 12:37:53 -070026
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070027namespace Subzero_ {
28#include "test_icmp.h"
29}
30
Jim Stichnoth57a8aab2016-01-06 09:34:36 -080031#include "insertelement.h"
John Porto1d235422015-08-12 12:37:53 -070032#include "xdefs.h"
33
Jim Stichnothdd842db2015-01-27 12:53:53 -080034volatile unsigned Values[] = {
35 0x0, 0x1, 0x7ffffffe, 0x7fffffff, 0x80000000, 0x80000001,
36 0xfffffffe, 0xffffffff, 0x7e, 0x7f, 0x80, 0x81,
37 0xfe, 0xff, 0x100, 0x101, 0x7ffe, 0x7fff,
38 0x8000, 0x8001, 0xfffe, 0xffff, 0x10000, 0x10001,
39};
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070040const static size_t NumValues = sizeof(Values) / sizeof(*Values);
41
42template <typename TypeUnsigned, typename TypeSigned>
43void testsInt(size_t &TotalTests, size_t &Passes, size_t &Failures) {
44 typedef bool (*FuncTypeUnsigned)(TypeUnsigned, TypeUnsigned);
45 typedef bool (*FuncTypeSigned)(TypeSigned, TypeSigned);
46 static struct {
47 const char *Name;
48 FuncTypeUnsigned FuncLlc;
49 FuncTypeUnsigned FuncSz;
50 } Funcs[] = {
51#define X(cmp, op) \
Antonio Maioranoca8a16e2020-11-10 16:56:20 -050052 {STR(cmp), (FuncTypeUnsigned)icmp##cmp, \
53 (FuncTypeUnsigned)Subzero_::icmp##cmp},
Jim Stichnothd9dc82e2015-03-03 17:06:33 -080054 ICMP_U_TABLE
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070055#undef X
56#define X(cmp, op) \
Antonio Maioranoca8a16e2020-11-10 16:56:20 -050057 {STR(cmp), (FuncTypeUnsigned)(FuncTypeSigned)icmp##cmp, \
58 (FuncTypeUnsigned)(FuncTypeSigned)Subzero_::icmp##cmp},
Jim Stichnothd9dc82e2015-03-03 17:06:33 -080059 ICMP_S_TABLE
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070060#undef X
Jim Stichnothd9dc82e2015-03-03 17:06:33 -080061 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070062 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
63
64 if (sizeof(TypeUnsigned) <= sizeof(uint32_t)) {
65 // This is the "normal" version of the loop nest, for 32-bit or
66 // narrower types.
67 for (size_t f = 0; f < NumFuncs; ++f) {
68 for (size_t i = 0; i < NumValues; ++i) {
69 for (size_t j = 0; j < NumValues; ++j) {
70 TypeUnsigned Value1 = Values[i];
71 TypeUnsigned Value2 = Values[j];
72 ++TotalTests;
73 bool ResultSz = Funcs[f].FuncSz(Value1, Value2);
74 bool ResultLlc = Funcs[f].FuncLlc(Value1, Value2);
75 if (ResultSz == ResultLlc) {
76 ++Passes;
77 } else {
78 ++Failures;
Matt Wala9a0168a2014-07-23 14:56:10 -070079 std::cout << "icmp" << Funcs[f].Name
80 << (CHAR_BIT * sizeof(TypeUnsigned)) << "(" << Value1
81 << ", " << Value2 << "): sz=" << ResultSz
Jim Stichnoth7da431b2014-08-05 11:22:37 -070082 << " llc=" << ResultLlc << "\n";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070083 }
84 }
85 }
86 }
87 } else {
88 // This is the 64-bit version. Test values are synthesized from
89 // the 32-bit values in Values[].
90 for (size_t f = 0; f < NumFuncs; ++f) {
91 for (size_t iLo = 0; iLo < NumValues; ++iLo) {
92 for (size_t iHi = 0; iHi < NumValues; ++iHi) {
93 for (size_t jLo = 0; jLo < NumValues; ++jLo) {
94 for (size_t jHi = 0; jHi < NumValues; ++jHi) {
95 TypeUnsigned Value1 =
96 (((TypeUnsigned)Values[iHi]) << 32) + Values[iLo];
97 TypeUnsigned Value2 =
98 (((TypeUnsigned)Values[jHi]) << 32) + Values[jLo];
99 ++TotalTests;
100 bool ResultSz = Funcs[f].FuncSz(Value1, Value2);
101 bool ResultLlc = Funcs[f].FuncLlc(Value1, Value2);
102 if (ResultSz == ResultLlc) {
103 ++Passes;
104 } else {
105 ++Failures;
106 std::cout << "icmp" << Funcs[f].Name
Matt Wala9a0168a2014-07-23 14:56:10 -0700107 << (CHAR_BIT * sizeof(TypeUnsigned)) << "(" << Value1
108 << ", " << Value2 << "): sz=" << ResultSz
Jim Stichnoth7da431b2014-08-05 11:22:37 -0700109 << " llc=" << ResultLlc << "\n";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700110 }
111 }
112 }
113 }
114 }
115 }
116 }
117}
118
David Sehr5c875422015-10-15 10:38:53 -0700119template <typename TypeUnsigned, typename TypeSigned>
120void testsIntWithZero(size_t &TotalTests, size_t &Passes, size_t &Failures) {
121 typedef bool (*FuncTypeUnsigned)(TypeUnsigned);
122 typedef bool (*FuncTypeSigned)(TypeSigned);
123 static struct {
124 const char *Name;
125 FuncTypeUnsigned FuncLlc;
126 FuncTypeUnsigned FuncSz;
127 } Funcs[] = {
128#define X(cmp, op) \
Antonio Maioranoca8a16e2020-11-10 16:56:20 -0500129 {STR(cmp), (FuncTypeUnsigned)icmp_zero##cmp, \
130 (FuncTypeUnsigned)Subzero_::icmp_zero##cmp},
David Sehr5c875422015-10-15 10:38:53 -0700131 ICMP_U_TABLE
132#undef X
133#define X(cmp, op) \
Antonio Maioranoca8a16e2020-11-10 16:56:20 -0500134 {STR(cmp), (FuncTypeUnsigned)(FuncTypeSigned)icmp_zero##cmp, \
135 (FuncTypeUnsigned)(FuncTypeSigned)Subzero_::icmp_zero##cmp},
David Sehr5c875422015-10-15 10:38:53 -0700136 ICMP_S_TABLE
137#undef X
138 };
139 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
140
141 if (sizeof(TypeUnsigned) <= sizeof(uint32_t)) {
142 // This is the "normal" version of the loop nest, for 32-bit or
143 // narrower types.
144 for (size_t f = 0; f < NumFuncs; ++f) {
145 for (size_t i = 0; i < NumValues; ++i) {
146 TypeUnsigned Value = Values[i];
147 ++TotalTests;
148 bool ResultSz = Funcs[f].FuncSz(Value);
149 bool ResultLlc = Funcs[f].FuncLlc(Value);
150 if (ResultSz == ResultLlc) {
151 ++Passes;
152 } else {
153 ++Failures;
154 std::cout << "icmp" << Funcs[f].Name
155 << (CHAR_BIT * sizeof(TypeUnsigned)) << "(" << Value
156 << "): sz=" << ResultSz << " llc=" << ResultLlc << "\n";
157 }
158 }
159 }
160 } else {
161 // This is the 64-bit version. Test values are synthesized from
162 // the 32-bit values in Values[].
163 for (size_t f = 0; f < NumFuncs; ++f) {
164 for (size_t iLo = 0; iLo < NumValues; ++iLo) {
165 for (size_t iHi = 0; iHi < NumValues; ++iHi) {
166 TypeUnsigned Value =
167 (((TypeUnsigned)Values[iHi]) << 32) + Values[iLo];
168 ++TotalTests;
169 bool ResultSz = Funcs[f].FuncSz(Value);
170 bool ResultLlc = Funcs[f].FuncLlc(Value);
171 if (ResultSz == ResultLlc) {
172 ++Passes;
173 } else {
174 ++Failures;
175 std::cout << "icmp" << Funcs[f].Name
176 << (CHAR_BIT * sizeof(TypeUnsigned)) << "(" << Value
177 << "): sz=" << ResultSz << " llc=" << ResultLlc << "\n";
178 }
179 }
180 }
181 }
182 }
183}
184
Matt Wala9a0168a2014-07-23 14:56:10 -0700185const static size_t MaxTestsPerFunc = 100000;
186
187template <typename TypeUnsignedLabel, typename TypeSignedLabel>
188void testsVecInt(size_t &TotalTests, size_t &Passes, size_t &Failures) {
189 typedef typename Vectors<TypeUnsignedLabel>::Ty TypeUnsigned;
190 typedef typename Vectors<TypeSignedLabel>::Ty TypeSigned;
Jim Stichnoth57a8aab2016-01-06 09:34:36 -0800191 typedef typename Vectors<TypeUnsignedLabel>::ElementTy ElementTypeUnsigned;
192 typedef typename Vectors<TypeSignedLabel>::ElementTy ElementTypeSigned;
Matt Wala9a0168a2014-07-23 14:56:10 -0700193 typedef TypeUnsigned (*FuncTypeUnsigned)(TypeUnsigned, TypeUnsigned);
194 typedef TypeSigned (*FuncTypeSigned)(TypeSigned, TypeSigned);
195 static struct {
196 const char *Name;
197 FuncTypeUnsigned FuncLlc;
198 FuncTypeUnsigned FuncSz;
199 } Funcs[] = {
200#define X(cmp, op) \
Antonio Maioranoca8a16e2020-11-10 16:56:20 -0500201 {STR(cmp), (FuncTypeUnsigned)icmp##cmp, \
202 (FuncTypeUnsigned)Subzero_::icmp##cmp},
Jim Stichnothd9dc82e2015-03-03 17:06:33 -0800203 ICMP_U_TABLE
Matt Wala9a0168a2014-07-23 14:56:10 -0700204#undef X
205#define X(cmp, op) \
Antonio Maioranoca8a16e2020-11-10 16:56:20 -0500206 {STR(cmp), (FuncTypeUnsigned)(FuncTypeSigned)icmp##cmp, \
207 (FuncTypeUnsigned)(FuncTypeSigned)Subzero_::icmp##cmp},
Jim Stichnothd9dc82e2015-03-03 17:06:33 -0800208 ICMP_S_TABLE
Matt Wala9a0168a2014-07-23 14:56:10 -0700209#undef X
Jim Stichnothd9dc82e2015-03-03 17:06:33 -0800210 };
Matt Wala9a0168a2014-07-23 14:56:10 -0700211 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
212 const static size_t NumElementsInType = Vectors<TypeUnsigned>::NumElements;
213 for (size_t f = 0; f < NumFuncs; ++f) {
214 PRNG Index;
215 for (size_t i = 0; i < MaxTestsPerFunc; ++i) {
216 // Initialize the test vectors.
217 TypeUnsigned Value1, Value2;
Jim Stichnoth57a8aab2016-01-06 09:34:36 -0800218 for (size_t j = 0; j < NumElementsInType; ++j) {
219 setElement(Value1, j, Values[Index() % NumValues]);
220 setElement(Value2, j, Values[Index() % NumValues]);
Matt Wala9a0168a2014-07-23 14:56:10 -0700221 }
222 // Perform the test.
223 TypeUnsigned ResultSz = Funcs[f].FuncSz(Value1, Value2);
224 TypeUnsigned ResultLlc = Funcs[f].FuncLlc(Value1, Value2);
225 ++TotalTests;
226 if (!memcmp(&ResultSz, &ResultLlc, sizeof(ResultSz))) {
227 ++Passes;
228 } else {
229 ++Failures;
230 std::cout << "test" << Funcs[f].Name
231 << Vectors<TypeUnsignedLabel>::TypeName << "("
232 << vectAsString<TypeUnsignedLabel>(Value1) << ","
233 << vectAsString<TypeUnsignedLabel>(Value2)
234 << "): sz=" << vectAsString<TypeUnsignedLabel>(ResultSz)
235 << " llc=" << vectAsString<TypeUnsignedLabel>(ResultLlc)
Jim Stichnoth7da431b2014-08-05 11:22:37 -0700236 << "\n";
Matt Wala9a0168a2014-07-23 14:56:10 -0700237 }
238 }
239 }
240}
241
242// Return true on wraparound
Jim Stichnoth57a8aab2016-01-06 09:34:36 -0800243template <typename T>
244bool __attribute__((noinline))
245incrementI1Vector(typename Vectors<T>::Ty &Vect) {
Matt Wala9a0168a2014-07-23 14:56:10 -0700246 size_t Pos = 0;
247 const static size_t NumElements = Vectors<T>::NumElements;
248 for (Pos = 0; Pos < NumElements; ++Pos) {
249 if (Vect[Pos] == 0) {
250 Vect[Pos] = 1;
251 break;
252 }
253 Vect[Pos] = 0;
254 }
255 return (Pos == NumElements);
256}
257
258template <typename T>
259void testsVecI1(size_t &TotalTests, size_t &Passes, size_t &Failures) {
260 typedef typename Vectors<T>::Ty Ty;
261 typedef Ty (*FuncType)(Ty, Ty);
262 static struct {
263 const char *Name;
264 FuncType FuncLlc;
265 FuncType FuncSz;
266 } Funcs[] = {
267#define X(cmp, op) \
Antonio Maioranoca8a16e2020-11-10 16:56:20 -0500268 {STR(cmp), (FuncType)icmpi1##cmp, (FuncType)Subzero_::icmpi1##cmp},
Jim Stichnothd9dc82e2015-03-03 17:06:33 -0800269 ICMP_U_TABLE ICMP_S_TABLE};
Matt Wala9a0168a2014-07-23 14:56:10 -0700270 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
271 const static size_t NumElements = Vectors<T>::NumElements;
272 const static size_t MAX_NUMBER_OF_ELEMENTS_FOR_EXHAUSTIVE_TESTING = 8;
273
274 // Check if the type is small enough to try all possible input pairs.
275 if (NumElements <= MAX_NUMBER_OF_ELEMENTS_FOR_EXHAUSTIVE_TESTING) {
276 for (size_t f = 0; f < NumFuncs; ++f) {
277 Ty Value1, Value2;
278 memset(&Value1, 0, sizeof(Value1));
279 for (bool IsValue1Done = false; !IsValue1Done;
280 IsValue1Done = incrementI1Vector<T>(Value1)) {
281 memset(&Value2, 0, sizeof(Value2));
282 for (bool IsValue2Done = false; !IsValue2Done;
283 IsValue2Done = incrementI1Vector<T>(Value2)) {
284 Ty ResultSz = Funcs[f].FuncSz(Value1, Value2);
285 Ty ResultLlc = Funcs[f].FuncLlc(Value1, Value2);
286 ++TotalTests;
287 if (!memcmp(&ResultSz, &ResultLlc, sizeof(ResultSz))) {
288 ++Passes;
289 } else {
290 ++Failures;
291 std::cout << "test" << Funcs[f].Name << Vectors<T>::TypeName << "("
292 << vectAsString<T>(Value1) << ","
293 << vectAsString<T>(Value2)
294 << "): sz=" << vectAsString<T>(ResultSz)
Jim Stichnoth7da431b2014-08-05 11:22:37 -0700295 << " llc=" << vectAsString<T>(ResultLlc) << "\n";
Matt Wala9a0168a2014-07-23 14:56:10 -0700296 }
297 }
298 }
299 }
300 } else {
301 for (size_t f = 0; f < NumFuncs; ++f) {
302 PRNG Index;
303 for (size_t i = 0; i < MaxTestsPerFunc; ++i) {
304 Ty Value1, Value2;
305 // Initialize the test vectors.
306 for (size_t j = 0; j < NumElements; ++j) {
Jim Stichnoth57a8aab2016-01-06 09:34:36 -0800307 setElement(Value1, j, Index() % 2);
308 setElement(Value2, j, Index() % 2);
Matt Wala9a0168a2014-07-23 14:56:10 -0700309 }
310 // Perform the test.
311 Ty ResultSz = Funcs[f].FuncSz(Value1, Value2);
312 Ty ResultLlc = Funcs[f].FuncLlc(Value1, Value2);
313 ++TotalTests;
314 if (!memcmp(&ResultSz, &ResultLlc, sizeof(ResultSz))) {
315 ++Passes;
316 } else {
317 ++Failures;
318 std::cout << "test" << Funcs[f].Name << Vectors<T>::TypeName << "("
319 << vectAsString<T>(Value1) << "," << vectAsString<T>(Value2)
320 << "): sz=" << vectAsString<T>(ResultSz)
Jim Stichnoth7da431b2014-08-05 11:22:37 -0700321 << " llc=" << vectAsString<T>(ResultLlc) << "\n";
Matt Wala9a0168a2014-07-23 14:56:10 -0700322 }
323 }
324 }
325 }
326}
327
John Porto1d235422015-08-12 12:37:53 -0700328int main(int argc, char *argv[]) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700329 size_t TotalTests = 0;
330 size_t Passes = 0;
331 size_t Failures = 0;
332
Jim Stichnoth7da431b2014-08-05 11:22:37 -0700333 testsInt<uint8_t, myint8_t>(TotalTests, Passes, Failures);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700334 testsInt<uint16_t, int16_t>(TotalTests, Passes, Failures);
335 testsInt<uint32_t, int32_t>(TotalTests, Passes, Failures);
John Porto1d235422015-08-12 12:37:53 -0700336 testsInt<uint64, int64>(TotalTests, Passes, Failures);
David Sehr5c875422015-10-15 10:38:53 -0700337 testsIntWithZero<uint8_t, myint8_t>(TotalTests, Passes, Failures);
338 testsIntWithZero<uint16_t, int16_t>(TotalTests, Passes, Failures);
339 testsIntWithZero<uint32_t, int32_t>(TotalTests, Passes, Failures);
340 testsIntWithZero<uint64, int64>(TotalTests, Passes, Failures);
Matt Wala9a0168a2014-07-23 14:56:10 -0700341 testsVecInt<v4ui32, v4si32>(TotalTests, Passes, Failures);
342 testsVecInt<v8ui16, v8si16>(TotalTests, Passes, Failures);
343 testsVecInt<v16ui8, v16si8>(TotalTests, Passes, Failures);
344 testsVecI1<v4i1>(TotalTests, Passes, Failures);
345 testsVecI1<v8i1>(TotalTests, Passes, Failures);
346 testsVecI1<v16i1>(TotalTests, Passes, Failures);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700347
348 std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes
349 << " Failures=" << Failures << "\n";
350 return Failures;
351}