Skip to content

Commit 3ed1fbb

Browse files
authored
Tests for additional builtin classification functions (#59)
This change adds tests for functions 'iszero', 'issubnornal' and 'issignaling'. It also adds tests for Intel fp80 type and some other small enhancements. Migrated from: https://reviews.llvm.org/D112933 Pull request: #59
1 parent 3377a72 commit 3ed1fbb

File tree

9 files changed

+943
-251
lines changed

9 files changed

+943
-251
lines changed

SingleSource/UnitTests/Float/check-helper.h

Lines changed: 27 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -15,46 +15,38 @@
1515

1616
#define DimOf(x) (sizeof(x) / sizeof(x[0]))
1717

18-
// Checks if condition 'cond' is true for the 'value'.
18+
// Prints bits of a floating-point value, specified by the parameter 'value'.
19+
// 'value' may an integer or a pointer to integer, the exact meaning is
20+
// determined by macros VAL_FORMAT and GET_VALUE.
1921
//
2022
// Requires the following macros to be defined:
2123
//
22-
// VAL_FORMAT - printf format specifier without %, like "d" or "llx", which
23-
// should be used to print 'value'.
24+
// VAL_FORMAT - printf format specifier, like "%d" or "%llx %llx", which
25+
// should be used to print the value represented by the
26+
// argument 'value'.
27+
// GET_VALUE - a macro that extracts the value or values for printing
28+
// the 'value'.
2429
//
25-
#define CHECK_VALUE(cond, value) \
26-
do { \
27-
if (!(cond)) { \
28-
printf("Check '%s' in file '%s' at line %d " \
29-
"failed for the value '%" VAL_FORMAT "'\n", \
30-
#cond, __FILE__, __LINE__, (value)); \
31-
exit(-1); \
32-
} \
33-
} while(0)
30+
#define PRINT_VALUE(value) printf(VAL_FORMAT, GET_VALUE(value));
3431

35-
// Checks if floating point 'value' is equal to the value 'expected' which is an
36-
// integer that represents bits of floating point number.
32+
// Checks if condition 'cond' is true for the 'value'.
3733
//
38-
// Requires the following macros to be defined:
34+
// The argument 'value' is a pointer to the bits representing the tested
35+
// floating-point value. It does not participate in checks and is used only for
36+
// printing the tested value in diagnostics. Actual value to print is obtained
37+
// using macro 'GET_VALUE'.
3938
//
40-
// INT_FORMAT - printf format specifier without %, like "d" or "llx",
41-
// which should be used to print 'expected'.
42-
// FLOAT_FORMAT - printf format specifier without % to print 'value'.
43-
// INT_TYPE - type of 'expected'.
44-
// FLOAT_TYPE - type of 'value'.
45-
//
46-
#define CHECK_EQ(value, expected) \
47-
do { \
48-
union { \
49-
INT_TYPE i; \
50-
FLOAT_TYPE f; \
51-
} u; \
52-
u.i = (value); \
53-
if (u.f != (expected)) { \
54-
printf("Check in file '%s' at line %d failed: " \
55-
"'%" INT_FORMAT "' != '%" FLOAT_FORMAT "'\n", \
56-
__FILE__, __LINE__, (INT_TYPE)(value), (expected)); \
57-
exit(-1); \
58-
} \
59-
} while(0)
39+
// Macros required to be defined are same as for PRINT_VALUE.
40+
//
41+
#define CHECK_VALUE(cond, value) \
42+
do { \
43+
if (!(cond)) { \
44+
printf("Check '%s' in file '%s' at line %d failed for the value '", \
45+
#cond, __FILE__, __LINE__); \
46+
PRINT_VALUE(value); \
47+
printf("'\n"); \
48+
exit(-1); \
49+
} \
50+
} while (0)
51+
6052
#endif

SingleSource/UnitTests/Float/classify-f32.h

Lines changed: 108 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,8 @@
1919
#include <stdio.h>
2020
#include <stdlib.h>
2121

22-
23-
#define INT_FORMAT PRIx32
24-
#define FLOAT_FORMAT "g"
25-
#define VAL_FORMAT INT_FORMAT
26-
#define INT_TYPE uint32_t
27-
#define FLOAT_TYPE float
22+
#define VAL_FORMAT "%" PRIx32
23+
#define GET_VALUE(x) (*(uint32_t *)x)
2824

2925
uint32_t FloatQNaNValues[] = {
3026
F32_MAKE(0, F32_EXP_MASK, F32_QNAN_BIT | F32_PAYLOAD_MASK),
@@ -37,28 +33,25 @@ uint32_t FloatQNaNValues[] = {
3733
F32_MAKE(1, F32_EXP_MASK, F32_QNAN_BIT | 0x00100000U),
3834

3935
F32_MAKE(0, F32_EXP_MASK, F32_QNAN_BIT | 0x00000001U),
40-
F32_MAKE(1, F32_EXP_MASK, F32_QNAN_BIT | 0x00000002U)
41-
};
36+
F32_MAKE(1, F32_EXP_MASK, F32_QNAN_BIT | 0x00000002U)};
4237

43-
uint32_t FloatSNaNValues[] = {
44-
F32_MAKE(0, F32_EXP_MASK, F32_PAYLOAD_MASK),
45-
F32_MAKE(1, F32_EXP_MASK, F32_PAYLOAD_MASK),
38+
uint32_t FloatSNaNValues[] = {F32_MAKE(0, F32_EXP_MASK, F32_PAYLOAD_MASK),
39+
F32_MAKE(1, F32_EXP_MASK, F32_PAYLOAD_MASK),
4640

47-
F32_MAKE(0, F32_EXP_MASK, 0x00200000U),
48-
F32_MAKE(1, F32_EXP_MASK, 0x00100000U),
41+
F32_MAKE(0, F32_EXP_MASK, 0x00200000U),
42+
F32_MAKE(1, F32_EXP_MASK, 0x00100000U),
4943

50-
F32_MAKE(0, F32_EXP_MASK, 0x00000001U),
51-
F32_MAKE(1, F32_EXP_MASK, 0x00000002U)
52-
};
44+
F32_MAKE(0, F32_EXP_MASK, 0x00000001U),
45+
F32_MAKE(1, F32_EXP_MASK, 0x00000002U)};
5346

5447
uint32_t FloatInfValues[] = {
55-
F32_MAKE(0, F32_EXP_MASK, 0), // +Inf
56-
F32_MAKE(1, F32_EXP_MASK, 0) // -Inf
48+
F32_MAKE(0, F32_EXP_MASK, 0), // +Inf
49+
F32_MAKE(1, F32_EXP_MASK, 0) // -Inf
5750
};
5851

5952
uint32_t FloatZeroValues[] = {
60-
F32_MAKE(0, 0, 0), // +0.0
61-
F32_MAKE(1, 0, 0) // -0.0
53+
F32_MAKE(0, 0, 0), // +0.0
54+
F32_MAKE(1, 0, 0) // -0.0
6255
};
6356

6457
uint32_t FloatDenormValues[] = {
@@ -101,99 +94,130 @@ uint32_t FloatNormalValues[] = {
10194
};
10295

10396
int test_float() {
104-
CHECK_EQ(F32_NORMAL(0, 0, 0), 1.0F);
105-
CHECK_EQ(F32_NORMAL(0, 0, F32_MANTISSA(1, 0, 0)), 1.5F);
106-
CHECK_EQ(F32_NORMAL(0, 0, F32_MANTISSA(0, 1, 0)), 1.25F);
107-
CHECK_EQ(F32_NORMAL(0, 0, F32_MANTISSA(0, 0, 1)), 1.125);
108-
CHECK_EQ(F32_NORMAL(0, -1, 0), 0.5F);
109-
CHECK_EQ(F32_NORMAL(0, -2, 0), 0.25);
110-
CHECK_EQ(F32_NORMAL(0, -3, 0), 0.125);
111-
CHECK_EQ(F32_NORMAL(0, 1, 0), 2.0F);
112-
CHECK_EQ(F32_NORMAL(0, 1, F32_MANTISSA(1, 0, 0)), 3.0F);
113-
114-
CHECK_EQ(F32_NORMAL(1, 0, 0), -1.0F);
115-
CHECK_EQ(F32_NORMAL(1, 0, F32_MANTISSA(1, 0, 0)), -1.5F);
116-
CHECK_EQ(F32_NORMAL(1, 0, F32_MANTISSA(0, 1, 0)), -1.25F);
117-
CHECK_EQ(F32_NORMAL(1, 0, F32_MANTISSA(0, 0, 1)), -1.125);
118-
CHECK_EQ(F32_NORMAL(1, -1, 0), -0.5F);
119-
CHECK_EQ(F32_NORMAL(1, -2, 0), -0.25);
120-
CHECK_EQ(F32_NORMAL(1, -3, 0), -0.125);
121-
CHECK_EQ(F32_NORMAL(1, 1, 0), -2.0F);
122-
CHECK_EQ(F32_NORMAL(1, 1, F32_MANTISSA(1, 0, 0)), -3.0F);
123-
124-
CHECK_EQ(F32_NORMAL(0, F32_EXP_MIN, 0), 1.1754943508e-38F);
125-
CHECK_EQ(F32_NORMAL(1, F32_EXP_MIN, 0), -1.1754943508e-38F);
126-
CHECK_EQ(F32_NORMAL(0, F32_EXP_MAX, F32_MANTISSA_MASK), 3.4028234664e38F);
127-
CHECK_EQ(F32_NORMAL(1, F32_EXP_MAX, F32_MANTISSA_MASK), -3.4028234664e38F);
128-
12997
for (unsigned i = 0; i < DimOf(FloatQNaNValues); i++) {
13098
uint32_t *IPtr = FloatQNaNValues + i;
131-
uint32_t IX = *IPtr;
13299
float X = *(float *)IPtr;
133-
CHECK_VALUE(__builtin_isnan(X), IX);
134-
CHECK_VALUE(!__builtin_isinf(X), IX);
135-
CHECK_VALUE(!__builtin_isfinite(X), IX);
136-
CHECK_VALUE(!__builtin_isnormal(X), IX);
137-
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 0, IX);
100+
CHECK_VALUE(__builtin_isnan(X), IPtr);
101+
CHECK_VALUE(!__builtin_issignaling(X), IPtr);
102+
CHECK_VALUE(!__builtin_isinf(X), IPtr);
103+
CHECK_VALUE(!__builtin_isfinite(X), IPtr);
104+
CHECK_VALUE(!__builtin_isnormal(X), IPtr);
105+
CHECK_VALUE(!__builtin_issubnormal(X), IPtr);
106+
CHECK_VALUE(!__builtin_iszero(X), IPtr);
107+
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 0, IPtr);
138108
}
139109
for (unsigned i = 0; i < DimOf(FloatSNaNValues); i++) {
140110
uint32_t *IPtr = FloatSNaNValues + i;
141-
uint32_t IX = *IPtr;
142111
float X = *(float *)IPtr;
143-
CHECK_VALUE(__builtin_isnan(X), IX);
144-
CHECK_VALUE(!__builtin_isinf(X), IX);
145-
CHECK_VALUE(!__builtin_isfinite(X), IX);
146-
CHECK_VALUE(!__builtin_isnormal(X), IX);
147-
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 0, IX);
112+
CHECK_VALUE(__builtin_isnan(X), IPtr);
113+
CHECK_VALUE(__builtin_issignaling(X), IPtr);
114+
CHECK_VALUE(!__builtin_isinf(X), IPtr);
115+
CHECK_VALUE(!__builtin_isfinite(X), IPtr);
116+
CHECK_VALUE(!__builtin_isnormal(X), IPtr);
117+
CHECK_VALUE(!__builtin_issubnormal(X), IPtr);
118+
CHECK_VALUE(!__builtin_iszero(X), IPtr);
119+
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 0, IPtr);
148120
}
149121
for (unsigned i = 0; i < DimOf(FloatInfValues); i++) {
150122
uint32_t *IPtr = FloatInfValues + i;
151-
uint32_t IX = *IPtr;
152123
float X = *(float *)IPtr;
153-
CHECK_VALUE(!__builtin_isnan(X), IX);
154-
CHECK_VALUE(__builtin_isinf(X), IX);
155-
CHECK_VALUE(!__builtin_isfinite(X), IX);
156-
CHECK_VALUE(!__builtin_isnormal(X), IX);
157-
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 1, IX);
124+
CHECK_VALUE(!__builtin_isnan(X), IPtr);
125+
CHECK_VALUE(!__builtin_issignaling(X), IPtr);
126+
CHECK_VALUE(__builtin_isinf(X), IPtr);
127+
CHECK_VALUE(!__builtin_isfinite(X), IPtr);
128+
CHECK_VALUE(!__builtin_isnormal(X), IPtr);
129+
CHECK_VALUE(!__builtin_issubnormal(X), IPtr);
130+
CHECK_VALUE(!__builtin_iszero(X), IPtr);
131+
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 1, IPtr);
158132
}
159133
for (unsigned i = 0; i < DimOf(FloatZeroValues); i++) {
160134
uint32_t *IPtr = FloatZeroValues + i;
161-
uint32_t IX = *IPtr;
162135
float X = *(float *)IPtr;
163-
CHECK_VALUE(!__builtin_isnan(X), IX);
164-
CHECK_VALUE(!__builtin_isinf(X), IX);
165-
CHECK_VALUE(__builtin_isfinite(X), IX);
166-
CHECK_VALUE(!__builtin_isnormal(X), IX);
167-
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 4, IX);
136+
CHECK_VALUE(!__builtin_isnan(X), IPtr);
137+
CHECK_VALUE(!__builtin_issignaling(X), IPtr);
138+
CHECK_VALUE(!__builtin_isinf(X), IPtr);
139+
CHECK_VALUE(__builtin_isfinite(X), IPtr);
140+
CHECK_VALUE(!__builtin_isnormal(X), IPtr);
141+
CHECK_VALUE(!__builtin_issubnormal(X), IPtr);
142+
CHECK_VALUE(__builtin_iszero(X), IPtr);
143+
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 4, IPtr);
168144
}
169145
for (unsigned i = 0; i < DimOf(FloatDenormValues); i++) {
170146
uint32_t *IPtr = FloatDenormValues + i;
171-
uint32_t IX = *IPtr;
172147
float X = *(float *)IPtr;
173-
CHECK_VALUE(!__builtin_isnan(X), IX);
174-
CHECK_VALUE(!__builtin_isinf(X), IX);
175-
CHECK_VALUE(__builtin_isfinite(X), IX);
176-
CHECK_VALUE(!__builtin_isnormal(X), IX);
177-
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 3, IX);
148+
CHECK_VALUE(!__builtin_isnan(X), IPtr);
149+
CHECK_VALUE(!__builtin_issignaling(X), IPtr);
150+
CHECK_VALUE(!__builtin_isinf(X), IPtr);
151+
CHECK_VALUE(__builtin_isfinite(X), IPtr);
152+
CHECK_VALUE(!__builtin_isnormal(X), IPtr);
153+
CHECK_VALUE(__builtin_issubnormal(X), IPtr);
154+
CHECK_VALUE(!__builtin_iszero(X), IPtr);
155+
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 3, IPtr);
178156
}
179157
for (unsigned i = 0; i < DimOf(FloatNormalValues); i++) {
180158
uint32_t *IPtr = FloatNormalValues + i;
181-
uint32_t IX = *IPtr;
182159
float X = *(float *)IPtr;
183-
CHECK_VALUE(!__builtin_isnan(X), IX);
184-
CHECK_VALUE(!__builtin_isinf(X), IX);
185-
CHECK_VALUE(__builtin_isfinite(X), IX);
186-
CHECK_VALUE(__builtin_isnormal(X), IX);
187-
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 2, IX);
160+
CHECK_VALUE(!__builtin_isnan(X), IPtr);
161+
CHECK_VALUE(!__builtin_issignaling(X), IPtr);
162+
CHECK_VALUE(!__builtin_isinf(X), IPtr);
163+
CHECK_VALUE(__builtin_isfinite(X), IPtr);
164+
CHECK_VALUE(__builtin_isnormal(X), IPtr);
165+
CHECK_VALUE(!__builtin_issubnormal(X), IPtr);
166+
CHECK_VALUE(!__builtin_iszero(X), IPtr);
167+
CHECK_VALUE(__builtin_fpclassify(0, 1, 2, 3, 4, X) == 2, IPtr);
188168
}
189169

190170
return 0;
191171
}
192172

193-
#undef INT_FORMAT
194-
#undef FLOAT_FORMAT
173+
#define FLOAT_TYPE float
174+
#include "gen_isfpclass_funcs.h"
175+
176+
void test_isfpclass_float() {
177+
for (unsigned i = 0; i < DimOf(FloatZeroValues); i++) {
178+
float X = *(float *)(FloatZeroValues + i);
179+
if (__builtin_signbit(X) == 0)
180+
test_fcPosZero_float(X);
181+
else
182+
test_fcNegZero_float(X);
183+
}
184+
for (unsigned i = 0; i < DimOf(FloatDenormValues); i++) {
185+
float X = *(float *)(FloatDenormValues + i);
186+
if (X < 0)
187+
test_fcNegSubnormal_float(X);
188+
else
189+
test_fcPosSubnormal_float(X);
190+
}
191+
for (unsigned i = 0; i < DimOf(FloatNormalValues); i++) {
192+
float X = *(float *)(FloatNormalValues + i);
193+
if (X < 0)
194+
test_fcNegNormal_float(X);
195+
else
196+
test_fcPosNormal_float(X);
197+
}
198+
for (unsigned i = 0; i < DimOf(FloatInfValues); i++) {
199+
float X = *(float *)(FloatInfValues + i);
200+
if (X > 0)
201+
test_fcPosInf_float(X);
202+
else
203+
test_fcNegInf_float(X);
204+
}
205+
for (unsigned i = 0; i < DimOf(FloatQNaNValues); i++) {
206+
float X = *(float *)(FloatQNaNValues + i);
207+
test_fcQNan_float(X);
208+
}
209+
for (unsigned i = 0; i < DimOf(FloatSNaNValues); i++) {
210+
float X = *(float *)(FloatSNaNValues + i);
211+
test_fcSNan_float(X);
212+
}
213+
test_fcPosInf_float(__builtin_inff());
214+
test_fcNegInf_float(-__builtin_inff());
215+
test_fcPosZero_float(0.0F);
216+
test_fcNegZero_float(-0.0F);
217+
}
218+
195219
#undef VAL_FORMAT
196-
#undef INT_TYPE
220+
#undef GET_VALUE
197221
#undef FLOAT_TYPE
198222

199223
#endif

0 commit comments

Comments
 (0)