Matt Wala | 89a7c2b | 2014-07-22 10:55:30 -0700 | [diff] [blame] | 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 | |
Matt Wala | 4988923 | 2014-07-18 12:45:09 -0700 | [diff] [blame] | 14 | /* crosstest.py --test=test_vector_ops.ll --driver=test_vector_ops_main.cpp \ |
| 15 | --prefix=Subzero_ --output=test_vector_ops */ |
| 16 | |
Matt Wala | 4988923 | 2014-07-18 12:45:09 -0700 | [diff] [blame] | 17 | #include <cstring> |
Matt Wala | 4988923 | 2014-07-18 12:45:09 -0700 | [diff] [blame] | 18 | #include <iostream> |
| 19 | #include <limits> |
Matt Wala | 4988923 | 2014-07-18 12:45:09 -0700 | [diff] [blame] | 20 | #include <stdlib.h> |
| 21 | |
Matt Wala | 89a7c2b | 2014-07-22 10:55:30 -0700 | [diff] [blame] | 22 | #include "test_vector_ops.h" |
Matt Wala | 4988923 | 2014-07-18 12:45:09 -0700 | [diff] [blame] | 23 | |
Matt Wala | 89a7c2b | 2014-07-22 10:55:30 -0700 | [diff] [blame] | 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(). |
Matt Wala | 4988923 | 2014-07-18 12:45:09 -0700 | [diff] [blame] | 27 | template <typename T> |
| 28 | typename 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" << std::endl; |
| 57 | abort(); |
| 58 | } |
| 59 | |
| 60 | memcpy(Dest, TestVectors, sizeof(TestVectors)); |
| 61 | |
| 62 | return static_cast<Ty *>(Dest); |
| 63 | } |
| 64 | |
| 65 | template <typename T> |
| 66 | void 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 << ")" << std::endl; |
| 93 | std::cout << "llc=" << vectAsString<T>(ResultLlc) << std::endl; |
| 94 | std::cout << "sz =" << vectAsString<T>(ResultSz) << std::endl; |
| 95 | } |
| 96 | } |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | free(TestVectors); |
| 101 | } |
| 102 | |
| 103 | template <typename T> |
| 104 | void 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 << ")" << std::endl; |
| 124 | std::cout << "llc=" << ResultLlc << std::endl; |
| 125 | std::cout << "sz =" << ResultSz << std::endl; |
| 126 | } |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | free(TestVectors); |
| 131 | } |
| 132 | |
| 133 | int main(int argc, char *argv[]) { |
| 134 | size_t TotalTests = 0; |
| 135 | size_t Passes = 0; |
| 136 | size_t Failures = 0; |
| 137 | |
| 138 | testInsertElement<v4i1>(TotalTests, Passes, Failures); |
| 139 | testInsertElement<v8i1>(TotalTests, Passes, Failures); |
| 140 | testInsertElement<v16i1>(TotalTests, Passes, Failures); |
| 141 | testInsertElement<v16si8>(TotalTests, Passes, Failures); |
| 142 | testInsertElement<v16ui8>(TotalTests, Passes, Failures); |
| 143 | testInsertElement<v8si16>(TotalTests, Passes, Failures); |
| 144 | testInsertElement<v8ui16>(TotalTests, Passes, Failures); |
| 145 | testInsertElement<v4si32>(TotalTests, Passes, Failures); |
| 146 | testInsertElement<v4ui32>(TotalTests, Passes, Failures); |
| 147 | testInsertElement<v4f32>(TotalTests, Passes, Failures); |
| 148 | |
| 149 | testExtractElement<v4i1>(TotalTests, Passes, Failures); |
| 150 | testExtractElement<v8i1>(TotalTests, Passes, Failures); |
| 151 | testExtractElement<v16i1>(TotalTests, Passes, Failures); |
| 152 | testExtractElement<v16si8>(TotalTests, Passes, Failures); |
| 153 | testExtractElement<v16ui8>(TotalTests, Passes, Failures); |
| 154 | testExtractElement<v8si16>(TotalTests, Passes, Failures); |
| 155 | testExtractElement<v8ui16>(TotalTests, Passes, Failures); |
| 156 | testExtractElement<v4si32>(TotalTests, Passes, Failures); |
| 157 | testExtractElement<v4ui32>(TotalTests, Passes, Failures); |
| 158 | testExtractElement<v4f32>(TotalTests, Passes, Failures); |
| 159 | |
| 160 | std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes |
| 161 | << " Failures=" << Failures << "\n"; |
| 162 | |
| 163 | return Failures; |
| 164 | } |
| 165 | |
| 166 | extern "C" { |
| 167 | |
| 168 | void ice_unreachable(void) { |
| 169 | std::cerr << "\"unreachable\" instruction encountered" << std::endl; |
| 170 | abort(); |
| 171 | } |
| 172 | } |