//===- 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 #include #include #include #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 VectorOps::Ty *getTestVectors(size_t &NumTestVectors) { typedef typename VectorOps::Ty Ty; typedef typename VectorOps::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::NumElements; ++I) Incr[I] = (ElementTy)I; Ty Decr; for (int I = 0; I < VectorOps::NumElements; ++I) Decr[I] = (ElementTy)-I; Ty Min; for (int I = 0; I < VectorOps::NumElements; ++I) Min[I] = std::numeric_limits::min(); Ty Max; for (int I = 0; I < VectorOps::NumElements; ++I) Max[I] = std::numeric_limits::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(Dest); } template void testInsertElement(size_t &TotalTests, size_t &Passes, size_t &Failures) { typedef typename VectorOps::Ty Ty; typedef typename VectorOps::ElementTy ElementTy; size_t NumTestVectors; Ty *TestVectors = getTestVectors(NumTestVectors); ElementTy TestElements[] = {0, 1, std::numeric_limits::min(), std::numeric_limits::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::NumElements; ++I) { Ty ResultLlc = VectorOps::insertelement(Vect, Elt, I); Ty ResultSz = VectorOps::Subzero_insertelement(Vect, Elt, I); ++TotalTests; if (!memcmp(&ResultLlc, &ResultSz, sizeof(ResultLlc))) { ++Passes; } else { ++Failures; std::cout << "insertelement<" << VectorOps::TypeName << ">(Vect="; std::cout << vectAsString(Vect) << ", Element=" << (typename VectorOps::CastTy)Elt << ", Pos=" << I << ")\n"; std::cout << "llc=" << vectAsString(ResultLlc) << "\n"; std::cout << "sz =" << vectAsString(ResultSz) << "\n"; } } } } free(TestVectors); } template void testExtractElement(size_t &TotalTests, size_t &Passes, size_t &Failures) { typedef typename VectorOps::Ty Ty; typedef typename VectorOps::ElementTy ElementTy; typedef typename VectorOps::CastTy CastTy; size_t NumTestVectors; Ty *TestVectors = getTestVectors(NumTestVectors); for (size_t VI = 0; VI < NumTestVectors; ++VI) { Ty Vect = TestVectors[VI]; for (size_t I = 0; I < VectorOps::NumElements; ++I) { CastTy ResultLlc = VectorOps::extractelement(Vect, I); CastTy ResultSz = VectorOps::Subzero_extractelement(Vect, I); ++TotalTests; if (!memcmp(&ResultLlc, &ResultSz, sizeof(ResultLlc))) { ++Passes; } else { ++Failures; std::cout << "extractelement<" << VectorOps::TypeName << ">(Vect="; std::cout << vectAsString(Vect) << ", Pos=" << I << ")\n"; std::cout << "llc=" << ResultLlc << "\n"; std::cout << "sz =" << ResultSz << "\n"; } } } free(TestVectors); } template void testShuffleVector(size_t &TotalTests, size_t &Passes, size_t &Failures) { typedef typename VectorOps::Ty Ty; typedef typename VectorOps::ElementTy ElementTy; size_t NumTestVectors; Ty *TestVectors = getTestVectors(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::shufflevector_count(); ++Which) { Ty ResultLlc = VectorOps::shufflevector(Vect0, Vect1, Which); Ty ResultSz = VectorOps::Subzero_shufflevector(Vect0, Vect1, Which); ++TotalTests; if (!memcmp(&ResultLlc, &ResultSz, sizeof(ResultLlc))) { ++Passes; } else { ++Failures; std::cout << "shufflevector<" << VectorOps::TypeName << ">(Vect0="; std::cout << vectAsString(Vect0) << ", Vect1=" << vectAsString(Vect1) << ", Which=" << VJ << ")\n"; std::cout << "llc=" << vectAsString(ResultLlc) << "\n"; std::cout << "sz =" << vectAsString(ResultSz) << "\n"; } } } } free(TestVectors); } int main(int argc, char *argv[]) { size_t TotalTests = 0; size_t Passes = 0; size_t Failures = 0; testInsertElement(TotalTests, Passes, Failures); testInsertElement(TotalTests, Passes, Failures); testInsertElement(TotalTests, Passes, Failures); testInsertElement(TotalTests, Passes, Failures); testInsertElement(TotalTests, Passes, Failures); testInsertElement(TotalTests, Passes, Failures); testInsertElement(TotalTests, Passes, Failures); testInsertElement(TotalTests, Passes, Failures); testInsertElement(TotalTests, Passes, Failures); testInsertElement(TotalTests, Passes, Failures); testExtractElement(TotalTests, Passes, Failures); testExtractElement(TotalTests, Passes, Failures); testExtractElement(TotalTests, Passes, Failures); testExtractElement(TotalTests, Passes, Failures); testExtractElement(TotalTests, Passes, Failures); testExtractElement(TotalTests, Passes, Failures); testExtractElement(TotalTests, Passes, Failures); testExtractElement(TotalTests, Passes, Failures); testExtractElement(TotalTests, Passes, Failures); testExtractElement(TotalTests, Passes, Failures); testShuffleVector(TotalTests, Passes, Failures); testShuffleVector(TotalTests, Passes, Failures); testShuffleVector(TotalTests, Passes, Failures); testShuffleVector(TotalTests, Passes, Failures); testShuffleVector(TotalTests, Passes, Failures); testShuffleVector(TotalTests, Passes, Failures); testShuffleVector(TotalTests, Passes, Failures); testShuffleVector(TotalTests, Passes, Failures); testShuffleVector(TotalTests, Passes, Failures); testShuffleVector(TotalTests, Passes, Failures); std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes << " Failures=" << Failures << "\n"; return Failures; }