Skip to content

Commit fd77ee9

Browse files
committed
Conditionalize NaN-handling parts of tests
Now we only try to test the difficult parts if we're using the new implementations, and otherwise, fall back to treating all NaNs as good enough when a NaN result is expected.
1 parent a6f6263 commit fd77ee9

File tree

2 files changed

+71
-16
lines changed

2 files changed

+71
-16
lines changed

compiler-rt/test/builtins/Unit/addsf3_test.c

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,27 @@
1111

1212
#include "fp_test.h"
1313

14+
// By default this test uses compareResultF to check the returned floats, which
15+
// accepts any returned NaN if the expected result is the canonical NaN value
16+
// 0x7fc00000. For the Thumb1 assembler FP implementation, which commits to a
17+
// more detailed handling of NaNs, we tighten up the check and include some
18+
// extra test cases specific to that NaN policy.
19+
#if __thumb__ && !__thumb2__
20+
# define EXPECT_EXACT_RESULTS
21+
# define ARM_NAN_HANDLING
22+
#endif
23+
1424
// Returns: a + b
1525
COMPILER_RT_ABI float __addsf3(float a, float b);
1626

1727
int test__addsf3(uint32_t a_rep, uint32_t b_rep, uint32_t expected_rep) {
1828
float a = fromRep32(a_rep), b = fromRep32(b_rep);
1929
float x = __addsf3(a, b);
30+
#ifdef EXPECT_EXACT_RESULTS
31+
int ret = toRep32(x) == expected_rep;
32+
#else
2033
int ret = compareResultF(x, expected_rep);
34+
#endif
2135

2236
if (ret) {
2337
printf("error in test__addsf3(%08" PRIx32 ", %08" PRIx32 ") = %08" PRIx32
@@ -275,10 +289,23 @@ int main() {
275289
status |= test__addsf3(0xbbebe66d, 0x3b267c1f, 0xbb98a85e);
276290
status |= test__addsf3(0x01f5b166, 0x81339a37, 0x019be44a);
277291

278-
#if __thumb__ && !__thumb2__
279-
// These tests depend on Arm-specific IEEE 754 implementation choices
280-
// regarding NaNs, which are satisfied by arm/addsf3.S but not guaranteed by
281-
// other implementations:
292+
// Test that the result of an operation is a NaN at all when it should be.
293+
//
294+
// In most configurations these tests' results are checked compared using
295+
// compareResultF, so we set all the answers to the canonical NaN 0x7fc00000,
296+
// which causes compareResultF to accept any NaN encoding. We also use the
297+
// same value as the input NaN in tests that have one, so that even in
298+
// EXPECT_EXACT_RESULTS mode these tests should pass, because 0x7fc00000 is
299+
// still the exact expected NaN.
300+
status |= test__addsf3(0x7f800000, 0xff800000, 0x7fc00000);
301+
status |= test__addsf3(0xff800000, 0x7f800000, 0x7fc00000);
302+
status |= test__addsf3(0x3f800000, 0x7fc00000, 0x7fc00000);
303+
status |= test__addsf3(0x7fc00000, 0x3f800000, 0x7fc00000);
304+
status |= test__addsf3(0x7fc00000, 0x7fc00000, 0x7fc00000);
305+
306+
#ifdef ARM_NAN_HANDLING
307+
// Tests specific to the NaN handling of Arm hardware, mimicked by
308+
// arm/addsf3.S:
282309
//
283310
// - a quiet NaN is distinguished by the top mantissa bit being 1
284311
//
@@ -290,7 +317,10 @@ int main() {
290317
// from the first operand
291318
//
292319
// - if both operands are quiet NaNs then the output NaN is the first
293-
// operand.
320+
// operand
321+
//
322+
// - invalid operations not involving an input NaN return the quiet
323+
// NaN with fewest bits set, 0x7fc00000.
294324

295325
status |= test__addsf3(0x00000000, 0x7fad4be3, 0x7fed4be3);
296326
status |= test__addsf3(0x00000000, 0x7fdf48c7, 0x7fdf48c7);
@@ -346,7 +376,7 @@ int main() {
346376
status |= test__addsf3(0xff800000, 0x7f800000, 0x7fc00000);
347377
status |= test__addsf3(0xff800000, 0x7f857fdc, 0x7fc57fdc);
348378
status |= test__addsf3(0xff800000, 0x7fde0397, 0x7fde0397);
349-
#endif // __arm__
379+
#endif // ARM_NAN_HANDLING
350380

351381
return status;
352382
}

compiler-rt/test/builtins/Unit/subsf3_test.c

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,27 @@
1111

1212
#include "fp_test.h"
1313

14-
// Returns: a + b
14+
// By default this test uses compareResultF to check the returned floats, which
15+
// accepts any returned NaN if the expected result is the canonical NaN value
16+
// 0x7fc00000. For the Thumb1 optimized FP implementation, which commits to a
17+
// more detailed handling of NaNs, we tighten up the check and include some
18+
// extra test cases specific to that NaN policy.
19+
#if __thumb__ && !__thumb2__
20+
# define EXPECT_EXACT_RESULTS
21+
# define ARM_NAN_HANDLING
22+
#endif
23+
24+
// Returns: a - b
1525
COMPILER_RT_ABI float __subsf3(float a, float b);
1626

1727
int test__subsf3(uint32_t a_rep, uint32_t b_rep, uint32_t expected_rep) {
1828
float a = fromRep32(a_rep), b = fromRep32(b_rep);
1929
float x = __subsf3(a, b);
30+
#ifdef EXPECT_EXACT_RESULTS
31+
int ret = toRep32(x) == expected_rep;
32+
#else
2033
int ret = compareResultF(x, expected_rep);
34+
#endif
2135

2236
if (ret) {
2337
printf("error in test__subsf3(%08" PRIx32 ", %08" PRIx32 ") = %08" PRIx32
@@ -273,10 +287,23 @@ int main() {
273287
status |= test__subsf3(0x007ffff7, 0x00f7ffff, 0x80780008);
274288
status |= test__subsf3(0x80ffffbf, 0x80800000, 0x807fffbf);
275289

276-
#if __thumb__ && !__thumb2__
277-
// These tests depend on Arm-specific IEEE 754 implementation choices
278-
// regarding NaNs, which are satisfied by arm/addsf3.S but not guaranteed by
279-
// other implementations:
290+
// Test that the result of an operation is a NaN at all when it should be.
291+
//
292+
// In most configurations these tests' results are checked compared using
293+
// compareResultF, so we set all the answers to the canonical NaN 0x7fc00000,
294+
// which causes compareResultF to accept any NaN encoding. We also use the
295+
// same value as the input NaN in tests that have one, so that even in
296+
// EXPECT_EXACT_RESULTS mode these tests should pass, because 0x7fc00000 is
297+
// still the exact expected NaN.
298+
status |= test__subsf3(0x7f800000, 0x7f800000, 0x7fc00000);
299+
status |= test__subsf3(0xff800000, 0xff800000, 0x7fc00000);
300+
status |= test__subsf3(0x3f800000, 0x7fc00000, 0x7fc00000);
301+
status |= test__subsf3(0x7fc00000, 0x3f800000, 0x7fc00000);
302+
status |= test__subsf3(0x7fc00000, 0x7fc00000, 0x7fc00000);
303+
304+
#ifdef ARM_NAN_HANDLING
305+
// Tests specific to the NaN handling of Arm hardware, mimicked by the
306+
// subtraction function in arm/addsf3.S:
280307
//
281308
// - a quiet NaN is distinguished by the top mantissa bit being 1
282309
//
@@ -290,10 +317,8 @@ int main() {
290317
// - if both operands are quiet NaNs then the output NaN is the first
291318
// operand
292319
//
293-
// - subtraction is treated as a first-class operation, not just "flip the
294-
// sign of operand 2 and add". So if the output is a NaN derived from
295-
// second operand (with or without quietening), the sign bit is the same
296-
// as that of the original operand.
320+
// - invalid operations not involving an input NaN return the quiet
321+
// NaN with fewest bits set, 0x7fc00000.
297322

298323
status |= test__subsf3(0x00000000, 0x7fad4be3, 0x7fed4be3);
299324
status |= test__subsf3(0x00000000, 0x7fdf48c7, 0x7fdf48c7);
@@ -349,7 +374,7 @@ int main() {
349374
status |= test__subsf3(0xff800000, 0x7f857fdc, 0x7fc57fdc);
350375
status |= test__subsf3(0xff800000, 0x7fde0397, 0x7fde0397);
351376
status |= test__subsf3(0xff800000, 0xff800000, 0x7fc00000);
352-
#endif // __arm__
377+
#endif // ARM_NAN_HANDLING
353378

354379
return status;
355380
}

0 commit comments

Comments
 (0)