Skip to content

Commit 66a3bcb

Browse files
committed
Update build and test setup
Now we should only test the extra NaN faithfulness in cases where it's provided by the library. Also tweaked the cmake setup to make it easier to add more assembly files later. Plus a missing piece of comment in fnan2.c.
1 parent 40e3621 commit 66a3bcb

File tree

5 files changed

+97
-18
lines changed

5 files changed

+97
-18
lines changed

compiler-rt/lib/builtins/CMakeLists.txt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -426,17 +426,19 @@ option(COMPILER_RT_ARM_OPTIMIZED_FP
426426
"On 32-bit Arm, use optimized assembly implementations of FP arithmetic. Likely to increase code size, but be faster." ON)
427427

428428
if(COMPILER_RT_ARM_OPTIMIZED_FP)
429-
set(arm_or_thumb2_base_SOURCES
429+
set(assembly_files
430430
arm/mulsf3.S
431-
arm/divsf3.S
431+
arm/divsf3.S)
432+
set_source_files_properties(${assembly_files}
433+
PROPERTIES COMPILE_OPTIONS "-Wa,-mimplicit-it=always")
434+
set(arm_or_thumb2_base_SOURCES
435+
${assembly_files}
432436
arm/fnan2.c
433437
arm/fnorm2.c
434438
arm/funder.c
435439
${arm_or_thumb2_base_SOURCES}
436440
)
437441
endif()
438-
set_source_files_properties(arm/mulsf3.S arm/divsf3.S
439-
PROPERTIES COMPILE_OPTIONS "-Wa,-mimplicit-it=always")
440442

441443
set(arm_sync_SOURCES
442444
arm/sync_fetch_and_add_4.S

compiler-rt/lib/builtins/arm/fnan2.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@
1313
// On input, a and b are floating-point numbers in IEEE 754 encoding, and at
1414
// least one of them must be a NaN. The return value is the correct output NaN.
1515
//
16+
// A signalling NaN in the input (with bit 22 clear) takes priority over any
17+
// quiet NaN, and is adjusted on return by setting bit 22 to make it quiet. If
18+
// both inputs are the same type of NaN then the first input takes priority:
19+
// the input a is used instead of b.
20+
//
1621
//===----------------------------------------------------------------------===//
1722

1823
#include <stdint.h>

compiler-rt/test/builtins/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ if(APPLE)
3535
darwin_filter_host_archs(BUILTIN_SUPPORTED_ARCH BUILTIN_TEST_ARCH)
3636
endif()
3737

38+
if(COMPILER_RT_ARM_OPTIMIZED_FP)
39+
list(APPEND BUILTINS_TEST_TARGET_CFLAGS -DCOMPILER_RT_ARM_OPTIMIZED_FP)
40+
endif()
41+
3842
foreach(arch ${BUILTIN_TEST_ARCH})
3943
set(BUILTINS_TEST_TARGET_ARCH ${arch})
4044
string(TOLOWER "-${arch}-${OS_NAME}" BUILTINS_TEST_CONFIG_SUFFIX)

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

Lines changed: 42 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 Arm optimized FP implementation, which commits to a more
17+
// detailed handling of NaNs, we tighten up the check and include some extra
18+
// test cases specific to that NaN policy.
19+
#if (__arm__ && !(__thumb__ && !__thumb2__)) && COMPILER_RT_ARM_OPTIMIZED_FP
20+
# define EXPECT_EXACT_RESULTS
21+
# define ARM_NAN_HANDLING
22+
#endif
23+
1424
// Returns: a / b
1525
COMPILER_RT_ABI float __divsf3(float a, float b);
1626

1727
int test__divsf3(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 = __divsf3(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__divsf3(%08" PRIx32 ", %08" PRIx32 ") = %08" PRIx32
@@ -309,10 +323,29 @@ int main(void) {
309323
status |= test__divsf3(0x2cbed883, 0x333f6113, 0x38ff4953);
310324
status |= test__divsf3(0x3f87ffff, 0x7f001000, 0x0043f781);
311325

312-
#if __thumb__ && !__thumb2__
313-
// These tests depend on Arm-specific IEEE 754 implementation choices
314-
// regarding NaNs, which are satisfied by arm/mulsf3.S but not guaranteed by
315-
// other implementations:
326+
// Test that the result of an operation is a NaN at all when it should be.
327+
//
328+
// In most configurations these tests' results are checked compared using
329+
// compareResultF, so we set all the answers to the canonical NaN 0x7fc00000,
330+
// which causes compareResultF to accept any NaN encoding. We also use the
331+
// same value as the input NaN in tests that have one, so that even in
332+
// EXPECT_EXACT_RESULTS mode these tests should pass, because 0x7fc00000 is
333+
// still the exact expected NaN.
334+
status |= test__divsf3(0x00000000, 0x00000000, 0x7fc00000);
335+
status |= test__divsf3(0x00000000, 0x80000000, 0x7fc00000);
336+
status |= test__divsf3(0x7f800000, 0x7f800000, 0x7fc00000);
337+
status |= test__divsf3(0x7f800000, 0xff800000, 0x7fc00000);
338+
status |= test__divsf3(0x80000000, 0x00000000, 0x7fc00000);
339+
status |= test__divsf3(0x80000000, 0x80000000, 0x7fc00000);
340+
status |= test__divsf3(0xff800000, 0x7f800000, 0x7fc00000);
341+
status |= test__divsf3(0xff800000, 0xff800000, 0x7fc00000);
342+
status |= test__divsf3(0x3f800000, 0x7fc00000, 0x7fc00000);
343+
status |= test__divsf3(0x7fc00000, 0x3f800000, 0x7fc00000);
344+
status |= test__divsf3(0x7fc00000, 0x7fc00000, 0x7fc00000);
345+
346+
#ifdef ARM_NAN_HANDLING
347+
// Tests specific to the NaN handling of Arm hardware, mimicked by
348+
// arm/divsf3.S:
316349
//
317350
// - a quiet NaN is distinguished by the top mantissa bit being 1
318351
//
@@ -324,7 +357,10 @@ int main(void) {
324357
// from the first operand
325358
//
326359
// - if both operands are quiet NaNs then the output NaN is the first
327-
// operand.
360+
// operand
361+
//
362+
// - invalid operations not involving an input NaN return the quiet
363+
// NaN with fewest bits set, 0x7fc00000.
328364

329365
status |= test__divsf3(0x00000000, 0x00000000, 0x7fc00000);
330366
status |= test__divsf3(0x00000000, 0x7fad4be3, 0x7fed4be3);
@@ -386,7 +422,7 @@ int main(void) {
386422
status |= test__divsf3(0xff800000, 0x7f857fdc, 0x7fc57fdc);
387423
status |= test__divsf3(0xff800000, 0x7fde0397, 0x7fde0397);
388424
status |= test__divsf3(0xff800000, 0xff800000, 0x7fc00000);
389-
#endif // __arm__
425+
#endif // ARM_NAN_HANDLING
390426

391427
return status;
392428
}

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

Lines changed: 40 additions & 8 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 Arm optimized FP implementation, which commits to a more
17+
// detailed handling of NaNs, we tighten up the check and include some extra
18+
// test cases specific to that NaN policy.
19+
#if (__arm__ && !(__thumb__ && !__thumb2__)) && COMPILER_RT_ARM_OPTIMIZED_FP
20+
# define EXPECT_EXACT_RESULTS
21+
# define ARM_NAN_HANDLING
22+
#endif
23+
24+
// Returns: a * b
1525
COMPILER_RT_ABI float __mulsf3(float a, float b);
1626

1727
int test__mulsf3(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 = __mulsf3(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__mulsf3(%08" PRIx32 ", %08" PRIx32 ") = %08" PRIx32
@@ -27,7 +41,7 @@ int test__mulsf3(uint32_t a_rep, uint32_t b_rep, uint32_t expected_rep) {
2741
return ret;
2842
}
2943

30-
int main() {
44+
int main(void) {
3145
int status = 0;
3246

3347
status |= test__mulsf3(0x00000000, 0x00000000, 0x00000000);
@@ -505,10 +519,25 @@ int main() {
505519
status |= test__mulsf3(0x19ffc008, 0x1a002004, 0x00000001);
506520
status |= test__mulsf3(0x7f7ffff0, 0xc0000008, 0xff800000);
507521

508-
#if __thumb__ && !__thumb2__
509-
// These tests depend on Arm-specific IEEE 754 implementation choices
510-
// regarding NaNs, which are satisfied by arm/mulsf3.S but not guaranteed by
511-
// other implementations:
522+
// Test that the result of an operation is a NaN at all when it should be.
523+
//
524+
// In most configurations these tests' results are checked compared using
525+
// compareResultF, so we set all the answers to the canonical NaN 0x7fc00000,
526+
// which causes compareResultF to accept any NaN encoding. We also use the
527+
// same value as the input NaN in tests that have one, so that even in
528+
// EXPECT_EXACT_RESULTS mode these tests should pass, because 0x7fc00000 is
529+
// still the exact expected NaN.
530+
status |= test__mulsf3(0x7f800000, 0x00000000, 0x7fc00000);
531+
status |= test__mulsf3(0x7f800000, 0x80000000, 0x7fc00000);
532+
status |= test__mulsf3(0x80000000, 0x7f800000, 0x7fc00000);
533+
status |= test__mulsf3(0x80000000, 0xff800000, 0x7fc00000);
534+
status |= test__mulsf3(0x3f800000, 0x7fc00000, 0x7fc00000);
535+
status |= test__mulsf3(0x7fc00000, 0x3f800000, 0x7fc00000);
536+
status |= test__mulsf3(0x7fc00000, 0x7fc00000, 0x7fc00000);
537+
538+
#ifdef ARM_NAN_HANDLING
539+
// Tests specific to the NaN handling of Arm hardware, mimicked by
540+
// arm/mulsf3.S:
512541
//
513542
// - a quiet NaN is distinguished by the top mantissa bit being 1
514543
//
@@ -520,7 +549,10 @@ int main() {
520549
// from the first operand
521550
//
522551
// - if both operands are quiet NaNs then the output NaN is the first
523-
// operand.
552+
// operand
553+
//
554+
// - invalid operations not involving an input NaN return the quiet
555+
// NaN with fewest bits set, 0x7fc00000.
524556

525557
status |= test__mulsf3(0x00000000, 0x7fad4be3, 0x7fed4be3);
526558
status |= test__mulsf3(0x00000000, 0x7fdf48c7, 0x7fdf48c7);
@@ -578,7 +610,7 @@ int main() {
578610
status |= test__mulsf3(0xff7fffff, 0x7feb00d7, 0x7feb00d7);
579611
status |= test__mulsf3(0xff800000, 0x7f857fdc, 0x7fc57fdc);
580612
status |= test__mulsf3(0xff800000, 0x7fde0397, 0x7fde0397);
581-
#endif // __arm__
613+
#endif // ARM_NAN_HANDLING
582614

583615
return status;
584616
}

0 commit comments

Comments
 (0)