Skip to content

Commit 78579b9

Browse files
authored
[libc] Implement CMPLX related macros (#156344)
1 parent bbde9c1 commit 78579b9

File tree

9 files changed

+134
-38
lines changed

9 files changed

+134
-38
lines changed

libc/docs/headers/complex.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Macros
1010
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
1111
| <Func> | <Func_f> (float) | <Func> (double) | <Func_l> (long double) | <Func_f16> (float16) | <Func_f128> (float128) | C23 Definition Section | C23 Error Handling Section |
1212
+===========+==================+=================+========================+======================+========================+========================+============================+
13-
| CMPLX | | | | | | 7.3.9.3 | N/A |
13+
| CMPLX | |check| | |check| | |check| | |check| | |check| | 7.3.9.3 | N/A |
1414
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
1515

1616
Functions

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,25 @@ add_macro_header(
6161
fcntl-macros.h
6262
)
6363

64+
add_macro_header(
65+
cfloat128_macros
66+
HDR
67+
cfloat128-macros.h
68+
)
69+
70+
add_macro_header(
71+
cfloat16_macros
72+
HDR
73+
cfloat16-macros.h
74+
)
75+
6476
add_macro_header(
6577
complex_macros
6678
HDR
6779
complex-macros.h
80+
DEPENDS
81+
.cfloat128_macros
82+
.cfloat16_macros
6883
)
6984

7085
add_macro_header(
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//===-- Detection of _Complex _Float128 compiler builtin 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_MACROS_CFLOAT128_MACROS_H
10+
#define LLVM_LIBC_MACROS_CFLOAT128_MACROS_H
11+
12+
#include "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, for C and in GCC 13 or later, for C++. For
16+
// clang, the complex variant of `__float128` is defined instead, and only on
17+
// x86-64 targets for clang 11 or later.
18+
//
19+
// TODO: Update the complex variant of C23 `_Float128` type detection again when
20+
// clang supports it.
21+
#ifdef __clang__
22+
#if (__clang_major__ >= 11) && \
23+
(defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__))
24+
// Use _Complex __float128 type. clang uses __SIZEOF_FLOAT128__ or __FLOAT128__
25+
// macro to notify the availability of __float128 type:
26+
// https://reviews.llvm.org/D15120
27+
#define LIBC_TYPES_HAS_CFLOAT128
28+
#endif
29+
#elif defined(__GNUC__)
30+
#if (defined(__STDC_IEC_60559_COMPLEX__) || defined(__SIZEOF_FLOAT128__)) && \
31+
(__GNUC__ >= 13 || (!defined(__cplusplus)))
32+
#define LIBC_TYPES_HAS_CFLOAT128
33+
#endif
34+
#endif
35+
36+
#if !defined(LIBC_TYPES_HAS_CFLOAT128) && (LDBL_MANT_DIG == 113)
37+
#define LIBC_TYPES_HAS_CFLOAT128
38+
#define LIBC_TYPES_CFLOAT128_IS_COMPLEX_LONG_DOUBLE
39+
#endif
40+
41+
#endif // LLVM_LIBC_MACROS_CFLOAT128_MACROS_H
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Detection of _Complex _Float16 compiler builtin 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_MACROS_CFLOAT16_MACROS_H
10+
#define LLVM_LIBC_MACROS_CFLOAT16_MACROS_H
11+
12+
#if defined(__FLT16_MANT_DIG__) && \
13+
(!defined(__GNUC__) || __GNUC__ >= 13 || \
14+
(defined(__clang__) && __clang_major__ >= 14)) && \
15+
!defined(__arm__) && !defined(_M_ARM) && !defined(__riscv) && \
16+
!defined(_WIN32)
17+
#define LIBC_TYPES_HAS_CFLOAT16
18+
#endif
19+
20+
#endif // LLVM_LIBC_MACROS_CFLOAT16_MACROS_H

libc/include/llvm-libc-macros/complex-macros.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
#ifndef __LLVM_LIBC_MACROS_COMPLEX_MACROS_H
1010
#define __LLVM_LIBC_MACROS_COMPLEX_MACROS_H
1111

12+
#include "cfloat128-macros.h"
13+
#include "cfloat16-macros.h"
14+
1215
#ifndef __STDC_NO_COMPLEX__
1316

1417
#define __STDC_VERSION_COMPLEX_H__ 202311L
@@ -19,6 +22,23 @@
1922

2023
// TODO: Add imaginary macros once GCC or Clang support _Imaginary builtin-type.
2124

25+
#define CMPLX(x, y) __builtin_complex((double)(x), (double)(y))
26+
#define CMPLXF(x, y) __builtin_complex((float)(x), (float)(y))
27+
#define CMPLXL(x, y) __builtin_complex((long double)(x), (long double)(y))
28+
29+
#ifdef LIBC_TYPES_HAS_CFLOAT16
30+
#if !defined(__clang__) || (__clang_major__ >= 22 && __clang_minor__ > 0)
31+
#define CMPLXF16(x, y) __builtin_complex((_Float16)(x), (_Float16)(y))
32+
#else
33+
#define CMPLXF16(x, y) \
34+
((complex _Float16)(__builtin_complex((float)(x), (float)(y))))
2235
#endif
36+
#endif // LIBC_TYPES_HAS_CFLOAT16
37+
38+
#ifdef LIBC_TYPES_HAS_CFLOAT128
39+
#define CMPLXF128(x, y) __builtin_complex((float128)(x), (float128)(y))
40+
#endif // LIBC_TYPES_HAS_CFLOAT128
41+
42+
#endif // __STDC_NO_COMPLEX__
2343

2444
#endif // __LLVM_LIBC_MACROS_COMPLEX_MACROS_H

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,15 @@ add_header(
150150
HDR
151151
cfloat128.h
152152
DEPENDS
153-
libc.include.llvm-libc-macros.float_macros
153+
libc.include.llvm-libc-macros.cfloat128_macros
154+
)
155+
add_header(
156+
cfloat16
157+
HDR
158+
cfloat16.h
159+
DEPENDS
160+
libc.include.llvm-libc-macros.cfloat16_macros
154161
)
155-
add_header(cfloat16 HDR cfloat16.h)
156162
add_header(fsblkcnt_t HDR fsblkcnt_t.h)
157163
add_header(fsfilcnt_t HDR fsfilcnt_t.h)
158164
add_header(

libc/include/llvm-libc-types/cfloat128.h

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,14 @@
99
#ifndef LLVM_LIBC_TYPES_CFLOAT128_H
1010
#define LLVM_LIBC_TYPES_CFLOAT128_H
1111

12-
#include "../llvm-libc-macros/float-macros.h" // LDBL_MANT_DIG
12+
#include "../llvm-libc-macros/cfloat128-macros.h"
1313

14-
// Currently, the complex variant of C23 `_Float128` type is only defined as a
15-
// built-in type in GCC 7 or later, for C and in GCC 13 or later, for C++. For
16-
// clang, the complex variant of `__float128` is defined instead, and only on
17-
// x86-64 targets for clang 11 or later.
18-
//
19-
// TODO: Update the complex variant of C23 `_Float128` type detection again when
20-
// clang supports it.
21-
#ifdef __clang__
22-
#if (__clang_major__ >= 11) && \
23-
(defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__))
24-
// Use _Complex __float128 type. clang uses __SIZEOF_FLOAT128__ or __FLOAT128__
25-
// macro to notify the availability of __float128 type:
26-
// https://reviews.llvm.org/D15120
27-
#define LIBC_TYPES_HAS_CFLOAT128
14+
#ifdef LIBC_TYPES_HAS_CFLOAT128
15+
#ifndef LIBC_TYPES_CFLOAT128_IS_COMPLEX_LONG_DOUBLE
2816
typedef _Complex __float128 cfloat128;
29-
#endif
30-
#elif defined(__GNUC__)
31-
#if (defined(__STDC_IEC_60559_COMPLEX__) || defined(__SIZEOF_FLOAT128__)) && \
32-
(__GNUC__ >= 13 || (!defined(__cplusplus)))
33-
#define LIBC_TYPES_HAS_CFLOAT128
34-
typedef _Complex _Float128 cfloat128;
35-
#endif
36-
#endif
37-
38-
#if !defined(LIBC_TYPES_HAS_CFLOAT128) && (LDBL_MANT_DIG == 113)
39-
#define LIBC_TYPES_HAS_CFLOAT128
40-
#define LIBC_TYPES_CFLOAT128_IS_COMPLEX_LONG_DOUBLE
17+
#else
4118
typedef _Complex long double cfloat128;
42-
#endif
19+
#endif // LIBC_TYPES_CFLOAT128_IS_COMPLEX_LONG_DOUBLE
20+
#endif // LIBC_TYPES_HAS_CFLOAT128
4321

4422
#endif // LLVM_LIBC_TYPES_CFLOAT128_H

libc/include/llvm-libc-types/cfloat16.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,10 @@
99
#ifndef LLVM_LIBC_TYPES_CFLOAT16_H
1010
#define LLVM_LIBC_TYPES_CFLOAT16_H
1111

12-
#if defined(__FLT16_MANT_DIG__) && \
13-
(!defined(__GNUC__) || __GNUC__ >= 13 || \
14-
(defined(__clang__) && __clang_major__ >= 14)) && \
15-
!defined(__arm__) && !defined(_M_ARM) && !defined(__riscv) && \
16-
!defined(_WIN32)
17-
#define LIBC_TYPES_HAS_CFLOAT16
12+
#include "../llvm-libc-macros/cfloat16-macros.h"
13+
14+
#ifdef LIBC_TYPES_HAS_CFLOAT16
1815
typedef _Complex _Float16 cfloat16;
19-
#endif
16+
#endif // LIBC_TYPES_HAS_CFLOAT16
2017

2118
#endif // LLVM_LIBC_TYPES_CFLOAT16_H

libc/test/include/complex_test.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,22 @@ TEST(LlvmLibcComplexTest, VersionMacro) {
1717
TEST(LlvmLibcComplexTest, IMacro) { EXPECT_CFP_EQ(1.0fi, I); }
1818

1919
TEST(LlvmLibcComplexTest, _Complex_IMacro) { EXPECT_CFP_EQ(1.0fi, _Complex_I); }
20+
21+
TEST(LlvmLibcComplexTest, CMPLXMacro) {
22+
EXPECT_CFP_EQ(CMPLX(0, 1.0), I);
23+
EXPECT_CFP_EQ(CMPLX(1.0, 0), 1.0);
24+
EXPECT_CFP_EQ(CMPLXF(0, 1.0f), I);
25+
EXPECT_CFP_EQ(CMPLXF(1.0f, 0), 1.0f);
26+
EXPECT_CFP_EQ(CMPLXL(0, 1.0l), I);
27+
EXPECT_CFP_EQ(CMPLXL(1.0l, 0), 1.0l);
28+
29+
#ifdef LIBC_TYPES_HAS_CFLOAT16
30+
EXPECT_CFP_EQ(CMPLXF16(0, 1.0), I);
31+
EXPECT_CFP_EQ(CMPLXF16(1.0, 0), 1.0);
32+
#endif // LIBC_TYPES_HAS_CFLOAT16
33+
34+
#ifdef LIBC_TYPES_HAS_CFLOAT128
35+
EXPECT_CFP_EQ(CMPLXF128(0, 1.0), I);
36+
EXPECT_CFP_EQ(CMPLXF128(1.0, 0), 1.0);
37+
#endif // LIBC_TYPES_HAS_CFLOAT128
38+
}

0 commit comments

Comments
 (0)