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