Skip to content

Commit 7be4ab0

Browse files
authored
[libc][complex] Added support for CFP16 and CFP128 (#112594)
Fixes: #112217
1 parent 761fa58 commit 7be4ab0

File tree

9 files changed

+134
-2
lines changed

9 files changed

+134
-2
lines changed

libc/include/llvm-libc-types/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,14 @@ add_header(
134134
DEPENDS
135135
libc.include.llvm-libc-macros.float_macros
136136
)
137+
add_header(
138+
cfloat128
139+
HDR
140+
cfloat128.h
141+
DEPENDS
142+
libc.include.llvm-libc-macros.float_macros
143+
)
144+
add_header(cfloat16 HDR cfloat16.h)
137145
add_header(fsblkcnt_t HDR fsblkcnt_t.h)
138146
add_header(fsfilcnt_t HDR fsfilcnt_t.h)
139147
add_header(
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//===-- Definition of cfloat128 type --------------------------------------===//
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+
9+
#ifndef LLVM_LIBC_TYPES_CFLOAT128_H
10+
#define LLVM_LIBC_TYPES_CFLOAT128_H
11+
12+
#include "../llvm-libc-macros/float-macros.h" // LDBL_MANT_DIG
13+
14+
// Currently, the complex variant of C23 `_Float128` type is only defined as a
15+
// built-in type in GCC 7 or later, and only for C. For C++, or for clang,
16+
// the complex variant of `__float128` is defined instead, and only on x86-64
17+
// targets.
18+
//
19+
// TODO: Update the complex variant of C23 `_Float128` type detection again when
20+
// clang supports it.
21+
// https://github.com/llvm/llvm-project/issues/80195
22+
#if defined(__STDC_IEC_60559_COMPLEX__) && !defined(__clang__) && \
23+
!defined(__cplusplus)
24+
#define LIBC_TYPES_HAS_CFLOAT128
25+
typedef _Complex _Float128 cfloat128;
26+
#elif defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)
27+
// Use _Complex __float128 type. gcc and clang sometime use __SIZEOF_FLOAT128__
28+
// to notify the availability of __float128. clang also uses __FLOAT128__ macro
29+
// to notify the availability of __float128 type:
30+
// https://reviews.llvm.org/D15120
31+
#define LIBC_TYPES_HAS_CFLOAT128
32+
typedef _Complex __float128 cfloat128;
33+
#elif (LDBL_MANT_DIG == 113)
34+
#define LIBC_TYPES_HAS_CFLOAT128
35+
typedef _Complex long double cfloat128;
36+
#endif
37+
38+
#endif // LLVM_LIBC_TYPES_CFLOAT128_H
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Definition of cfloat16 type ---------------------------------------===//
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+
9+
#ifndef LLVM_LIBC_TYPES_CFLOAT16_H
10+
#define LLVM_LIBC_TYPES_CFLOAT16_H
11+
12+
#if defined(__FLT16_MANT_DIG__) && \
13+
(!defined(__GNUC__) || __GNUC__ >= 13 || defined(__clang__)) && \
14+
!defined(__arm__) && !defined(_M_ARM) && !defined(__riscv) && \
15+
!defined(_WIN32)
16+
#define LIBC_TYPES_HAS_CFLOAT16
17+
typedef _Complex _Float16 cfloat16;
18+
#endif
19+
20+
#endif // LLVM_LIBC_TYPES_CFLOAT16_H

libc/src/__support/CPP/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ add_header_library(
126126
type_traits/is_array.h
127127
type_traits/is_base_of.h
128128
type_traits/is_class.h
129+
type_traits/is_complex.h
129130
type_traits/is_const.h
130131
type_traits/is_constant_evaluated.h
131132
type_traits/is_convertible.h
@@ -165,6 +166,7 @@ add_header_library(
165166
libc.include.llvm-libc-macros.stdfix_macros
166167
libc.src.__support.macros.attributes
167168
libc.src.__support.macros.properties.types
169+
libc.src.__support.macros.properties.complex_types
168170
)
169171

170172
add_header_library(

libc/src/__support/CPP/type_traits.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include "src/__support/CPP/type_traits/is_array.h"
2626
#include "src/__support/CPP/type_traits/is_base_of.h"
2727
#include "src/__support/CPP/type_traits/is_class.h"
28-
#include "src/__support/CPP/type_traits/is_complex.h"
2928
#include "src/__support/CPP/type_traits/is_const.h"
3029
#include "src/__support/CPP/type_traits/is_constant_evaluated.h"
3130
#include "src/__support/CPP/type_traits/is_convertible.h"

libc/src/__support/CPP/type_traits/is_complex.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010

1111
#include "src/__support/CPP/type_traits/is_same.h"
1212
#include "src/__support/CPP/type_traits/remove_cv.h"
13+
#include "src/__support/macros/attributes.h"
14+
#include "src/__support/macros/config.h"
15+
// LIBC_TYPES_HAS_CFLOAT16 && LIBC_TYPES_HAS_CFLOAT128
16+
#include "src/__support/macros/properties/complex_types.h"
1317

1418
namespace LIBC_NAMESPACE_DECL {
1519
namespace cpp {
@@ -25,7 +29,16 @@ template <typename T> struct is_complex {
2529
public:
2630
LIBC_INLINE_VAR static constexpr bool value =
2731
__is_unqualified_any_of<T, _Complex float, _Complex double,
28-
_Complex long double>();
32+
_Complex long double
33+
#ifdef LIBC_TYPES_HAS_CFLOAT16
34+
,
35+
cfloat16
36+
#endif
37+
#ifdef LIBC_TYPES_HAS_CFLOAT128
38+
,
39+
cfloat128
40+
#endif
41+
>();
2942
};
3043
template <typename T>
3144
LIBC_INLINE_VAR constexpr bool is_complex_v = is_complex<T>::value;

libc/src/__support/macros/properties/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,13 @@ add_header_library(
3737
libc.include.llvm-libc-macros.float16_macros
3838
libc.include.llvm-libc-types.float128
3939
)
40+
41+
add_header_library(
42+
complex_types
43+
HDRS
44+
complex_types.h
45+
DEPENDS
46+
.types
47+
libc.include.llvm-libc-types.cfloat16
48+
libc.include.llvm-libc-types.cfloat128
49+
)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//===-- Complex Types support -----------------------------------*- 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+
// Complex Types detection and support.
9+
10+
#ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_CTYPES_H
11+
#define LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_CTYPES_H
12+
13+
#include "include/llvm-libc-types/cfloat128.h"
14+
#include "include/llvm-libc-types/cfloat16.h"
15+
#include "types.h"
16+
17+
// -- cfloat16 support --------------------------------------------------------
18+
// LIBC_TYPES_HAS_CFLOAT16 and 'cfloat16' type is provided by
19+
// "include/llvm-libc-types/cfloat16.h"
20+
21+
// -- cfloat128 support -------------------------------------------------------
22+
// LIBC_TYPES_HAS_CFLOAT128 and 'cfloat128' type are provided by
23+
// "include/llvm-libc-types/cfloat128.h"
24+
25+
#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_CTYPES_H

libc/test/UnitTest/FPMatcher.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "src/__support/CPP/array.h"
1313
#include "src/__support/CPP/type_traits.h"
14+
#include "src/__support/CPP/type_traits/is_complex.h"
1415
#include "src/__support/FPUtil/FEnvImpl.h"
1516
#include "src/__support/FPUtil/FPBits.h"
1617
#include "src/__support/FPUtil/fpbits_str.h"
@@ -128,6 +129,14 @@ template <typename T, TestCond Condition> class CFPMatcher : public Matcher<T> {
128129
return matchComplex<double>();
129130
else if (cpp::is_complex_type_same<T, _Complex long double>())
130131
return matchComplex<long double>();
132+
#ifdef LIBC_TYPES_HAS_CFLOAT16
133+
else if (cpp::is_complex_type_same<T, cfloat16>)
134+
return matchComplex<float16>();
135+
#endif
136+
#ifdef LIBC_TYPES_HAS_CFLOAT128
137+
else if (cpp::is_complex_type_same<T, cfloat128>)
138+
return matchComplex<float128>();
139+
#endif
131140
}
132141

133142
void explainError() override {
@@ -137,6 +146,14 @@ template <typename T, TestCond Condition> class CFPMatcher : public Matcher<T> {
137146
return explainErrorComplex<double>();
138147
else if (cpp::is_complex_type_same<T, _Complex long double>())
139148
return explainErrorComplex<long double>();
149+
#ifdef LIBC_TYPES_HAS_CFLOAT16
150+
else if (cpp::is_complex_type_same<T, cfloat16>)
151+
return explainErrorComplex<float16>();
152+
#endif
153+
#ifdef LIBC_TYPES_HAS_CFLOAT128
154+
else if (cpp::is_complex_type_same<T, cfloat128>)
155+
return explainErrorComplex<float128>();
156+
#endif
140157
}
141158
};
142159

0 commit comments

Comments
 (0)