Add extendhfxf2 into compiler rt (#113897)

Retry of pr #109090 and #111099.

Co-authored-by: Alexander Richardson <alexrichardson@google.com>
This commit is contained in:
B I Mohammed Abbas
2024-11-25 23:49:27 +05:30
committed by GitHub
parent d047bee496
commit a5dd646360
3 changed files with 90 additions and 0 deletions

View File

@@ -296,6 +296,7 @@ endif ()
# long double is not 80 bits on Android or MSVC.
set(x86_80_BIT_SOURCES
divxc3.c
extendhfxf2.c
extendxftf2.c
fixxfdi.c
fixxfti.c

View File

@@ -0,0 +1,16 @@
//===-- lib/extendhfxf2.c - half -> long double conversion --------*- C -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "int_lib.h"
#define SRC_HALF
#define DST_DOUBLE
#include "fp_extend_impl.inc"
// Long double are expected to be as precise as double.
COMPILER_RT_ABI xf_float __extendhfxf2(src_t a) {
return (xf_float)__extendXfYf2__(a);
}

View File

@@ -0,0 +1,73 @@
// RUN: %clang_builtins %s %librt -o %t && %run %t
// REQUIRES: librt_has_extendhfxf2
#include <limits.h>
#include <math.h> // for isnan, isinf
#include <stdio.h>
#include "int_lib.h"
#if HAS_80_BIT_LONG_DOUBLE && defined(COMPILER_RT_HAS_FLOAT16)
long double __extendhfxf2(_Float16 f);
int test_extendhfxf2(_Float16 a, long double expected) {
long double x = __extendhfxf2(a);
__uint16_t *b = (void *)&a;
int ret = !((isnan(x) && isnan(expected)) || x == expected);
if (ret) {
printf("error in test__extendhfxf2(%#.4x) = %.20Lf, "
"expected %.20Lf\n",
*b, x, expected);
}
return ret;
}
char assumption_1[sizeof(_Float16) * CHAR_BIT == 16] = {0};
int main() {
// Small positive value
if (test_extendhfxf2(0.09997558593750000000f, 0.09997558593750000000L))
return 1;
// Small negative value
if (test_extendhfxf2(-0.09997558593750000000f, -0.09997558593750000000L))
return 1;
// Zero
if (test_extendhfxf2(0.0f, 0.0L))
return 1;
// Smallest positive non-zero value
if (test_extendhfxf2(0x1p-16f, 0x1p-16L))
return 1;
// Smallest negative non-zero value
if (test_extendhfxf2(-0x1p-16f, -0x1p-16L))
return 1;
// Positive infinity
if (test_extendhfxf2(__builtin_huge_valf16(), __builtin_huge_valf64x()))
return 1;
// Negative infinity
if (test_extendhfxf2(-__builtin_huge_valf16(),
(long double)-__builtin_huge_valf64x()))
return 1;
// NaN
if (test_extendhfxf2(__builtin_nanf16(""),
(long double)__builtin_nanf64x("")))
return 1;
return 0;
}
#else
int main() {
printf("skipped\n");
return 0;
}
#endif