Skip to content

Commit 4b5c7e4

Browse files
overmightyyuxuanchen1997
authored andcommitted
[libc][math][c23] Add {f,d}mul{l,f128} and f16mul{,f,l,f128} C23 math functions (#98972)
Summary: Part of #93566. Fixes #94833. Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60250946
1 parent e1cce9c commit 4b5c7e4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1227
-364
lines changed

libc/config/linux/aarch64/entrypoints.txt

+4
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ set(TARGET_LIBM_ENTRYPOINTS
357357
libc.src.math.cosf
358358
libc.src.math.coshf
359359
libc.src.math.cospif
360+
libc.src.math.dmull
360361
libc.src.math.erff
361362
libc.src.math.exp
362363
libc.src.math.exp10
@@ -411,6 +412,7 @@ set(TARGET_LIBM_ENTRYPOINTS
411412
libc.src.math.fmodf
412413
libc.src.math.fmodl
413414
libc.src.math.fmul
415+
libc.src.math.fmull
414416
libc.src.math.frexp
415417
libc.src.math.frexpf
416418
libc.src.math.frexpl
@@ -531,6 +533,8 @@ if(LIBC_TYPES_HAS_FLOAT16)
531533
libc.src.math.f16div
532534
libc.src.math.f16divf
533535
libc.src.math.f16fmaf
536+
libc.src.math.f16mul
537+
libc.src.math.f16mulf
534538
libc.src.math.f16sqrt
535539
libc.src.math.f16sqrtf
536540
libc.src.math.f16sub

libc/config/linux/x86_64/entrypoints.txt

+8
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ set(TARGET_LIBM_ENTRYPOINTS
382382
libc.src.math.cosf
383383
libc.src.math.coshf
384384
libc.src.math.cospif
385+
libc.src.math.dmull
385386
libc.src.math.erff
386387
libc.src.math.exp
387388
libc.src.math.exp10
@@ -437,6 +438,7 @@ set(TARGET_LIBM_ENTRYPOINTS
437438
libc.src.math.fmodf
438439
libc.src.math.fmodl
439440
libc.src.math.fmul
441+
libc.src.math.fmull
440442
libc.src.math.frexp
441443
libc.src.math.frexpf
442444
libc.src.math.frexpl
@@ -561,6 +563,9 @@ if(LIBC_TYPES_HAS_FLOAT16)
561563
libc.src.math.f16fma
562564
libc.src.math.f16fmaf
563565
libc.src.math.f16fmal
566+
libc.src.math.f16mul
567+
libc.src.math.f16mulf
568+
libc.src.math.f16mull
564569
libc.src.math.f16sqrt
565570
libc.src.math.f16sqrtf
566571
libc.src.math.f16sqrtl
@@ -622,6 +627,7 @@ if(LIBC_TYPES_HAS_FLOAT16)
622627
libc.src.math.f16addf128
623628
libc.src.math.f16divf128
624629
libc.src.math.f16fmaf128
630+
libc.src.math.f16mulf128
625631
libc.src.math.f16sqrtf128
626632
libc.src.math.f16subf128
627633
)
@@ -634,6 +640,7 @@ if(LIBC_TYPES_HAS_FLOAT128)
634640
libc.src.math.canonicalizef128
635641
libc.src.math.ceilf128
636642
libc.src.math.copysignf128
643+
libc.src.math.dmulf128
637644
libc.src.math.fabsf128
638645
libc.src.math.fdimf128
639646
libc.src.math.floorf128
@@ -648,6 +655,7 @@ if(LIBC_TYPES_HAS_FLOAT128)
648655
libc.src.math.fminimum_numf128
649656
libc.src.math.fminimumf128
650657
libc.src.math.fmodf128
658+
libc.src.math.fmulf128
651659
libc.src.math.frexpf128
652660
libc.src.math.fromfpf128
653661
libc.src.math.fromfpxf128

libc/docs/math/index.rst

+4-2
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ Basic Operations
120120
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
121121
| dfma | N/A | N/A | | N/A | | 7.12.14.5 | F.10.11 |
122122
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
123-
| dmul | N/A | N/A | | N/A | | 7.12.14.3 | F.10.11 |
123+
| dmul | N/A | N/A | |check| | N/A | |check|\* | 7.12.14.3 | F.10.11 |
124124
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
125125
| dsub | N/A | N/A | | N/A | | 7.12.14.2 | F.10.11 |
126126
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
@@ -130,6 +130,8 @@ Basic Operations
130130
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
131131
| f16fma | |check|\* | |check|\* | |check|\* | N/A | |check| | 7.12.14.5 | F.10.11 |
132132
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
133+
| f16mul | |check|\* | |check|\* | |check|\* | N/A | |check| | 7.12.14.5 | F.10.11 |
134+
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
133135
| f16sub | |check|\* | |check|\* | |check|\* | N/A | |check| | 7.12.14.2 | F.10.11 |
134136
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
135137
| fabs | |check| | |check| | |check| | |check| | |check| | 7.12.7.3 | F.10.4.3 |
@@ -166,7 +168,7 @@ Basic Operations
166168
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
167169
| fmod | |check| | |check| | |check| | |check| | |check| | 7.12.10.1 | F.10.7.1 |
168170
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
169-
| fmul | N/A | |check| | | N/A | | 7.12.14.3 | F.10.11 |
171+
| fmul | N/A | |check| | |check| | N/A | |check|\* | 7.12.14.3 | F.10.11 |
170172
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
171173
| frexp | |check| | |check| | |check| | |check| | |check| | 7.12.6.7 | F.10.3.7 |
172174
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+

libc/spec/llvm_libc_ext.td

+8
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ def LLVMLibcExt : StandardSpec<"llvm_libc_ext"> {
6565
GuardedFunctionSpec<"f16subf", RetValSpec<Float16Type>, [ArgSpec<FloatType>, ArgSpec<FloatType>], "LIBC_TYPES_HAS_FLOAT16">,
6666
GuardedFunctionSpec<"f16subl", RetValSpec<Float16Type>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>], "LIBC_TYPES_HAS_FLOAT16">,
6767

68+
GuardedFunctionSpec<"fmulf128", RetValSpec<FloatType>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,
69+
70+
GuardedFunctionSpec<"dmulf128", RetValSpec<DoubleType>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,
71+
72+
GuardedFunctionSpec<"f16mul", RetValSpec<Float16Type>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>], "LIBC_TYPES_HAS_FLOAT16">,
73+
GuardedFunctionSpec<"f16mulf", RetValSpec<Float16Type>, [ArgSpec<FloatType>, ArgSpec<FloatType>], "LIBC_TYPES_HAS_FLOAT16">,
74+
GuardedFunctionSpec<"f16mull", RetValSpec<Float16Type>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>], "LIBC_TYPES_HAS_FLOAT16">,
75+
6876
GuardedFunctionSpec<"f16div", RetValSpec<Float16Type>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>], "LIBC_TYPES_HAS_FLOAT16">,
6977
GuardedFunctionSpec<"f16divf", RetValSpec<Float16Type>, [ArgSpec<FloatType>, ArgSpec<FloatType>], "LIBC_TYPES_HAS_FLOAT16">,
7078
GuardedFunctionSpec<"f16divl", RetValSpec<Float16Type>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>], "LIBC_TYPES_HAS_FLOAT16">,

libc/spec/stdc.td

+7-2
Original file line numberDiff line numberDiff line change
@@ -475,8 +475,6 @@ def StdC : StandardSpec<"stdc"> {
475475
GuardedFunctionSpec<"fminimum_mag_numf16", RetValSpec<Float16Type>, [ArgSpec<Float16Type>, ArgSpec<Float16Type>], "LIBC_TYPES_HAS_FLOAT16">,
476476
GuardedFunctionSpec<"fminimum_mag_numf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,
477477

478-
FunctionSpec<"fmul", RetValSpec<FloatType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
479-
480478
FunctionSpec<"fma", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
481479
FunctionSpec<"fmaf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>, ArgSpec<FloatType>]>,
482480

@@ -733,6 +731,13 @@ def StdC : StandardSpec<"stdc"> {
733731

734732
GuardedFunctionSpec<"f16subf128", RetValSpec<Float16Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT16_AND_FLOAT128">,
735733

734+
FunctionSpec<"fmul", RetValSpec<FloatType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
735+
FunctionSpec<"fmull", RetValSpec<FloatType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
736+
737+
FunctionSpec<"dmull", RetValSpec<DoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
738+
739+
GuardedFunctionSpec<"f16mulf128", RetValSpec<Float16Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT16_AND_FLOAT128">,
740+
736741
GuardedFunctionSpec<"f16divf128", RetValSpec<Float16Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT16_AND_FLOAT128">,
737742

738743
GuardedFunctionSpec<"f16sqrtf128", RetValSpec<Float16Type>, [ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT16_AND_FLOAT128">,

libc/src/__support/FPUtil/generic/CMakeLists.txt

+17
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,20 @@ add_header_library(
8484
libc.src.__support.macros.attributes
8585
libc.src.__support.macros.optimization
8686
)
87+
88+
add_header_library(
89+
mul
90+
HDRS
91+
mul.h
92+
DEPENDS
93+
libc.hdr.errno_macros
94+
libc.hdr.fenv_macros
95+
libc.src.__support.CPP.bit
96+
libc.src.__support.CPP.type_traits
97+
libc.src.__support.FPUtil.basic_operations
98+
libc.src.__support.FPUtil.fenv_impl
99+
libc.src.__support.FPUtil.fp_bits
100+
libc.src.__support.FPUtil.dyadic_float
101+
libc.src.__support.macros.attributes
102+
libc.src.__support.macros.optimization
103+
)
+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
//===-- Multiplication of IEEE 754 floating-point numbers -------*- 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+
9+
#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_GENERIC_MUL_H
10+
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_GENERIC_MUL_H
11+
12+
#include "hdr/errno_macros.h"
13+
#include "hdr/fenv_macros.h"
14+
#include "src/__support/CPP/bit.h"
15+
#include "src/__support/CPP/type_traits.h"
16+
#include "src/__support/FPUtil/BasicOperations.h"
17+
#include "src/__support/FPUtil/FEnvImpl.h"
18+
#include "src/__support/FPUtil/FPBits.h"
19+
#include "src/__support/FPUtil/dyadic_float.h"
20+
#include "src/__support/macros/attributes.h"
21+
#include "src/__support/macros/config.h"
22+
#include "src/__support/macros/optimization.h"
23+
24+
namespace LIBC_NAMESPACE_DECL {
25+
namespace fputil::generic {
26+
27+
template <typename OutType, typename InType>
28+
LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<OutType> &&
29+
cpp::is_floating_point_v<InType> &&
30+
sizeof(OutType) <= sizeof(InType),
31+
OutType>
32+
mul(InType x, InType y) {
33+
using OutFPBits = FPBits<OutType>;
34+
using OutStorageType = typename OutFPBits::StorageType;
35+
using InFPBits = FPBits<InType>;
36+
using InStorageType = typename InFPBits::StorageType;
37+
// The product of two p-digit numbers is a 2p-digit number.
38+
using DyadicFloat =
39+
DyadicFloat<cpp::bit_ceil(2 * static_cast<size_t>(InFPBits::SIG_LEN))>;
40+
41+
InFPBits x_bits(x);
42+
InFPBits y_bits(y);
43+
44+
Sign result_sign = x_bits.sign() == y_bits.sign() ? Sign::POS : Sign::NEG;
45+
46+
if (LIBC_UNLIKELY(x_bits.is_inf_or_nan() || y_bits.is_inf_or_nan() ||
47+
x_bits.is_zero() || y_bits.is_zero())) {
48+
if (x_bits.is_nan() || y_bits.is_nan()) {
49+
if (x_bits.is_signaling_nan() || y_bits.is_signaling_nan())
50+
raise_except_if_required(FE_INVALID);
51+
52+
if (x_bits.is_quiet_nan()) {
53+
InStorageType x_payload = static_cast<InStorageType>(getpayload(x));
54+
if ((x_payload & ~(OutFPBits::FRACTION_MASK >> 1)) == 0)
55+
return OutFPBits::quiet_nan(x_bits.sign(),
56+
static_cast<OutStorageType>(x_payload))
57+
.get_val();
58+
}
59+
60+
if (y_bits.is_quiet_nan()) {
61+
InStorageType y_payload = static_cast<InStorageType>(getpayload(y));
62+
if ((y_payload & ~(OutFPBits::FRACTION_MASK >> 1)) == 0)
63+
return OutFPBits::quiet_nan(y_bits.sign(),
64+
static_cast<OutStorageType>(y_payload))
65+
.get_val();
66+
}
67+
68+
return OutFPBits::quiet_nan().get_val();
69+
}
70+
71+
if (x_bits.is_inf()) {
72+
if (y_bits.is_zero()) {
73+
set_errno_if_required(EDOM);
74+
raise_except_if_required(FE_INVALID);
75+
return OutFPBits::quiet_nan().get_val();
76+
}
77+
78+
return OutFPBits::inf(result_sign).get_val();
79+
}
80+
81+
if (y_bits.is_inf()) {
82+
if (x_bits.is_zero()) {
83+
set_errno_if_required(EDOM);
84+
raise_except_if_required(FE_INVALID);
85+
return OutFPBits::quiet_nan().get_val();
86+
}
87+
88+
return OutFPBits::inf(result_sign).get_val();
89+
}
90+
91+
// Now either x or y is zero, and the other one is finite.
92+
return OutFPBits::zero(result_sign).get_val();
93+
}
94+
95+
DyadicFloat xd(x);
96+
DyadicFloat yd(y);
97+
98+
DyadicFloat result = quick_mul(xd, yd);
99+
return result.template as<OutType, /*ShouldSignalExceptions=*/true>();
100+
}
101+
102+
} // namespace fputil::generic
103+
} // namespace LIBC_NAMESPACE_DECL
104+
105+
#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_GENERIC_MUL_H

libc/src/math/CMakeLists.txt

+10
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ add_math_entrypoint_object(cosh)
8686
add_math_entrypoint_object(coshf)
8787
add_math_entrypoint_object(cospif)
8888

89+
add_math_entrypoint_object(dmull)
90+
add_math_entrypoint_object(dmulf128)
91+
8992
add_math_entrypoint_object(erf)
9093
add_math_entrypoint_object(erff)
9194

@@ -118,6 +121,11 @@ add_math_entrypoint_object(f16fmaf)
118121
add_math_entrypoint_object(f16fmal)
119122
add_math_entrypoint_object(f16fmaf128)
120123

124+
add_math_entrypoint_object(f16mul)
125+
add_math_entrypoint_object(f16mulf)
126+
add_math_entrypoint_object(f16mull)
127+
add_math_entrypoint_object(f16mulf128)
128+
121129
add_math_entrypoint_object(f16sqrt)
122130
add_math_entrypoint_object(f16sqrtf)
123131
add_math_entrypoint_object(f16sqrtl)
@@ -210,6 +218,8 @@ add_math_entrypoint_object(fminimum_mag_numf16)
210218
add_math_entrypoint_object(fminimum_mag_numf128)
211219

212220
add_math_entrypoint_object(fmul)
221+
add_math_entrypoint_object(fmull)
222+
add_math_entrypoint_object(fmulf128)
213223

214224
add_math_entrypoint_object(fmod)
215225
add_math_entrypoint_object(fmodf)

libc/src/math/dmulf128.h

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Implementation header for dmulf128 ----------------------*- 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+
9+
#ifndef LLVM_LIBC_SRC_MATH_DMULF128_H
10+
#define LLVM_LIBC_SRC_MATH_DMULF128_H
11+
12+
#include "src/__support/macros/config.h"
13+
#include "src/__support/macros/properties/types.h"
14+
15+
namespace LIBC_NAMESPACE_DECL {
16+
17+
double dmulf128(float128 x, float128 y);
18+
19+
} // namespace LIBC_NAMESPACE_DECL
20+
21+
#endif // LLVM_LIBC_SRC_MATH_DMULF128_H

libc/src/math/dmull.h

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Implementation header for dmull -------------------------*- 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+
9+
#ifndef LLVM_LIBC_SRC_MATH_DMULL_H
10+
#define LLVM_LIBC_SRC_MATH_DMULL_H
11+
12+
#include "src/__support/macros/config.h"
13+
14+
namespace LIBC_NAMESPACE_DECL {
15+
16+
double dmull(long double x, long double y);
17+
18+
} // namespace LIBC_NAMESPACE_DECL
19+
20+
#endif // LLVM_LIBC_SRC_MATH_DMULL_H

libc/src/math/f16mul.h

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Implementation header for f16mul ------------------------*- 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+
9+
#ifndef LLVM_LIBC_SRC_MATH_F16MUL_H
10+
#define LLVM_LIBC_SRC_MATH_F16MUL_H
11+
12+
#include "src/__support/macros/config.h"
13+
#include "src/__support/macros/properties/types.h"
14+
15+
namespace LIBC_NAMESPACE_DECL {
16+
17+
float16 f16mul(double x, double y);
18+
19+
} // namespace LIBC_NAMESPACE_DECL
20+
21+
#endif // LLVM_LIBC_SRC_MATH_F16MUL_H

libc/src/math/f16mulf.h

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Implementation header for f16mulf -----------------------*- 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+
9+
#ifndef LLVM_LIBC_SRC_MATH_F16MULF_H
10+
#define LLVM_LIBC_SRC_MATH_F16MULF_H
11+
12+
#include "src/__support/macros/config.h"
13+
#include "src/__support/macros/properties/types.h"
14+
15+
namespace LIBC_NAMESPACE_DECL {
16+
17+
float16 f16mulf(float x, float y);
18+
19+
} // namespace LIBC_NAMESPACE_DECL
20+
21+
#endif // LLVM_LIBC_SRC_MATH_F16MULF_H

0 commit comments

Comments
 (0)