Skip to content

Commit

Permalink
[libc][complex] Added support for CFP16 and CFP128 (#112594)
Browse files Browse the repository at this point in the history
Fixes: #112217
  • Loading branch information
Sh0g0-1758 authored Oct 18, 2024
1 parent 761fa58 commit 7be4ab0
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 2 deletions.
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

0 comments on commit 7be4ab0

Please sign in to comment.