|  | //===- 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; | 
|  | } |