1 //===- subzero/crosstest/test_vector_ops_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 insertelement and extractelement operations
11 //
12 //===----------------------------------------------------------------------===//
13 
14 /* crosstest.py --test=test_vector_ops.ll  --driver=test_vector_ops_main.cpp \
15    --prefix=Subzero_ --output=test_vector_ops */
16 
17 #include <cstring>
18 #include <iostream>
19 #include <limits>
20 #include <stdlib.h>
21 
22 #include "test_vector_ops.h"
23 
24 // Return a set of test vectors for the given vector type. Due to lack
25 // of an aligned allocator in C++, the returned value is allocated with
26 // posix_memalign() and should be freed with free().
27 template <typename T>
getTestVectors(size_t & NumTestVectors)28 typename VectorOps<T>::Ty *getTestVectors(size_t &NumTestVectors) {
29   typedef typename VectorOps<T>::Ty Ty;
30   typedef typename VectorOps<T>::ElementTy ElementTy;
31 
32   Ty Zero;
33   memset(&Zero, 0, sizeof(Zero));
34   Ty Incr;
35   // Note: The casts in the next two initializations are necessary,
36   // since ElementTy isn't necessarily the type that the value is stored
37   // in the vector.
38   for (int I = 0; I < VectorOps<T>::NumElements; ++I)
39     Incr[I] = (ElementTy)I;
40   Ty Decr;
41   for (int I = 0; I < VectorOps<T>::NumElements; ++I)
42     Decr[I] = (ElementTy)-I;
43   Ty Min;
44   for (int I = 0; I < VectorOps<T>::NumElements; ++I)
45     Min[I] = std::numeric_limits<ElementTy>::min();
46   Ty Max;
47   for (int I = 0; I < VectorOps<T>::NumElements; ++I)
48     Max[I] = std::numeric_limits<ElementTy>::max();
49   Ty TestVectors[] = {Zero, Incr, Decr, Min, Max};
50 
51   NumTestVectors = sizeof(TestVectors) / sizeof(Ty);
52 
53   const size_t VECTOR_ALIGNMENT = 16;
54   void *Dest;
55   if (posix_memalign(&Dest, VECTOR_ALIGNMENT, sizeof(TestVectors))) {
56     std::cerr << "memory allocation error\n";
57     abort();
58   }
59 
60   memcpy(Dest, TestVectors, sizeof(TestVectors));
61 
62   return static_cast<Ty *>(Dest);
63 }
64 
65 template <typename T>
testInsertElement(size_t & TotalTests,size_t & Passes,size_t & Failures)66 void testInsertElement(size_t &TotalTests, size_t &Passes, size_t &Failures) {
67   typedef typename VectorOps<T>::Ty Ty;
68   typedef typename VectorOps<T>::ElementTy ElementTy;
69 
70   size_t NumTestVectors;
71   Ty *TestVectors = getTestVectors<T>(NumTestVectors);
72 
73   ElementTy TestElements[] = {0, 1, std::numeric_limits<ElementTy>::min(),
74                               std::numeric_limits<ElementTy>::max()};
75   const size_t NumTestElements = sizeof(TestElements) / sizeof(ElementTy);
76 
77   for (size_t VI = 0; VI < NumTestVectors; ++VI) {
78     Ty Vect = TestVectors[VI];
79     for (size_t EI = 0; EI < NumTestElements; ++EI) {
80       ElementTy Elt = TestElements[EI];
81       for (size_t I = 0; I < VectorOps<T>::NumElements; ++I) {
82         Ty ResultLlc = VectorOps<T>::insertelement(Vect, Elt, I);
83         Ty ResultSz = VectorOps<T>::Subzero_insertelement(Vect, Elt, I);
84         ++TotalTests;
85         if (!memcmp(&ResultLlc, &ResultSz, sizeof(ResultLlc))) {
86           ++Passes;
87         } else {
88           ++Failures;
89           std::cout << "insertelement<" << VectorOps<T>::TypeName << ">(Vect=";
90           std::cout << vectAsString<T>(Vect)
91                     << ", Element=" << (typename VectorOps<T>::CastTy)Elt
92                     << ", Pos=" << I << ")\n";
93           std::cout << "llc=" << vectAsString<T>(ResultLlc) << "\n";
94           std::cout << "sz =" << vectAsString<T>(ResultSz) << "\n";
95         }
96       }
97     }
98   }
99 
100   free(TestVectors);
101 }
102 
103 template <typename T>
testExtractElement(size_t & TotalTests,size_t & Passes,size_t & Failures)104 void testExtractElement(size_t &TotalTests, size_t &Passes, size_t &Failures) {
105   typedef typename VectorOps<T>::Ty Ty;
106   typedef typename VectorOps<T>::ElementTy ElementTy;
107   typedef typename VectorOps<T>::CastTy CastTy;
108 
109   size_t NumTestVectors;
110   Ty *TestVectors = getTestVectors<T>(NumTestVectors);
111 
112   for (size_t VI = 0; VI < NumTestVectors; ++VI) {
113     Ty Vect = TestVectors[VI];
114     for (size_t I = 0; I < VectorOps<T>::NumElements; ++I) {
115       CastTy ResultLlc = VectorOps<T>::extractelement(Vect, I);
116       CastTy ResultSz = VectorOps<T>::Subzero_extractelement(Vect, I);
117       ++TotalTests;
118       if (!memcmp(&ResultLlc, &ResultSz, sizeof(ResultLlc))) {
119         ++Passes;
120       } else {
121         ++Failures;
122         std::cout << "extractelement<" << VectorOps<T>::TypeName << ">(Vect=";
123         std::cout << vectAsString<T>(Vect) << ", Pos=" << I << ")\n";
124         std::cout << "llc=" << ResultLlc << "\n";
125         std::cout << "sz =" << ResultSz << "\n";
126       }
127     }
128   }
129 
130   free(TestVectors);
131 }
132 
133 template <typename T>
testShuffleVector(size_t & TotalTests,size_t & Passes,size_t & Failures)134 void testShuffleVector(size_t &TotalTests, size_t &Passes, size_t &Failures) {
135   typedef typename VectorOps<T>::Ty Ty;
136   typedef typename VectorOps<T>::ElementTy ElementTy;
137 
138   size_t NumTestVectors;
139   Ty *TestVectors = getTestVectors<T>(NumTestVectors);
140 
141   for (size_t VI = 0; VI < NumTestVectors; ++VI) {
142     Ty Vect0 = TestVectors[VI];
143     for (size_t VJ = 0; VJ < NumTestVectors; ++VJ) {
144       Ty Vect1 = TestVectors[VJ];
145       for (uint32_t Which = 0; Which < VectorOps<T>::shufflevector_count();
146            ++Which) {
147         Ty ResultLlc = VectorOps<T>::shufflevector(Vect0, Vect1, Which);
148         Ty ResultSz = VectorOps<T>::Subzero_shufflevector(Vect0, Vect1, Which);
149         ++TotalTests;
150         if (!memcmp(&ResultLlc, &ResultSz, sizeof(ResultLlc))) {
151           ++Passes;
152         } else {
153           ++Failures;
154           std::cout << "shufflevector<" << VectorOps<T>::TypeName << ">(Vect0=";
155           std::cout << vectAsString<T>(Vect0)
156                     << ", Vect1=" << vectAsString<T>(Vect1) << ", Which=" << VJ
157                     << ")\n";
158           std::cout << "llc=" << vectAsString<T>(ResultLlc) << "\n";
159           std::cout << "sz =" << vectAsString<T>(ResultSz) << "\n";
160         }
161       }
162     }
163   }
164 
165   free(TestVectors);
166 }
167 
main(int argc,char * argv[])168 int main(int argc, char *argv[]) {
169   size_t TotalTests = 0;
170   size_t Passes = 0;
171   size_t Failures = 0;
172 
173   testInsertElement<v4i1>(TotalTests, Passes, Failures);
174   testInsertElement<v8i1>(TotalTests, Passes, Failures);
175   testInsertElement<v16i1>(TotalTests, Passes, Failures);
176   testInsertElement<v16si8>(TotalTests, Passes, Failures);
177   testInsertElement<v16ui8>(TotalTests, Passes, Failures);
178   testInsertElement<v8si16>(TotalTests, Passes, Failures);
179   testInsertElement<v8ui16>(TotalTests, Passes, Failures);
180   testInsertElement<v4si32>(TotalTests, Passes, Failures);
181   testInsertElement<v4ui32>(TotalTests, Passes, Failures);
182   testInsertElement<v4f32>(TotalTests, Passes, Failures);
183 
184   testExtractElement<v4i1>(TotalTests, Passes, Failures);
185   testExtractElement<v8i1>(TotalTests, Passes, Failures);
186   testExtractElement<v16i1>(TotalTests, Passes, Failures);
187   testExtractElement<v16si8>(TotalTests, Passes, Failures);
188   testExtractElement<v16ui8>(TotalTests, Passes, Failures);
189   testExtractElement<v8si16>(TotalTests, Passes, Failures);
190   testExtractElement<v8ui16>(TotalTests, Passes, Failures);
191   testExtractElement<v4si32>(TotalTests, Passes, Failures);
192   testExtractElement<v4ui32>(TotalTests, Passes, Failures);
193   testExtractElement<v4f32>(TotalTests, Passes, Failures);
194 
195   testShuffleVector<v4i1>(TotalTests, Passes, Failures);
196   testShuffleVector<v8i1>(TotalTests, Passes, Failures);
197   testShuffleVector<v16i1>(TotalTests, Passes, Failures);
198   testShuffleVector<v16si8>(TotalTests, Passes, Failures);
199   testShuffleVector<v16ui8>(TotalTests, Passes, Failures);
200   testShuffleVector<v8si16>(TotalTests, Passes, Failures);
201   testShuffleVector<v8ui16>(TotalTests, Passes, Failures);
202   testShuffleVector<v4si32>(TotalTests, Passes, Failures);
203   testShuffleVector<v4ui32>(TotalTests, Passes, Failures);
204   testShuffleVector<v4f32>(TotalTests, Passes, Failures);
205 
206   std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes
207             << " Failures=" << Failures << "\n";
208 
209   return Failures;
210 }
211