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().
27template <typename T>
28typename 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
65template <typename T>
66void 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
103template <typename T>
104void 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
133template <typename T>
134void 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
168int 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