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