xref: /aosp_15_r20/external/swiftshader/third_party/subzero/crosstest/test_fcmp_main.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
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 "test_arith.def"
24 #include "test_fcmp.def"
25 #include "vectors.h"
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);
40 FCMP_TABLE;
41 #undef X
42 
43 volatile double *Values;
44 size_t NumValues;
45 
initializeValues()46 void 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 
testsScalar(size_t & TotalTests,size_t & Passes,size_t & Failures)65 void 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   {"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},
87       FCMP_TABLE
88 #undef X
89   };
90   const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs);
91 
92   bool ResultSz, ResultLlc;
93 
94   assert(Values && NumValues);
95 
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
110                     << " llc=" << ResultLlc << "\n";
111         }
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
123                     << " llc=" << ResultLlc << "\n";
124         }
125         ++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         }
153       }
154     }
155   }
156 }
157 
testsVector(size_t & TotalTests,size_t & Passes,size_t & Failures)158 void 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[] = {
165 #define X(cmp) {"fcmp" STR(cmp), Subzero_fcmp##cmp##Vector, fcmp##cmp##Vector},
166       FCMP_TABLE
167 #undef X
168   };
169   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 
main(int argc,char * argv[])200 int main(int argc, char *argv[]) {
201   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);
209 
210   std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes
211             << " Failures=" << Failures << "\n";
212   return Failures;
213 }
214