blob: 40fdbab2f79cfb42656c4ffef34768559455a270 [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
Jan Voung109fa152014-10-07 17:22:51 -070023#include "test_arith.def"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070024#include "test_fcmp.def"
Antonio Maioranoca8a16e2020-11-10 16:56:20 -050025#include "vectors.h"
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070026
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); \
David Sehre3984282015-12-15 17:34:55 -080030 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); \
Matt Walace0ca8f2014-07-24 12:34:20 -070032 extern "C" v4si32 fcmp##cmp##Vector(v4f32 a, v4f32 b); \
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070033 extern "C" bool Subzero_fcmp##cmp##Float(float a, float b); \
Matt Walace0ca8f2014-07-24 12:34:20 -070034 extern "C" bool Subzero_fcmp##cmp##Double(double a, double b); \
David Sehre3984282015-12-15 17:34:55 -080035 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); \
Matt Walace0ca8f2014-07-24 12:34:20 -070039 extern "C" v4si32 Subzero_fcmp##cmp##Vector(v4f32 a, v4f32 b);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070040FCMP_TABLE;
41#undef X
42
Matt Walace0ca8f2014-07-24 12:34:20 -070043volatile double *Values;
44size_t NumValues;
45
46void initializeValues() {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070047 static const double NegInf = -1.0 / 0.0;
48 static const double Zero = 0.0;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070049 static const double PosInf = 1.0 / 0.0;
50 static const double Nan = 0.0 / 0.0;
Jan Voungf37fbbe2014-07-09 16:13:13 -070051 static const double NegNan = -0.0 / 0.0;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070052 assert(std::fpclassify(NegInf) == FP_INFINITE);
53 assert(std::fpclassify(PosInf) == FP_INFINITE);
54 assert(std::fpclassify(Nan) == FP_NAN);
Jan Voungf37fbbe2014-07-09 16:13:13 -070055 assert(std::fpclassify(NegNan) == FP_NAN);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070056 assert(NegInf < Zero);
57 assert(NegInf < PosInf);
58 assert(Zero < PosInf);
Jan Voung109fa152014-10-07 17:22:51 -070059 static volatile double InitValues[] =
Jim Stichnothdd842db2015-01-27 12:53:53 -080060 FP_VALUE_ARRAY(NegInf, PosInf, NegNan, Nan);
Matt Walace0ca8f2014-07-24 12:34:20 -070061 NumValues = sizeof(InitValues) / sizeof(*InitValues);
62 Values = InitValues;
63}
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070064
Matt Walace0ca8f2014-07-24 12:34:20 -070065void testsScalar(size_t &TotalTests, size_t &Passes, size_t &Failures) {
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070066 typedef bool (*FuncTypeFloat)(float, float);
67 typedef bool (*FuncTypeDouble)(double, double);
David Sehre3984282015-12-15 17:34:55 -080068 typedef int (*FuncTypeFloatSelect)(float, float, int, int);
69 typedef int (*FuncTypeDoubleSelect)(double, double, int, int);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070070 static struct {
71 const char *Name;
72 FuncTypeFloat FuncFloatSz;
73 FuncTypeFloat FuncFloatLlc;
74 FuncTypeDouble FuncDoubleSz;
75 FuncTypeDouble FuncDoubleLlc;
David Sehre3984282015-12-15 17:34:55 -080076 FuncTypeFloatSelect FuncFloatSelectSz;
77 FuncTypeFloatSelect FuncFloatSelectLlc;
78 FuncTypeDoubleSelect FuncDoubleSelectSz;
79 FuncTypeDoubleSelect FuncDoubleSelectLlc;
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070080 } Funcs[] = {
81#define X(cmp) \
Antonio Maioranoca8a16e2020-11-10 16:56:20 -050082 {"fcmp" STR(cmp), Subzero_fcmp##cmp##Float, \
83 fcmp##cmp##Float, Subzero_fcmp##cmp##Double, \
84 fcmp##cmp##Double, Subzero_fcmpSelect##cmp##Float, \
85 fcmpSelect##cmp##Float, Subzero_fcmpSelect##cmp##Double, \
86 fcmpSelect##cmp##Double},
Jim Stichnothd9dc82e2015-03-03 17:06:33 -080087 FCMP_TABLE
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070088#undef X
Jim Stichnothd9dc82e2015-03-03 17:06:33 -080089 };
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070090 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
91
92 bool ResultSz, ResultLlc;
93
Matt Walace0ca8f2014-07-24 12:34:20 -070094 assert(Values && NumValues);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -070095
96 for (size_t f = 0; f < NumFuncs; ++f) {
97 for (size_t i = 0; i < NumValues; ++i) {
98 for (size_t j = 0; j < NumValues; ++j) {
99 ++TotalTests;
100 float Value1Float = Values[i];
101 float Value2Float = Values[j];
102 ResultSz = Funcs[f].FuncFloatSz(Value1Float, Value2Float);
103 ResultLlc = Funcs[f].FuncFloatLlc(Value1Float, Value2Float);
104 if (ResultSz == ResultLlc) {
105 ++Passes;
106 } else {
107 ++Failures;
108 std::cout << Funcs[f].Name << "Float(" << Value1Float << ", "
109 << Value2Float << "): sz=" << ResultSz
Matt Walace0ca8f2014-07-24 12:34:20 -0700110 << " llc=" << ResultLlc << "\n";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700111 }
112 ++TotalTests;
113 double Value1Double = Values[i];
114 double Value2Double = Values[j];
115 ResultSz = Funcs[f].FuncDoubleSz(Value1Double, Value2Double);
116 ResultLlc = Funcs[f].FuncDoubleLlc(Value1Double, Value2Double);
117 if (ResultSz == ResultLlc) {
118 ++Passes;
119 } else {
120 ++Failures;
121 std::cout << Funcs[f].Name << "Double(" << Value1Double << ", "
122 << Value2Double << "): sz=" << ResultSz
Matt Walace0ca8f2014-07-24 12:34:20 -0700123 << " llc=" << ResultLlc << "\n";
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700124 }
David Sehre3984282015-12-15 17:34:55 -0800125 ++TotalTests;
126 float Value1SelectFloat = Values[i];
127 float Value2SelectFloat = Values[j];
128 ResultSz = Funcs[f].FuncFloatSelectSz(Value1Float, Value2Float, 1, 2);
129 ResultLlc = Funcs[f].FuncFloatSelectLlc(Value1Float, Value2Float, 1, 2);
130 if (ResultSz == ResultLlc) {
131 ++Passes;
132 } else {
133 ++Failures;
134 std::cout << Funcs[f].Name << "SelectFloat(" << Value1Float << ", "
135 << Value2Float << "): sz=" << ResultSz
136 << " llc=" << ResultLlc << "\n";
137 }
138 ++TotalTests;
139 double Value1SelectDouble = Values[i];
140 double Value2SelectDouble = Values[j];
141 ResultSz =
142 Funcs[f].FuncDoubleSelectSz(Value1Double, Value2Double, 1, 2);
143 ResultLlc =
144 Funcs[f].FuncDoubleSelectLlc(Value1Double, Value2Double, 1, 2);
145 if (ResultSz == ResultLlc) {
146 ++Passes;
147 } else {
148 ++Failures;
149 std::cout << Funcs[f].Name << "SelectDouble(" << Value1Double << ", "
150 << Value2Double << "): sz=" << ResultSz
151 << " llc=" << ResultLlc << "\n";
152 }
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700153 }
154 }
155 }
Matt Walace0ca8f2014-07-24 12:34:20 -0700156}
157
158void testsVector(size_t &TotalTests, size_t &Passes, size_t &Failures) {
159 typedef v4si32 (*FuncTypeVector)(v4f32, v4f32);
160 static struct {
161 const char *Name;
162 FuncTypeVector FuncVectorSz;
163 FuncTypeVector FuncVectorLlc;
164 } Funcs[] = {
Antonio Maioranoca8a16e2020-11-10 16:56:20 -0500165#define X(cmp) {"fcmp" STR(cmp), Subzero_fcmp##cmp##Vector, fcmp##cmp##Vector},
Jim Stichnothd9dc82e2015-03-03 17:06:33 -0800166 FCMP_TABLE
Matt Walace0ca8f2014-07-24 12:34:20 -0700167#undef X
Jim Stichnothd9dc82e2015-03-03 17:06:33 -0800168 };
Matt Walace0ca8f2014-07-24 12:34:20 -0700169 const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
170 const static size_t NumElementsInType = 4;
171 const static size_t MaxTestsPerFunc = 100000;
172
173 assert(Values && NumValues);
174
175 for (size_t f = 0; f < NumFuncs; ++f) {
176 PRNG Index;
177 for (size_t i = 0; i < MaxTestsPerFunc; ++i) {
178 v4f32 Value1, Value2;
179 for (size_t j = 0; j < NumElementsInType; ++j) {
180 Value1[j] = Values[Index() % NumValues];
181 Value2[j] = Values[Index() % NumValues];
182 }
183 ++TotalTests;
184 v4si32 ResultSz, ResultLlc;
185 ResultSz = Funcs[f].FuncVectorSz(Value1, Value2);
186 ResultLlc = Funcs[f].FuncVectorLlc(Value1, Value2);
187 if (!memcmp(&ResultSz, &ResultLlc, sizeof(ResultSz))) {
188 ++Passes;
189 } else {
190 ++Failures;
191 std::cout << Funcs[f].Name << "Vector(" << vectAsString<v4f32>(Value1)
192 << ", " << vectAsString<v4f32>(Value2)
193 << "): sz=" << vectAsString<v4si32>(ResultSz)
194 << " llc=" << vectAsString<v4si32>(ResultLlc) << "\n";
195 }
196 }
197 }
198}
199
John Porto1d235422015-08-12 12:37:53 -0700200int main(int argc, char *argv[]) {
Matt Walace0ca8f2014-07-24 12:34:20 -0700201 size_t TotalTests = 0;
202 size_t Passes = 0;
203 size_t Failures = 0;
204
205 initializeValues();
206
207 testsScalar(TotalTests, Passes, Failures);
208 testsVector(TotalTests, Passes, Failures);
Jim Stichnoth5bc2b1d2014-05-22 13:38:48 -0700209
210 std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes
211 << " Failures=" << Failures << "\n";
212 return Failures;
213}