Skip to content

Commit

Permalink
[libc][math][c23] add c23 floating point fmaximum and fminimum functi…
Browse files Browse the repository at this point in the history
…ons. (#86016)

Fixes #85496.

---------

Co-authored-by: Job Hernandez <h93@protonmail.com>
  • Loading branch information
Jobhdez and Job Hernandez committed Mar 25, 2024
1 parent 4e6745c commit 3e3f0c3
Show file tree
Hide file tree
Showing 114 changed files with 3,547 additions and 0 deletions.
32 changes: 32 additions & 0 deletions libc/config/linux/aarch64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,30 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.fmin
libc.src.math.fminf
libc.src.math.fminl
libc.src.math.fmaximum
libc.src.math.fmaximumf
libc.src.math.fmaximuml
libc.src.math.fmaximum_num
libc.src.math.fmaximum_numf
libc.src.math.fmaximum_numl
libc.src.math.fmaximum_mag
libc.src.math.fmaximum_magf
libc.src.math.fmaximum_magl
libc.src.math.fmaximum_mag_num
libc.src.math.fmaximum_mag_numf
libc.src.math.fmaximum_mag_numl
libc.src.math.fminimum
libc.src.math.fminimumf
libc.src.math.fminimuml
libc.src.math.fminimum_num
libc.src.math.fminimum_numf
libc.src.math.fminimum_numl
libc.src.math.fminimum_mag
libc.src.math.fminimum_magf
libc.src.math.fminimum_magl
libc.src.math.fminimum_mag_num
libc.src.math.fminimum_mag_numf
libc.src.math.fminimum_mag_numl
libc.src.math.fmod
libc.src.math.fmodf
libc.src.math.fmodl
Expand Down Expand Up @@ -466,6 +490,14 @@ if(LIBC_TYPES_HAS_FLOAT128)
libc.src.math.floorf128
libc.src.math.fmaxf128
libc.src.math.fminf128
libc.src.math.fmaximumf128
libc.src.math.fmaximum_numf128
libc.src.math.fmaximum_magf128
libc.src.math.fmaximum_mag_numf128
libc.src.math.fminimumf128
libc.src.math.fminimum_numf128
libc.src.math.fminimum_magf128
libc.src.math.fminimum_mag_numf128
libc.src.math.fmodf128
libc.src.math.frexpf128
libc.src.math.ilogbf128
Expand Down
24 changes: 24 additions & 0 deletions libc/config/linux/arm/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,30 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.fmin
libc.src.math.fminf
libc.src.math.fminl
libc.src.math.fmaximum
libc.src.math.fmaximumf
libc.src.math.fmaximuml
libc.src.math.fmaximum_num
libc.src.math.fmaximum_numf
libc.src.math.fmaximum_numl
libc.src.math.fmaximum_mag
libc.src.math.fmaximum_magf
libc.src.math.fmaximum_magl
libc.src.math.fmaximum_mag_num
libc.src.math.fmaximum_mag_numf
libc.src.math.fmaximum_mag_numl
libc.src.math.fminimum
libc.src.math.fminimumf
libc.src.math.fminimuml
libc.src.math.fminimum_num
libc.src.math.fminimum_numf
libc.src.math.fminimum_numl
libc.src.math.fminimum_mag
libc.src.math.fminimum_magf
libc.src.math.fminimum_magl
libc.src.math.fminimum_mag_num
libc.src.math.fminimum_mag_numf
libc.src.math.fminimum_mag_numl
libc.src.math.fmod
libc.src.math.fmodf
libc.src.math.frexp
Expand Down
32 changes: 32 additions & 0 deletions libc/config/linux/riscv/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,30 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.fmax
libc.src.math.fmaxf
libc.src.math.fmaxl
libc.src.math.fmaximum
libc.src.math.fmaximumf
libc.src.math.fmaximuml
libc.src.math.fmaximum_num
libc.src.math.fmaximum_numf
libc.src.math.fmaximum_numl
libc.src.math.fmaximum_mag
libc.src.math.fmaximum_magf
libc.src.math.fmaximum_magl
libc.src.math.fmaximum_mag_num
libc.src.math.fmaximum_mag_numf
libc.src.math.fmaximum_mag_numl
libc.src.math.fminimum
libc.src.math.fminimumf
libc.src.math.fminimuml
libc.src.math.fminimum_num
libc.src.math.fminimum_numf
libc.src.math.fminimum_numl
libc.src.math.fminimum_mag
libc.src.math.fminimum_magf
libc.src.math.fminimum_magl
libc.src.math.fminimum_mag_num
libc.src.math.fminimum_mag_numf
libc.src.math.fminimum_mag_numl
libc.src.math.fmod
libc.src.math.fmodf
libc.src.math.fmodl
Expand Down Expand Up @@ -474,6 +498,14 @@ if(LIBC_TYPES_HAS_FLOAT128)
libc.src.math.floorf128
libc.src.math.fmaxf128
libc.src.math.fminf128
libc.src.math.fmaximumf128
libc.src.math.fmaximum_numf128
libc.src.math.fmaximum_magf128
libc.src.math.fmaximum_mag_numf128
libc.src.math.fminimumf128
libc.src.math.fminimum_numf128
libc.src.math.fminimum_magf128
libc.src.math.fminimum_mag_numf128
libc.src.math.fmodf128
libc.src.math.frexpf128
libc.src.math.ilogbf128
Expand Down
32 changes: 32 additions & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,30 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.fmax
libc.src.math.fmaxf
libc.src.math.fmaxl
libc.src.math.fmaximum
libc.src.math.fmaximumf
libc.src.math.fmaximuml
libc.src.math.fmaximum_num
libc.src.math.fmaximum_numf
libc.src.math.fmaximum_numl
libc.src.math.fmaximum_mag
libc.src.math.fmaximum_magf
libc.src.math.fmaximum_magl
libc.src.math.fmaximum_mag_num
libc.src.math.fmaximum_mag_numf
libc.src.math.fmaximum_mag_numl
libc.src.math.fminimum
libc.src.math.fminimumf
libc.src.math.fminimuml
libc.src.math.fminimum_num
libc.src.math.fminimum_numf
libc.src.math.fminimum_numl
libc.src.math.fminimum_mag
libc.src.math.fminimum_magf
libc.src.math.fminimum_magl
libc.src.math.fminimum_mag_num
libc.src.math.fminimum_mag_numf
libc.src.math.fminimum_mag_numl
libc.src.math.fmod
libc.src.math.fmodf
libc.src.math.fmodl
Expand Down Expand Up @@ -499,6 +523,14 @@ if(LIBC_TYPES_HAS_FLOAT128)
libc.src.math.floorf128
libc.src.math.fmaxf128
libc.src.math.fminf128
libc.src.math.fmaximumf128
libc.src.math.fmaximum_numf128
libc.src.math.fmaximum_magf128
libc.src.math.fmaximum_mag_numf128
libc.src.math.fminimumf128
libc.src.math.fminimum_numf128
libc.src.math.fminimum_magf128
libc.src.math.fminimum_mag_numf128
libc.src.math.fmodf128
libc.src.math.frexpf128
libc.src.math.fromfpf128
Expand Down
24 changes: 24 additions & 0 deletions libc/config/windows/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,30 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.fmax
libc.src.math.fmaxf
libc.src.math.fmaxl
libc.src.math.fmaximum
libc.src.math.fmaximumf
libc.src.math.fmaximuml
libc.src.math.fmaximum_num
libc.src.math.fmaximum_numf
libc.src.math.fmaximum_numl
libc.src.math.fmaximum_mag
libc.src.math.fmaximum_magf
libc.src.math.fmaximum_magl
libc.src.math.fmaximum_mag_num
libc.src.math.fmaximum_mag_numf
libc.src.math.fmaximum_mag_numl
libc.src.math.fminimum
libc.src.math.fminimumf
libc.src.math.fminimuml
libc.src.math.fminimum_num
libc.src.math.fminimum_numf
libc.src.math.fminimum_numl
libc.src.math.fminimum_mag
libc.src.math.fminimum_magf
libc.src.math.fminimum_magl
libc.src.math.fminimum_mag_num
libc.src.math.fminimum_mag_numf
libc.src.math.fminimum_mag_numl
libc.src.math.fmod
libc.src.math.fmodf
libc.src.math.fmodl
Expand Down
40 changes: 40 additions & 0 deletions libc/spec/stdc.td
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,46 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"fmaxf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
FunctionSpec<"fmaxl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"fmaxf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"fmaximum", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"fmaximumf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
FunctionSpec<"fmaximuml", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"fmaximumf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"fmaximum_num", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"fmaximum_numf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
FunctionSpec<"fmaximum_numl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"fmaximum_numf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"fmaximum_mag", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"fmaximum_magf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
FunctionSpec<"fmaximum_magl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"fmaximum_magf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"fmaximum_mag_num", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"fmaximum_mag_numf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
FunctionSpec<"fmaximum_mag_numl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"fmaximum_mag_numf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"fminimum", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"fminimumf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
FunctionSpec<"fminimuml", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"fminimumf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"fminimum_num", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"fminimum_numf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
FunctionSpec<"fmaximum_numl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"fminimum_numf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"fminimum_mag", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"fminimum_magf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
FunctionSpec<"fminimum_magl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"fminimum_magf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"fminimum_mag_num", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"fminimum_mag_numf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
FunctionSpec<"fminimum_mag_numl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>]>,
GuardedFunctionSpec<"fminimum_mag_numf128", RetValSpec<Float128Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT128">,

FunctionSpec<"fma", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"fmaf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>, ArgSpec<FloatType>]>,
Expand Down
105 changes: 105 additions & 0 deletions libc/src/__support/FPUtil/BasicOperations.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "FPBits.h"

#include "FEnvImpl.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/common.h"

Expand Down Expand Up @@ -58,6 +59,110 @@ LIBC_INLINE T fmax(T x, T y) {
}
}

template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T fmaximum(T x, T y) {
FPBits<T> bitx(x), bity(y);

if (bitx.is_nan())
return x;
if (bity.is_nan())
return y;
if (bitx.sign() != bity.sign())
return (bitx.is_neg() ? y : x);
return x > y ? x : y;
}

template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T fminimum(T x, T y) {
const FPBits<T> bitx(x), bity(y);

if (bitx.is_nan())
return x;
if (bity.is_nan())
return y;
if (bitx.sign() != bity.sign())
return (bitx.is_neg()) ? x : y;
return x < y ? x : y;
}

template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T fmaximum_num(T x, T y) {
FPBits<T> bitx(x), bity(y);
if (bitx.is_signaling_nan() || bity.is_signaling_nan()) {
fputil::raise_except_if_required(FE_INVALID);
if (bitx.is_nan() && bity.is_nan())
return FPBits<T>::quiet_nan().get_val();
}
if (bitx.is_nan())
return y;
if (bity.is_nan())
return x;
if (bitx.sign() != bity.sign())
return (bitx.is_neg() ? y : x);
return x > y ? x : y;
}

template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T fminimum_num(T x, T y) {
FPBits<T> bitx(x), bity(y);
if (bitx.is_signaling_nan() || bity.is_signaling_nan()) {
fputil::raise_except_if_required(FE_INVALID);
if (bitx.is_nan() && bity.is_nan())
return FPBits<T>::quiet_nan().get_val();
}
if (bitx.is_nan())
return y;
if (bity.is_nan())
return x;
if (bitx.sign() != bity.sign())
return (bitx.is_neg() ? x : y);
return x < y ? x : y;
}

template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T fmaximum_mag(T x, T y) {
FPBits<T> bitx(x), bity(y);

if (abs(x) > abs(y))
return x;
if (abs(y) > abs(x))
return y;
return fmaximum(x, y);
}

template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T fminimum_mag(T x, T y) {
FPBits<T> bitx(x), bity(y);

if (abs(x) < abs(y))
return x;
if (abs(y) < abs(x))
return y;
return fminimum(x, y);
}

template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T fmaximum_mag_num(T x, T y) {
FPBits<T> bitx(x), bity(y);

if (abs(x) > abs(y))
return x;
if (abs(y) > abs(x))
return y;
return fmaximum_num(x, y);
}

template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T fminimum_mag_num(T x, T y) {
FPBits<T> bitx(x), bity(y);

if (abs(x) < abs(y))
return x;
if (abs(y) < abs(x))
return y;
return fminimum_num(x, y);
}

template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T fdim(T x, T y) {
FPBits<T> bitx(x), bity(y);
Expand Down

0 comments on commit 3e3f0c3

Please sign in to comment.