Skip to content

Commit a5dd646

Browse files
biabbasarichardson
andauthored
Add extendhfxf2 into compiler rt (#113897)
Retry of pr #109090 and #111099. Co-authored-by: Alexander Richardson <[email protected]>
1 parent d047bee commit a5dd646

File tree

3 files changed

+90
-0
lines changed

3 files changed

+90
-0
lines changed

compiler-rt/lib/builtins/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ endif ()
296296
# long double is not 80 bits on Android or MSVC.
297297
set(x86_80_BIT_SOURCES
298298
divxc3.c
299+
extendhfxf2.c
299300
extendxftf2.c
300301
fixxfdi.c
301302
fixxfti.c
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//===-- lib/extendhfxf2.c - half -> long double conversion --------*- C -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
#include "int_lib.h"
9+
#define SRC_HALF
10+
#define DST_DOUBLE
11+
#include "fp_extend_impl.inc"
12+
13+
// Long double are expected to be as precise as double.
14+
COMPILER_RT_ABI xf_float __extendhfxf2(src_t a) {
15+
return (xf_float)__extendXfYf2__(a);
16+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// RUN: %clang_builtins %s %librt -o %t && %run %t
2+
// REQUIRES: librt_has_extendhfxf2
3+
4+
#include <limits.h>
5+
#include <math.h> // for isnan, isinf
6+
#include <stdio.h>
7+
8+
#include "int_lib.h"
9+
10+
#if HAS_80_BIT_LONG_DOUBLE && defined(COMPILER_RT_HAS_FLOAT16)
11+
12+
long double __extendhfxf2(_Float16 f);
13+
14+
int test_extendhfxf2(_Float16 a, long double expected) {
15+
long double x = __extendhfxf2(a);
16+
__uint16_t *b = (void *)&a;
17+
int ret = !((isnan(x) && isnan(expected)) || x == expected);
18+
if (ret) {
19+
printf("error in test__extendhfxf2(%#.4x) = %.20Lf, "
20+
"expected %.20Lf\n",
21+
*b, x, expected);
22+
}
23+
return ret;
24+
}
25+
26+
char assumption_1[sizeof(_Float16) * CHAR_BIT == 16] = {0};
27+
28+
int main() {
29+
// Small positive value
30+
if (test_extendhfxf2(0.09997558593750000000f, 0.09997558593750000000L))
31+
return 1;
32+
33+
// Small negative value
34+
if (test_extendhfxf2(-0.09997558593750000000f, -0.09997558593750000000L))
35+
return 1;
36+
37+
// Zero
38+
if (test_extendhfxf2(0.0f, 0.0L))
39+
return 1;
40+
41+
// Smallest positive non-zero value
42+
if (test_extendhfxf2(0x1p-16f, 0x1p-16L))
43+
return 1;
44+
45+
// Smallest negative non-zero value
46+
if (test_extendhfxf2(-0x1p-16f, -0x1p-16L))
47+
return 1;
48+
49+
// Positive infinity
50+
if (test_extendhfxf2(__builtin_huge_valf16(), __builtin_huge_valf64x()))
51+
return 1;
52+
53+
// Negative infinity
54+
if (test_extendhfxf2(-__builtin_huge_valf16(),
55+
(long double)-__builtin_huge_valf64x()))
56+
return 1;
57+
58+
// NaN
59+
if (test_extendhfxf2(__builtin_nanf16(""),
60+
(long double)__builtin_nanf64x("")))
61+
return 1;
62+
63+
return 0;
64+
}
65+
66+
#else
67+
68+
int main() {
69+
printf("skipped\n");
70+
return 0;
71+
}
72+
73+
#endif

0 commit comments

Comments
 (0)