blob: 9f274173aa4adbbbf6f2a1dbe46966ae786bf9b3 [file] [log] [blame]
//===- 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;
}