| //===- subzero/crosstest/test_vector_ops_main.cpp - Driver for tests ------===// | |
| // | |
| // The Subzero Code Generator | |
| // | |
| // This file is distributed under the University of Illinois Open Source | |
| // License. See LICENSE.TXT for details. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // Driver for crosstesting insertelement and extractelement operations | |
| // | |
| //===----------------------------------------------------------------------===// | |
| /* crosstest.py --test=test_vector_ops.ll --driver=test_vector_ops_main.cpp \ | |
| --prefix=Subzero_ --output=test_vector_ops */ | |
| #include <cstring> | |
| #include <iostream> | |
| #include <limits> | |
| #include <stdlib.h> | |
| #include "test_vector_ops.h" | |
| // Return a set of test vectors for the given vector type. Due to lack | |
| // of an aligned allocator in C++, the returned value is allocated with | |
| // posix_memalign() and should be freed with free(). | |
| template <typename T> | |
| typename VectorOps<T>::Ty *getTestVectors(size_t &NumTestVectors) { | |
| typedef typename VectorOps<T>::Ty Ty; | |
| typedef typename VectorOps<T>::ElementTy ElementTy; | |
| Ty Zero; | |
| memset(&Zero, 0, sizeof(Zero)); | |
| Ty Incr; | |
| // Note: The casts in the next two initializations are necessary, | |
| // since ElementTy isn't necessarily the type that the value is stored | |
| // in the vector. | |
| for (int I = 0; I < VectorOps<T>::NumElements; ++I) | |
| Incr[I] = (ElementTy)I; | |
| Ty Decr; | |
| for (int I = 0; I < VectorOps<T>::NumElements; ++I) | |
| Decr[I] = (ElementTy)-I; | |
| Ty Min; | |
| for (int I = 0; I < VectorOps<T>::NumElements; ++I) | |
| Min[I] = std::numeric_limits<ElementTy>::min(); | |
| Ty Max; | |
| for (int I = 0; I < VectorOps<T>::NumElements; ++I) | |
| Max[I] = std::numeric_limits<ElementTy>::max(); | |
| Ty TestVectors[] = {Zero, Incr, Decr, Min, Max}; | |
| NumTestVectors = sizeof(TestVectors) / sizeof(Ty); | |
| const size_t VECTOR_ALIGNMENT = 16; | |
| void *Dest; | |
| if (posix_memalign(&Dest, VECTOR_ALIGNMENT, sizeof(TestVectors))) { | |
| std::cerr << "memory allocation error\n"; | |
| abort(); | |
| } | |
| memcpy(Dest, TestVectors, sizeof(TestVectors)); | |
| return static_cast<Ty *>(Dest); | |
| } | |
| template <typename T> | |
| void testInsertElement(size_t &TotalTests, size_t &Passes, size_t &Failures) { | |
| typedef typename VectorOps<T>::Ty Ty; | |
| typedef typename VectorOps<T>::ElementTy ElementTy; | |
| size_t NumTestVectors; | |
| Ty *TestVectors = getTestVectors<T>(NumTestVectors); | |
| ElementTy TestElements[] = {0, 1, std::numeric_limits<ElementTy>::min(), | |
| std::numeric_limits<ElementTy>::max()}; | |
| const size_t NumTestElements = sizeof(TestElements) / sizeof(ElementTy); | |
| for (size_t VI = 0; VI < NumTestVectors; ++VI) { | |
| Ty Vect = TestVectors[VI]; | |
| for (size_t EI = 0; EI < NumTestElements; ++EI) { | |
| ElementTy Elt = TestElements[EI]; | |
| for (size_t I = 0; I < VectorOps<T>::NumElements; ++I) { | |
| Ty ResultLlc = VectorOps<T>::insertelement(Vect, Elt, I); | |
| Ty ResultSz = VectorOps<T>::Subzero_insertelement(Vect, Elt, I); | |
| ++TotalTests; | |
| if (!memcmp(&ResultLlc, &ResultSz, sizeof(ResultLlc))) { | |
| ++Passes; | |
| } else { | |
| ++Failures; | |
| std::cout << "insertelement<" << VectorOps<T>::TypeName << ">(Vect="; | |
| std::cout << vectAsString<T>(Vect) | |
| << ", Element=" << (typename VectorOps<T>::CastTy)Elt | |
| << ", Pos=" << I << ")\n"; | |
| std::cout << "llc=" << vectAsString<T>(ResultLlc) << "\n"; | |
| std::cout << "sz =" << vectAsString<T>(ResultSz) << "\n"; | |
| } | |
| } | |
| } | |
| } | |
| free(TestVectors); | |
| } | |
| template <typename T> | |
| void testExtractElement(size_t &TotalTests, size_t &Passes, size_t &Failures) { | |
| typedef typename VectorOps<T>::Ty Ty; | |
| typedef typename VectorOps<T>::ElementTy ElementTy; | |
| typedef typename VectorOps<T>::CastTy CastTy; | |
| size_t NumTestVectors; | |
| Ty *TestVectors = getTestVectors<T>(NumTestVectors); | |
| for (size_t VI = 0; VI < NumTestVectors; ++VI) { | |
| Ty Vect = TestVectors[VI]; | |
| for (size_t I = 0; I < VectorOps<T>::NumElements; ++I) { | |
| CastTy ResultLlc = VectorOps<T>::extractelement(Vect, I); | |
| CastTy ResultSz = VectorOps<T>::Subzero_extractelement(Vect, I); | |
| ++TotalTests; | |
| if (!memcmp(&ResultLlc, &ResultSz, sizeof(ResultLlc))) { | |
| ++Passes; | |
| } else { | |
| ++Failures; | |
| std::cout << "extractelement<" << VectorOps<T>::TypeName << ">(Vect="; | |
| std::cout << vectAsString<T>(Vect) << ", Pos=" << I << ")\n"; | |
| std::cout << "llc=" << ResultLlc << "\n"; | |
| std::cout << "sz =" << ResultSz << "\n"; | |
| } | |
| } | |
| } | |
| free(TestVectors); | |
| } | |
| template <typename T> | |
| void testShuffleVector(size_t &TotalTests, size_t &Passes, size_t &Failures) { | |
| typedef typename VectorOps<T>::Ty Ty; | |
| typedef typename VectorOps<T>::ElementTy ElementTy; | |
| size_t NumTestVectors; | |
| Ty *TestVectors = getTestVectors<T>(NumTestVectors); | |
| for (size_t VI = 0; VI < NumTestVectors; ++VI) { | |
| Ty Vect0 = TestVectors[VI]; | |
| for (size_t VJ = 0; VJ < NumTestVectors; ++VJ) { | |
| Ty Vect1 = TestVectors[VJ]; | |
| for (uint32_t Which = 0; Which < VectorOps<T>::shufflevector_count(); | |
| ++Which) { | |
| Ty ResultLlc = VectorOps<T>::shufflevector(Vect0, Vect1, Which); | |
| Ty ResultSz = VectorOps<T>::Subzero_shufflevector(Vect0, Vect1, Which); | |
| ++TotalTests; | |
| if (!memcmp(&ResultLlc, &ResultSz, sizeof(ResultLlc))) { | |
| ++Passes; | |
| } else { | |
| ++Failures; | |
| std::cout << "shufflevector<" << VectorOps<T>::TypeName << ">(Vect0="; | |
| std::cout << vectAsString<T>(Vect0) | |
| << ", Vect1=" << vectAsString<T>(Vect1) << ", Which=" << VJ | |
| << ")\n"; | |
| std::cout << "llc=" << vectAsString<T>(ResultLlc) << "\n"; | |
| std::cout << "sz =" << vectAsString<T>(ResultSz) << "\n"; | |
| } | |
| } | |
| } | |
| } | |
| free(TestVectors); | |
| } | |
| int main(int argc, char *argv[]) { | |
| size_t TotalTests = 0; | |
| size_t Passes = 0; | |
| size_t Failures = 0; | |
| testInsertElement<v4i1>(TotalTests, Passes, Failures); | |
| testInsertElement<v8i1>(TotalTests, Passes, Failures); | |
| testInsertElement<v16i1>(TotalTests, Passes, Failures); | |
| testInsertElement<v16si8>(TotalTests, Passes, Failures); | |
| testInsertElement<v16ui8>(TotalTests, Passes, Failures); | |
| testInsertElement<v8si16>(TotalTests, Passes, Failures); | |
| testInsertElement<v8ui16>(TotalTests, Passes, Failures); | |
| testInsertElement<v4si32>(TotalTests, Passes, Failures); | |
| testInsertElement<v4ui32>(TotalTests, Passes, Failures); | |
| testInsertElement<v4f32>(TotalTests, Passes, Failures); | |
| testExtractElement<v4i1>(TotalTests, Passes, Failures); | |
| testExtractElement<v8i1>(TotalTests, Passes, Failures); | |
| testExtractElement<v16i1>(TotalTests, Passes, Failures); | |
| testExtractElement<v16si8>(TotalTests, Passes, Failures); | |
| testExtractElement<v16ui8>(TotalTests, Passes, Failures); | |
| testExtractElement<v8si16>(TotalTests, Passes, Failures); | |
| testExtractElement<v8ui16>(TotalTests, Passes, Failures); | |
| testExtractElement<v4si32>(TotalTests, Passes, Failures); | |
| testExtractElement<v4ui32>(TotalTests, Passes, Failures); | |
| testExtractElement<v4f32>(TotalTests, Passes, Failures); | |
| testShuffleVector<v4i1>(TotalTests, Passes, Failures); | |
| testShuffleVector<v8i1>(TotalTests, Passes, Failures); | |
| testShuffleVector<v16i1>(TotalTests, Passes, Failures); | |
| testShuffleVector<v16si8>(TotalTests, Passes, Failures); | |
| testShuffleVector<v16ui8>(TotalTests, Passes, Failures); | |
| testShuffleVector<v8si16>(TotalTests, Passes, Failures); | |
| testShuffleVector<v8ui16>(TotalTests, Passes, Failures); | |
| testShuffleVector<v4si32>(TotalTests, Passes, Failures); | |
| testShuffleVector<v4ui32>(TotalTests, Passes, Failures); | |
| testShuffleVector<v4f32>(TotalTests, Passes, Failures); | |
| std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes | |
| << " Failures=" << Failures << "\n"; | |
| return Failures; | |
| } |