blob: 9e9c32c5c3eca5aedafa8f39a60d10cc85d36948 [file] [log] [blame]
Matt Walace0ca8f2014-07-24 12:34:20 -07001//===- 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
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070014/* 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>
Matt Walace0ca8f2014-07-24 12:34:20 -070020#include <cstring>
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070021#include <iostream>
22
Matt Walace0ca8f2014-07-24 12:34:20 -070023#include "vectors.h"
Jan Voung109fa152014-10-07 17:22:51 -070024#include "test_arith.def"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070025#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); \
Matt Walace0ca8f2014-07-24 12:34:20 -070030 extern "C" v4si32 fcmp##cmp##Vector(v4f32 a, v4f32 b); \
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070031 extern "C" bool Subzero_fcmp##cmp##Float(float a, float b); \
Matt Walace0ca8f2014-07-24 12:34:20 -070032 extern "C" bool Subzero_fcmp##cmp##Double(double a, double b); \
33 extern "C" v4si32 Subzero_fcmp##cmp##Vector(v4f32 a, v4f32 b);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070034FCMP_TABLE;
35#undef X
36
Matt Walace0ca8f2014-07-24 12:34:20 -070037volatile double *Values;
38size_t NumValues;
39
40void initializeValues() {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070041 static const double NegInf = -1.0 / 0.0;
42 static const double Zero = 0.0;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070043 static const double PosInf = 1.0 / 0.0;
44 static const double Nan = 0.0 / 0.0;
Jan Voungf37fbbe2014-07-09 16:13:13 -070045 static const double NegNan = -0.0 / 0.0;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070046 assert(std::fpclassify(NegInf) == FP_INFINITE);
47 assert(std::fpclassify(PosInf) == FP_INFINITE);
48 assert(std::fpclassify(Nan) == FP_NAN);
Jan Voungf37fbbe2014-07-09 16:13:13 -070049 assert(std::fpclassify(NegNan) == FP_NAN);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070050 assert(NegInf < Zero);
51 assert(NegInf < PosInf);
52 assert(Zero < PosInf);
Jan Voung109fa152014-10-07 17:22:51 -070053 static volatile double InitValues[] =
Jim Stichnothdd842db2015-01-27 12:53:53 -080054 FP_VALUE_ARRAY(NegInf, PosInf, NegNan, Nan);
Matt Walace0ca8f2014-07-24 12:34:20 -070055 NumValues = sizeof(InitValues) / sizeof(*InitValues);
56 Values = InitValues;
57}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070058
Matt Walace0ca8f2014-07-24 12:34:20 -070059void testsScalar(size_t &TotalTests, size_t &Passes, size_t &Failures) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070060 typedef bool (*FuncTypeFloat)(float, float);
61 typedef bool (*FuncTypeDouble)(double, double);
62 static struct {
63 const char *Name;
64 FuncTypeFloat FuncFloatSz;
65 FuncTypeFloat FuncFloatLlc;
66 FuncTypeDouble FuncDoubleSz;
67 FuncTypeDouble FuncDoubleLlc;
68 } Funcs[] = {
69#define X(cmp) \
70 { \
71 "fcmp" STR(cmp), Subzero_fcmp##cmp##Float, fcmp##cmp##Float, \
72 Subzero_fcmp##cmp##Double, fcmp##cmp##Double \
73 } \
74 ,
Jim Stichnothd9dc82e2015-03-03 17:06:33 -080075 FCMP_TABLE
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070076#undef X
Jim Stichnothd9dc82e2015-03-03 17:06:33 -080077 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070078 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
79
80 bool ResultSz, ResultLlc;
81
Matt Walace0ca8f2014-07-24 12:34:20 -070082 assert(Values && NumValues);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070083
84 for (size_t f = 0; f < NumFuncs; ++f) {
85 for (size_t i = 0; i < NumValues; ++i) {
86 for (size_t j = 0; j < NumValues; ++j) {
87 ++TotalTests;
88 float Value1Float = Values[i];
89 float Value2Float = Values[j];
90 ResultSz = Funcs[f].FuncFloatSz(Value1Float, Value2Float);
91 ResultLlc = Funcs[f].FuncFloatLlc(Value1Float, Value2Float);
92 if (ResultSz == ResultLlc) {
93 ++Passes;
94 } else {
95 ++Failures;
96 std::cout << Funcs[f].Name << "Float(" << Value1Float << ", "
97 << Value2Float << "): sz=" << ResultSz
Matt Walace0ca8f2014-07-24 12:34:20 -070098 << " llc=" << ResultLlc << "\n";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070099 }
100 ++TotalTests;
101 double Value1Double = Values[i];
102 double Value2Double = Values[j];
103 ResultSz = Funcs[f].FuncDoubleSz(Value1Double, Value2Double);
104 ResultLlc = Funcs[f].FuncDoubleLlc(Value1Double, Value2Double);
105 if (ResultSz == ResultLlc) {
106 ++Passes;
107 } else {
108 ++Failures;
109 std::cout << Funcs[f].Name << "Double(" << Value1Double << ", "
110 << Value2Double << "): sz=" << ResultSz
Matt Walace0ca8f2014-07-24 12:34:20 -0700111 << " llc=" << ResultLlc << "\n";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700112 }
113 }
114 }
115 }
Matt Walace0ca8f2014-07-24 12:34:20 -0700116}
117
118void testsVector(size_t &TotalTests, size_t &Passes, size_t &Failures) {
119 typedef v4si32 (*FuncTypeVector)(v4f32, v4f32);
120 static struct {
121 const char *Name;
122 FuncTypeVector FuncVectorSz;
123 FuncTypeVector FuncVectorLlc;
124 } Funcs[] = {
125#define X(cmp) \
126 { "fcmp" STR(cmp), Subzero_fcmp##cmp##Vector, fcmp##cmp##Vector } \
127 ,
Jim Stichnothd9dc82e2015-03-03 17:06:33 -0800128 FCMP_TABLE
Matt Walace0ca8f2014-07-24 12:34:20 -0700129#undef X
Jim Stichnothd9dc82e2015-03-03 17:06:33 -0800130 };
Matt Walace0ca8f2014-07-24 12:34:20 -0700131 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
132 const static size_t NumElementsInType = 4;
133 const static size_t MaxTestsPerFunc = 100000;
134
135 assert(Values && NumValues);
136
137 for (size_t f = 0; f < NumFuncs; ++f) {
138 PRNG Index;
139 for (size_t i = 0; i < MaxTestsPerFunc; ++i) {
140 v4f32 Value1, Value2;
141 for (size_t j = 0; j < NumElementsInType; ++j) {
142 Value1[j] = Values[Index() % NumValues];
143 Value2[j] = Values[Index() % NumValues];
144 }
145 ++TotalTests;
146 v4si32 ResultSz, ResultLlc;
147 ResultSz = Funcs[f].FuncVectorSz(Value1, Value2);
148 ResultLlc = Funcs[f].FuncVectorLlc(Value1, Value2);
149 if (!memcmp(&ResultSz, &ResultLlc, sizeof(ResultSz))) {
150 ++Passes;
151 } else {
152 ++Failures;
153 std::cout << Funcs[f].Name << "Vector(" << vectAsString<v4f32>(Value1)
154 << ", " << vectAsString<v4f32>(Value2)
155 << "): sz=" << vectAsString<v4si32>(ResultSz)
156 << " llc=" << vectAsString<v4si32>(ResultLlc) << "\n";
157 }
158 }
159 }
160}
161
162int main(int argc, char **argv) {
163 size_t TotalTests = 0;
164 size_t Passes = 0;
165 size_t Failures = 0;
166
167 initializeValues();
168
169 testsScalar(TotalTests, Passes, Failures);
170 testsVector(TotalTests, Passes, Failures);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700171
172 std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes
173 << " Failures=" << Failures << "\n";
174 return Failures;
175}