Skip to content

[libc][complex] Added support for CFP16 and CFP128 #112594

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions libc/include/llvm-libc-types/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ add_header(
DEPENDS
libc.include.llvm-libc-macros.float_macros
)
add_header(
cfloat128
HDR
cfloat128.h
DEPENDS
libc.include.llvm-libc-macros.float_macros
)
add_header(cfloat16 HDR cfloat16.h)
add_header(fsblkcnt_t HDR fsblkcnt_t.h)
add_header(fsfilcnt_t HDR fsfilcnt_t.h)
add_header(
Expand Down
38 changes: 38 additions & 0 deletions libc/include/llvm-libc-types/cfloat128.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//===-- Definition of cfloat128 type --------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_TYPES_CFLOAT128_H
#define LLVM_LIBC_TYPES_CFLOAT128_H

#include "../llvm-libc-macros/float-macros.h" // LDBL_MANT_DIG

// Currently, the complex variant of C23 `_Float128` type is only defined as a
// built-in type in GCC 7 or later, and only for C. For C++, or for clang,
// the complex variant of `__float128` is defined instead, and only on x86-64
// targets.
//
// TODO: Update the complex variant of C23 `_Float128` type detection again when
// clang supports it.
// https://github.com/llvm/llvm-project/issues/80195
#if defined(__STDC_IEC_60559_COMPLEX__) && !defined(__clang__) && \
!defined(__cplusplus)
#define LIBC_TYPES_HAS_CFLOAT128
typedef _Complex _Float128 cfloat128;
#elif defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)
// Use _Complex __float128 type. gcc and clang sometime use __SIZEOF_FLOAT128__
// to notify the availability of __float128. clang also uses __FLOAT128__ macro
// to notify the availability of __float128 type:
// https://reviews.llvm.org/D15120
#define LIBC_TYPES_HAS_CFLOAT128
typedef _Complex __float128 cfloat128;
#elif (LDBL_MANT_DIG == 113)
#define LIBC_TYPES_HAS_CFLOAT128
typedef _Complex long double cfloat128;
#endif

#endif // LLVM_LIBC_TYPES_CFLOAT128_H
20 changes: 20 additions & 0 deletions libc/include/llvm-libc-types/cfloat16.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Definition of cfloat16 type ---------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_TYPES_CFLOAT16_H
#define LLVM_LIBC_TYPES_CFLOAT16_H

#if defined(__FLT16_MANT_DIG__) && \
(!defined(__GNUC__) || __GNUC__ >= 13 || defined(__clang__)) && \
!defined(__arm__) && !defined(_M_ARM) && !defined(__riscv) && \
!defined(_WIN32)
#define LIBC_TYPES_HAS_CFLOAT16
typedef _Complex _Float16 cfloat16;
#endif

#endif // LLVM_LIBC_TYPES_CFLOAT16_H
2 changes: 2 additions & 0 deletions libc/src/__support/CPP/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ add_header_library(
type_traits/is_array.h
type_traits/is_base_of.h
type_traits/is_class.h
type_traits/is_complex.h
type_traits/is_const.h
type_traits/is_constant_evaluated.h
type_traits/is_convertible.h
Expand Down Expand Up @@ -165,6 +166,7 @@ add_header_library(
libc.include.llvm-libc-macros.stdfix_macros
libc.src.__support.macros.attributes
libc.src.__support.macros.properties.types
libc.src.__support.macros.properties.complex_types
)

add_header_library(
Expand Down
1 change: 0 additions & 1 deletion libc/src/__support/CPP/type_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
#include "src/__support/CPP/type_traits/is_array.h"
#include "src/__support/CPP/type_traits/is_base_of.h"
#include "src/__support/CPP/type_traits/is_class.h"
#include "src/__support/CPP/type_traits/is_complex.h"
#include "src/__support/CPP/type_traits/is_const.h"
#include "src/__support/CPP/type_traits/is_constant_evaluated.h"
#include "src/__support/CPP/type_traits/is_convertible.h"
Expand Down
15 changes: 14 additions & 1 deletion libc/src/__support/CPP/type_traits/is_complex.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@

#include "src/__support/CPP/type_traits/is_same.h"
#include "src/__support/CPP/type_traits/remove_cv.h"
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
// LIBC_TYPES_HAS_CFLOAT16 && LIBC_TYPES_HAS_CFLOAT128
#include "src/__support/macros/properties/complex_types.h"

namespace LIBC_NAMESPACE_DECL {
namespace cpp {
Expand All @@ -25,7 +29,16 @@ template <typename T> struct is_complex {
public:
LIBC_INLINE_VAR static constexpr bool value =
__is_unqualified_any_of<T, _Complex float, _Complex double,
_Complex long double>();
_Complex long double
#ifdef LIBC_TYPES_HAS_CFLOAT16
,
cfloat16
#endif
#ifdef LIBC_TYPES_HAS_CFLOAT128
,
cfloat128
#endif
>();
};
template <typename T>
LIBC_INLINE_VAR constexpr bool is_complex_v = is_complex<T>::value;
Expand Down
10 changes: 10 additions & 0 deletions libc/src/__support/macros/properties/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,13 @@ add_header_library(
libc.include.llvm-libc-macros.float16_macros
libc.include.llvm-libc-types.float128
)

add_header_library(
complex_types
HDRS
complex_types.h
DEPENDS
.types
libc.include.llvm-libc-types.cfloat16
libc.include.llvm-libc-types.cfloat128
)
25 changes: 25 additions & 0 deletions libc/src/__support/macros/properties/complex_types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//===-- Complex Types support -----------------------------------*- 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
//
//===----------------------------------------------------------------------===//
// Complex Types detection and support.

#ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_CTYPES_H
#define LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_CTYPES_H

#include "include/llvm-libc-types/cfloat128.h"
#include "include/llvm-libc-types/cfloat16.h"
#include "types.h"

// -- cfloat16 support --------------------------------------------------------
// LIBC_TYPES_HAS_CFLOAT16 and 'cfloat16' type is provided by
// "include/llvm-libc-types/cfloat16.h"

// -- cfloat128 support -------------------------------------------------------
// LIBC_TYPES_HAS_CFLOAT128 and 'cfloat128' type are provided by
// "include/llvm-libc-types/cfloat128.h"

#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_CTYPES_H
17 changes: 17 additions & 0 deletions libc/test/UnitTest/FPMatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "src/__support/CPP/array.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/CPP/type_traits/is_complex.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/fpbits_str.h"
Expand Down Expand Up @@ -128,6 +129,14 @@ template <typename T, TestCond Condition> class CFPMatcher : public Matcher<T> {
return matchComplex<double>();
else if (cpp::is_complex_type_same<T, _Complex long double>())
return matchComplex<long double>();
#ifdef LIBC_TYPES_HAS_CFLOAT16
else if (cpp::is_complex_type_same<T, cfloat16>)
return matchComplex<float16>();
#endif
#ifdef LIBC_TYPES_HAS_CFLOAT128
else if (cpp::is_complex_type_same<T, cfloat128>)
return matchComplex<float128>();
#endif
}

void explainError() override {
Expand All @@ -137,6 +146,14 @@ template <typename T, TestCond Condition> class CFPMatcher : public Matcher<T> {
return explainErrorComplex<double>();
else if (cpp::is_complex_type_same<T, _Complex long double>())
return explainErrorComplex<long double>();
#ifdef LIBC_TYPES_HAS_CFLOAT16
else if (cpp::is_complex_type_same<T, cfloat16>)
return explainErrorComplex<float16>();
#endif
#ifdef LIBC_TYPES_HAS_CFLOAT128
else if (cpp::is_complex_type_same<T, cfloat128>)
return explainErrorComplex<float128>();
#endif
}
};

Expand Down
Loading