1//===- subzero/crosstest/test_fcmp_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 cross testing the fcmp bitcode instruction 11// 12//===----------------------------------------------------------------------===// 13 14/* crosstest.py --test=test_fcmp.pnacl.ll --driver=test_fcmp_main.cpp \ 15 --prefix=Subzero_ --output=test_fcmp */ 16 17#include <cassert> 18#include <cfloat> 19#include <cmath> 20#include <cstring> 21#include <iostream> 22 23#include "vectors.h" 24#include "test_arith.def" 25#include "test_fcmp.def" 26 27#define X(cmp) \ 28 extern "C" bool fcmp##cmp##Float(float a, float b); \ 29 extern "C" bool fcmp##cmp##Double(double a, double b); \ 30 extern "C" int fcmpSelect##cmp##Float(float a, float b, int c, int d); \ 31 extern "C" int fcmpSelect##cmp##Double(double a, double b, int c, int d); \ 32 extern "C" v4si32 fcmp##cmp##Vector(v4f32 a, v4f32 b); \ 33 extern "C" bool Subzero_fcmp##cmp##Float(float a, float b); \ 34 extern "C" bool Subzero_fcmp##cmp##Double(double a, double b); \ 35 extern "C" int Subzero_fcmpSelect##cmp##Float(float a, float b, int c, \ 36 int d); \ 37 extern "C" int Subzero_fcmpSelect##cmp##Double(double a, double b, int c, \ 38 int d); \ 39 extern "C" v4si32 Subzero_fcmp##cmp##Vector(v4f32 a, v4f32 b); 40FCMP_TABLE; 41#undef X 42 43volatile double *Values; 44size_t NumValues; 45 46void initializeValues() { 47 static const double NegInf = -1.0 / 0.0; 48 static const double Zero = 0.0; 49 static const double PosInf = 1.0 / 0.0; 50 static const double Nan = 0.0 / 0.0; 51 static const double NegNan = -0.0 / 0.0; 52 assert(std::fpclassify(NegInf) == FP_INFINITE); 53 assert(std::fpclassify(PosInf) == FP_INFINITE); 54 assert(std::fpclassify(Nan) == FP_NAN); 55 assert(std::fpclassify(NegNan) == FP_NAN); 56 assert(NegInf < Zero); 57 assert(NegInf < PosInf); 58 assert(Zero < PosInf); 59 static volatile double InitValues[] = 60 FP_VALUE_ARRAY(NegInf, PosInf, NegNan, Nan); 61 NumValues = sizeof(InitValues) / sizeof(*InitValues); 62 Values = InitValues; 63} 64 65void testsScalar(size_t &TotalTests, size_t &Passes, size_t &Failures) { 66 typedef bool (*FuncTypeFloat)(float, float); 67 typedef bool (*FuncTypeDouble)(double, double); 68 typedef int (*FuncTypeFloatSelect)(float, float, int, int); 69 typedef int (*FuncTypeDoubleSelect)(double, double, int, int); 70 static struct { 71 const char *Name; 72 FuncTypeFloat FuncFloatSz; 73 FuncTypeFloat FuncFloatLlc; 74 FuncTypeDouble FuncDoubleSz; 75 FuncTypeDouble FuncDoubleLlc; 76 FuncTypeFloatSelect FuncFloatSelectSz; 77 FuncTypeFloatSelect FuncFloatSelectLlc; 78 FuncTypeDoubleSelect FuncDoubleSelectSz; 79 FuncTypeDoubleSelect FuncDoubleSelectLlc; 80 } Funcs[] = { 81#define X(cmp) \ 82 { \ 83 "fcmp" STR(cmp), Subzero_fcmp##cmp##Float, fcmp##cmp##Float, \ 84 Subzero_fcmp##cmp##Double, fcmp##cmp##Double, \ 85 Subzero_fcmpSelect##cmp##Float, fcmpSelect##cmp##Float, \ 86 Subzero_fcmpSelect##cmp##Double, fcmpSelect##cmp##Double \ 87 } \ 88 , 89 FCMP_TABLE 90#undef X 91 }; 92 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs); 93 94 bool ResultSz, ResultLlc; 95 96 assert(Values && NumValues); 97 98 for (size_t f = 0; f < NumFuncs; ++f) { 99 for (size_t i = 0; i < NumValues; ++i) { 100 for (size_t j = 0; j < NumValues; ++j) { 101 ++TotalTests; 102 float Value1Float = Values[i]; 103 float Value2Float = Values[j]; 104 ResultSz = Funcs[f].FuncFloatSz(Value1Float, Value2Float); 105 ResultLlc = Funcs[f].FuncFloatLlc(Value1Float, Value2Float); 106 if (ResultSz == ResultLlc) { 107 ++Passes; 108 } else { 109 ++Failures; 110 std::cout << Funcs[f].Name << "Float(" << Value1Float << ", " 111 << Value2Float << "): sz=" << ResultSz 112 << " llc=" << ResultLlc << "\n"; 113 } 114 ++TotalTests; 115 double Value1Double = Values[i]; 116 double Value2Double = Values[j]; 117 ResultSz = Funcs[f].FuncDoubleSz(Value1Double, Value2Double); 118 ResultLlc = Funcs[f].FuncDoubleLlc(Value1Double, Value2Double); 119 if (ResultSz == ResultLlc) { 120 ++Passes; 121 } else { 122 ++Failures; 123 std::cout << Funcs[f].Name << "Double(" << Value1Double << ", " 124 << Value2Double << "): sz=" << ResultSz 125 << " llc=" << ResultLlc << "\n"; 126 } 127 ++TotalTests; 128 float Value1SelectFloat = Values[i]; 129 float Value2SelectFloat = Values[j]; 130 ResultSz = Funcs[f].FuncFloatSelectSz(Value1Float, Value2Float, 1, 2); 131 ResultLlc = Funcs[f].FuncFloatSelectLlc(Value1Float, Value2Float, 1, 2); 132 if (ResultSz == ResultLlc) { 133 ++Passes; 134 } else { 135 ++Failures; 136 std::cout << Funcs[f].Name << "SelectFloat(" << Value1Float << ", " 137 << Value2Float << "): sz=" << ResultSz 138 << " llc=" << ResultLlc << "\n"; 139 } 140 ++TotalTests; 141 double Value1SelectDouble = Values[i]; 142 double Value2SelectDouble = Values[j]; 143 ResultSz = 144 Funcs[f].FuncDoubleSelectSz(Value1Double, Value2Double, 1, 2); 145 ResultLlc = 146 Funcs[f].FuncDoubleSelectLlc(Value1Double, Value2Double, 1, 2); 147 if (ResultSz == ResultLlc) { 148 ++Passes; 149 } else { 150 ++Failures; 151 std::cout << Funcs[f].Name << "SelectDouble(" << Value1Double << ", " 152 << Value2Double << "): sz=" << ResultSz 153 << " llc=" << ResultLlc << "\n"; 154 } 155 } 156 } 157 } 158} 159 160void testsVector(size_t &TotalTests, size_t &Passes, size_t &Failures) { 161 typedef v4si32 (*FuncTypeVector)(v4f32, v4f32); 162 static struct { 163 const char *Name; 164 FuncTypeVector FuncVectorSz; 165 FuncTypeVector FuncVectorLlc; 166 } Funcs[] = { 167#define X(cmp) \ 168 { "fcmp" STR(cmp), Subzero_fcmp##cmp##Vector, fcmp##cmp##Vector } \ 169 , 170 FCMP_TABLE 171#undef X 172 }; 173 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs); 174 const static size_t NumElementsInType = 4; 175 const static size_t MaxTestsPerFunc = 100000; 176 177 assert(Values && NumValues); 178 179 for (size_t f = 0; f < NumFuncs; ++f) { 180 PRNG Index; 181 for (size_t i = 0; i < MaxTestsPerFunc; ++i) { 182 v4f32 Value1, Value2; 183 for (size_t j = 0; j < NumElementsInType; ++j) { 184 Value1[j] = Values[Index() % NumValues]; 185 Value2[j] = Values[Index() % NumValues]; 186 } 187 ++TotalTests; 188 v4si32 ResultSz, ResultLlc; 189 ResultSz = Funcs[f].FuncVectorSz(Value1, Value2); 190 ResultLlc = Funcs[f].FuncVectorLlc(Value1, Value2); 191 if (!memcmp(&ResultSz, &ResultLlc, sizeof(ResultSz))) { 192 ++Passes; 193 } else { 194 ++Failures; 195 std::cout << Funcs[f].Name << "Vector(" << vectAsString<v4f32>(Value1) 196 << ", " << vectAsString<v4f32>(Value2) 197 << "): sz=" << vectAsString<v4si32>(ResultSz) 198 << " llc=" << vectAsString<v4si32>(ResultLlc) << "\n"; 199 } 200 } 201 } 202} 203 204int main(int argc, char *argv[]) { 205 size_t TotalTests = 0; 206 size_t Passes = 0; 207 size_t Failures = 0; 208 209 initializeValues(); 210 211 testsScalar(TotalTests, Passes, Failures); 212 testsVector(TotalTests, Passes, Failures); 213 214 std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes 215 << " Failures=" << Failures << "\n"; 216 return Failures; 217} 218