llvm-project
llvm-project copied to clipboard
[libc][math][c23] add c23 floating point fmaximum and fminimum functions.
Hello,
This PR addresses this issue https://github.com/llvm/llvm-project/issues/85496.
I have added fminimum and fmaximum functions.
I built it using
$ cmake ../llvm -G Ninja -DLLVM_ENABLE_PROJECTS="llvm;libc" -DLLVM_TARGETS_TO_BUILD="X86" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
$ ninja libc -j8
I ran the tests as follows:
ninja libc-math-smoke-tests
Please let me know of anything I need to change. I will be available.
Thanks.
@llvm/pr-subscribers-backend-amdgpu
@llvm/pr-subscribers-libc
Author: Job Henandez Lara (Jobhdez)
Changes
Hello,
I have added fminimum and fmaximum functions.
I built it using
$ cmake ../llvm -G Ninja -DLLVM_ENABLE_PROJECTS="llvm;libc" -DLLVM_TARGETS_TO_BUILD="X86" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
$ ninja libc -j8
I ran the tests as follows:
ninja libc-math-smoke-tests
Please let me know of anything I need to change. I will be available.
Thanks.
Patch is 161.81 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/86016.diff
141 Files Affected:
- (modified) libc/config/linux/aarch64/entrypoints.txt (+24)
- (modified) libc/config/linux/arm/entrypoints.txt (+24)
- (modified) libc/config/linux/riscv/entrypoints.txt (+24)
- (modified) libc/config/linux/x86_64/entrypoints.txt (+24)
- (modified) libc/config/windows/entrypoints.txt (+25-1)
- (modified) libc/spec/stdc.td (+40)
- (modified) libc/src/__support/FPUtil/BasicOperations.h (+124)
- (modified) libc/src/math/CMakeLists.txt (+40)
- (added) libc/src/math/amdgpu/fmaximum.cpp (+21)
- (added) libc/src/math/amdgpu/fmaximum_mag.cpp (+21)
- (added) libc/src/math/amdgpu/fmaximum_mag_num.cpp (+21)
- (added) libc/src/math/amdgpu/fmaximum_mag_numf.cpp (+21)
- (added) libc/src/math/amdgpu/fmaximum_mag_numl.cpp (+21)
- (added) libc/src/math/amdgpu/fmaximum_magf.cpp (+21)
- (added) libc/src/math/amdgpu/fmaximum_magl.cpp (+21)
- (added) libc/src/math/amdgpu/fmaximum_num.cpp (+21)
- (added) libc/src/math/amdgpu/fmaximum_numf.cpp (+21)
- (added) libc/src/math/amdgpu/fmaximum_numl.cpp (+21)
- (added) libc/src/math/amdgpu/fmaximumf.cpp (+19)
- (added) libc/src/math/amdgpu/fmaximuml.cpp (+19)
- (added) libc/src/math/amdgpu/fminimum.cpp (+21)
- (added) libc/src/math/amdgpu/fminimum_mag.cpp (+21)
- (added) libc/src/math/amdgpu/fminimum_mag_num.cpp (+21)
- (added) libc/src/math/amdgpu/fminimum_mag_numf.cpp (+21)
- (added) libc/src/math/amdgpu/fminimum_mag_numl.cpp (+21)
- (added) libc/src/math/amdgpu/fminimum_magf.cpp (+21)
- (added) libc/src/math/amdgpu/fminimum_magl.cpp (+21)
- (added) libc/src/math/amdgpu/fminimum_num.cpp (+21)
- (added) libc/src/math/amdgpu/fminimum_numf.cpp (+21)
- (added) libc/src/math/amdgpu/fminimum_numl.cpp (+21)
- (added) libc/src/math/amdgpu/fminimumf.cpp (+19)
- (added) libc/src/math/amdgpu/fminimuml.cpp (+19)
- (added) libc/src/math/fmaximum.h (+18)
- (added) libc/src/math/fmaximum_mag.h (+18)
- (added) libc/src/math/fmaximum_mag_num.h (+18)
- (added) libc/src/math/fmaximum_mag_numf.h (+18)
- (added) libc/src/math/fmaximum_mag_numf128.h (+20)
- (added) libc/src/math/fmaximum_mag_numl.h (+18)
- (added) libc/src/math/fmaximum_magf.h (+18)
- (added) libc/src/math/fmaximum_magf128.h (+20)
- (added) libc/src/math/fmaximum_magl.h (+18)
- (added) libc/src/math/fmaximum_num.h (+18)
- (added) libc/src/math/fmaximum_numf.h (+18)
- (added) libc/src/math/fmaximum_numf128.h (+20)
- (added) libc/src/math/fmaximum_numl.h (+18)
- (added) libc/src/math/fmaximumf.h (+18)
- (added) libc/src/math/fmaximumf128.h (+20)
- (added) libc/src/math/fmaximuml.h (+18)
- (added) libc/src/math/fminimum.h (+18)
- (added) libc/src/math/fminimum_mag.h (+18)
- (added) libc/src/math/fminimum_mag_num.h (+18)
- (added) libc/src/math/fminimum_mag_numf.h (+18)
- (added) libc/src/math/fminimum_mag_numf128.h (+20)
- (added) libc/src/math/fminimum_mag_numl.h (+18)
- (added) libc/src/math/fminimum_magf.h (+18)
- (added) libc/src/math/fminimum_magf128.h (+20)
- (added) libc/src/math/fminimum_magl.h (+18)
- (added) libc/src/math/fminimum_num.h (+18)
- (added) libc/src/math/fminimum_numf.h (+18)
- (added) libc/src/math/fminimum_numf128.h (+20)
- (added) libc/src/math/fminimum_numl.h (+18)
- (added) libc/src/math/fminimumf.h (+18)
- (added) libc/src/math/fminimumf128.h (+20)
- (added) libc/src/math/fminimuml.h (+18)
- (modified) libc/src/math/generic/CMakeLists.txt (+395)
- (added) libc/src/math/generic/fmaximum.cpp (+19)
- (added) libc/src/math/generic/fmaximum_mag.cpp (+19)
- (added) libc/src/math/generic/fmaximum_mag_num.cpp (+19)
- (added) libc/src/math/generic/fmaximum_mag_numf.cpp (+19)
- (added) libc/src/math/generic/fmaximum_mag_numf128.cpp (+19)
- (added) libc/src/math/generic/fmaximum_mag_numl.cpp (+20)
- (added) libc/src/math/generic/fmaximum_magf.cpp (+19)
- (added) libc/src/math/generic/fmaximum_magf128.cpp (+19)
- (added) libc/src/math/generic/fmaximum_magl.cpp (+20)
- (added) libc/src/math/generic/fmaximum_num.cpp (+19)
- (added) libc/src/math/generic/fmaximum_numf.cpp (+19)
- (added) libc/src/math/generic/fmaximum_numf128.cpp (+19)
- (added) libc/src/math/generic/fmaximum_numl.cpp (+20)
- (added) libc/src/math/generic/fmaximumf.cpp (+19)
- (added) libc/src/math/generic/fmaximumf128.cpp (+19)
- (added) libc/src/math/generic/fmaximuml.cpp (+20)
- (added) libc/src/math/generic/fminimum.cpp (+19)
- (added) libc/src/math/generic/fminimum_mag.cpp (+19)
- (added) libc/src/math/generic/fminimum_mag_num.cpp (+19)
- (added) libc/src/math/generic/fminimum_mag_numf.cpp (+19)
- (added) libc/src/math/generic/fminimum_mag_numf128.cpp (+19)
- (added) libc/src/math/generic/fminimum_mag_numl.cpp (+20)
- (added) libc/src/math/generic/fminimum_magf.cpp (+19)
- (added) libc/src/math/generic/fminimum_magf128.cpp (+19)
- (added) libc/src/math/generic/fminimum_magl.cpp (+20)
- (added) libc/src/math/generic/fminimum_num.cpp (+19)
- (added) libc/src/math/generic/fminimum_numf.cpp (+19)
- (added) libc/src/math/generic/fminimum_numf128.cpp (+19)
- (added) libc/src/math/generic/fminimum_numl.cpp (+20)
- (added) libc/src/math/generic/fminimumf.cpp (+19)
- (added) libc/src/math/generic/fminimumf128.cpp (+19)
- (added) libc/src/math/generic/fminimuml.cpp (+20)
- (added) libc/src/math/nvptx/fmaximum.cpp (+19)
- (added) libc/src/math/nvptx/fmaximumf.cpp (+21)
- (modified) libc/test/src/math/smoke/CMakeLists.txt (+418)
- (modified) libc/test/src/math/smoke/FMaxTest.h (+1-1)
- (added) libc/test/src/math/smoke/FMaximumMagNumTest.h (+88)
- (added) libc/test/src/math/smoke/FMaximumMagTest.h (+88)
- (added) libc/test/src/math/smoke/FMaximumNumTest.h (+87)
- (added) libc/test/src/math/smoke/FMaximumTest.h (+87)
- (added) libc/test/src/math/smoke/FMinimumMagNumTest.h (+88)
- (added) libc/test/src/math/smoke/FMinimumMagTest.h (+88)
- (added) libc/test/src/math/smoke/FMinimumNumTest.h (+87)
- (added) libc/test/src/math/smoke/FMinimumTest.h (+87)
- (added) libc/test/src/math/smoke/fmaximum_mag_num_test.cpp (+13)
- (added) libc/test/src/math/smoke/fmaximum_mag_numf128_test.cpp (+13)
- (added) libc/test/src/math/smoke/fmaximum_mag_numf_test.cpp (+13)
- (added) libc/test/src/math/smoke/fmaximum_mag_numl_test.cpp (+13)
- (added) libc/test/src/math/smoke/fmaximum_mag_test.cpp (+13)
- (added) libc/test/src/math/smoke/fmaximum_magf128_test.cpp (+13)
- (added) libc/test/src/math/smoke/fmaximum_magf_test.cpp (+13)
- (added) libc/test/src/math/smoke/fmaximum_magl_test.cpp (+13)
- (added) libc/test/src/math/smoke/fmaximum_num_test.cpp (+13)
- (added) libc/test/src/math/smoke/fmaximum_numf128_test.cpp (+13)
- (added) libc/test/src/math/smoke/fmaximum_numf_test.cpp (+13)
- (added) libc/test/src/math/smoke/fmaximum_numl_test.cpp (+13)
- (added) libc/test/src/math/smoke/fmaximum_test.cpp (+13)
- (added) libc/test/src/math/smoke/fmaximumf128_test.cpp (+13)
- (added) libc/test/src/math/smoke/fmaximumf_test.cpp (+13)
- (added) libc/test/src/math/smoke/fmaximuml_test.cpp (+13)
- (added) libc/test/src/math/smoke/fminimum_mag_num_test.cpp (+13)
- (added) libc/test/src/math/smoke/fminimum_mag_numf128.cpp (+13)
- (added) libc/test/src/math/smoke/fminimum_mag_numf_test.cpp (+13)
- (added) libc/test/src/math/smoke/fminimum_mag_numl_test.cpp (+13)
- (added) libc/test/src/math/smoke/fminimum_mag_test.cpp (+13)
- (added) libc/test/src/math/smoke/fminimum_magf128_test.cpp (+13)
- (added) libc/test/src/math/smoke/fminimum_magf_test.cpp (+13)
- (added) libc/test/src/math/smoke/fminimum_magl_test.cpp (+13)
- (added) libc/test/src/math/smoke/fminimum_num_test.cpp (+13)
- (added) libc/test/src/math/smoke/fminimum_numf128_test.cpp (+13)
- (added) libc/test/src/math/smoke/fminimum_numf_test.cpp (+13)
- (added) libc/test/src/math/smoke/fminimum_numl_test.cpp (+13)
- (added) libc/test/src/math/smoke/fminimum_test.cpp (+13)
- (added) libc/test/src/math/smoke/fminimumf128_test.cpp (+13)
- (added) libc/test/src/math/smoke/fminimumf_test.cpp (+13)
- (added) libc/test/src/math/smoke/fminimuml_test.cpp (+13)
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 43c9e81f17833e..56fb490104f67b 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -363,6 +363,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
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index bf1559b2f02369..70a3ed55a69a29 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -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
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 99ef84d3f73974..456baff250e101 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -371,6 +371,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
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 99182e7f92ac09..65f95a92a538ff 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -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
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index d6227a427afe2b..1a1d92b1f2afe7 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -1,4 +1,4 @@
-set(TARGET_LIBC_ENTRYPOINTS
+fset(TARGET_LIBC_ENTRYPOINTS
# ctype.h entrypoints
libc.src.ctype.isalnum
libc.src.ctype.isalpha
@@ -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
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 84d28cc3350304..f35cf06a12ca0d 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -400,6 +400,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>]>,
diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index a19d6d0bef08ff..de04f6d0a353b5 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -58,6 +58,130 @@ 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;
+ } else if (bity.is_nan()) {
+ return y;
+ } else if (bitx.sign() != bity.sign()) {
+ // To make sure that fmax(+0, -0) == +0 == fmax(-0, +0), whenever x and
+ // y has different signs and both are not NaNs, we return the number
+ // with positive sign.
+ return (bitx.is_neg() ? y : x);
+ } else {
+ 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;
+ } else if (bity.is_nan()) {
+ return y;
+ } else if (bitx.sign() != bity.sign()) {
+ // To make sure that fmin(+0, -0) == -0 == fmin(-0, +0), whenever x and
+ // y has different signs and both are not NaNs, we return the number
+ // with negative sign.
+ return (bitx.is_neg()) ? x : y;
+ } else {
+ 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_nan()) {
+ return y;
+ } else if (bity.is_nan()) {
+ return x;
+ } else if (bitx.sign() != bity.sign()) {
+ // To make sure that fmax(+0, -0) == +0 == fmax(-0, +0), whenever x and
+ // y has different signs and both are not NaNs, we return the number
+ // with positive sign.
+ return (bitx.is_neg() ? y : x);
+ } else {
+ 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) {
+ const FPBits<T> bitx(x), bity(y);
+
+ if (bitx.is_nan()) {
+ return y;
+ } else if (bity.is_nan()) {
+ return x;
+ } else if (bitx.sign() != bity.sign()) {
+ // To make sure that fmin(+0, -0) == -0 == fmin(-0, +0), whenever x and
+ // y has different signs and both are not NaNs, we return the number
+ // with negative sign.
+ return (bitx.is_neg()) ? x : y;
+ } else {
+ 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;
+ } else if (abs(y) > abs(x)) {
+ return y;
+ } else {
+ 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;
+ } else if (abs(y) < abs(x)) {
+ return y;
+ } else {
+ 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;
+ } else if (abs(y) > abs(x)) {
+ return y;
+ } else {
+ 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;
+ } else if (abs(y) < abs(x)) {
+ return y;
+ } else {
+ 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);
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 5e2e6e699d0e0c..bdfd2a51346307 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -117,6 +117,46 @@ add_math_entrypoint_object(fminf)
add_math_entrypoint_object(fminl)
add_math_entrypoint_object(fminf128)
+add_math_entrypoint_object(fmaximum)
+add_math_entrypoint_object(fmaximumf)
+add_math_entrypoint_object(fmaximuml)
+add_math_entrypoint_object(fmaximumf128)
+
+add_math_entrypoint_object(fmaximum_num)
+add_math_entrypoint_object(fmaximum_numf)
+add_math_entrypoint_object(fmaximum_numl)
+add_math_entrypoint_object(fmaximum_numf128)
+
+add_math_entrypoint_object(fmaximum_mag)
+add_math_entrypoint_object(fmaximum_magf)
+add_math_entrypoint_object(fmaximum_magl)
+add_math_entrypoint_object(fmaximum_magf128)
+
+add_math_entrypoint_object(fmaximum_mag_num)
+add_math_entrypoint_object(fmaximum_mag_numf)
+add_math_entrypoint_object(fmaximum_mag_numl)
+add_math_entrypoint_object(fmaximum_mag_numf128)
+
+add_math_entrypoint_object(fminimum)
+add_math_entrypoint_object(fminimumf)
+add_math_entrypoint_object(fminimuml)
+add_math_entrypoint_object(fminimumf128)
+
+add_math_entrypoint_object(fminimum_num)
+add_math_entrypoint_object(fminimum_numf)
+add_math_entrypoint_object(fminimum_numl)
+add_math_entrypoint_object(fminimum_numf128)
+
+add_math_entrypoint_object(fminimum_mag)
+add_math_entrypoint_object(fminimum_magf)
+add_math_entrypoint_object(fminimum_magl)
+add_math_entrypoint_object(fminimum_magf128)
+
+add_math_entrypoint_object(fminimum_mag_num)
+add_math_entrypoint_object(fminimum_mag_numf)
+add_math_entrypoint_object(fminimum_mag_numl)
+add_math_entrypoint_object(fminimum_mag_numf128)
+
add_math_entrypoint_object(fmod)
add_math_entrypoint_object(fmodf)
add_math_entrypoint_object(fmodl)
diff --git a/libc/src/math/amdgpu/fmaximum.cpp b/libc/src/math/amdgpu/fmaximum.cpp
new file mode 100644
index 00000000000000..a121feb79addce
--- /dev/null
+++ b/libc/src/math/amdgpu/fmaximum.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of the fmaximum function for GPU -----------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/fmaximum.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, fmaximum, (double x, double y)) {
+ return __builtin_fmaximum(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/amdgpu/fmaximum_mag.cpp b/libc/src/math/amdgpu/fmaximum_mag.cpp
new file mode 100644
index 00000000000000..99e277f108e02e
--- /dev/null
+++ b/libc/src/math/amdgpu/fmaximum_mag.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of the fmaximum_mag function for GPU -----------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/fmaximum_mag.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, fmaximum_mag, (double x, double y)) {
+ return __builtin_fmaximum_mag(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/amdgpu/fmaximum_mag_num.cpp b/libc/src/math/amdgpu/fmaximum_mag_num.cpp
new file mode 100644
index 00000000000000..bde427903ad60b
--- /dev/null
+++ b/libc/src/math/amdgpu/fmaximum_mag_num.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of the fmaximum_mag_num function for GPU -----------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/fmaximum_mag_num.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, fmaximum_mag_num, (double x, double y)) {
+ return __builtin_fmaximum_mag_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/amdgpu/fmaximum_mag_numf.cpp b/libc/src/math/amdgpu/fmaximum_mag_numf.cpp
new file mode 100644
index 00000000000000..52f7d1413a1cc2
--- /dev/null
+++ b/libc/src/math/amdgpu/fmaximum_mag_numf.cpp
@@ -0,0 +1,21 @@
+//===-- Implementation of the fmaximum_mag_numf function for GPU -----------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/math/fmaximum_mag_numf.h"
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/optimization.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, fmaximum_mag_numf, (float x, float y)) {
+ return __builtin_fmaximum_mag_num(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/amdgpu/fmaximum_mag_numl.cpp b/libc/sr...
[truncated]
:white_check_mark: With the latest revision this PR passed the C/C++ code formatter.
Thanks for the patch! Try git clang-format HEAD~ to appease the linter!
Thanks for the patch! Try
git clang-format HEAD~to appease the linter!
Do I just do just that. Do I Have to amend the commit?
Thanks for the patch! Try
git clang-format HEAD~to appease the linter!Do I just do just that. Do I Have to amend the commit?
I'd just commit the result and push it so that you have more than one commit.
There was an open bug for this, yeah? If you put Fixes #<bug number> without the <> in the commit message, github will autoclose that issue when the PR is merged.
There was an open bug for this, yeah? If you put
Fixes #<bug number>without the<>in the commit message, github will autoclose that issue when the PR is merged.
It’s for this issue here https://github.com/llvm/llvm-project/issues/85496
Thanks for the patch! Try
git clang-format HEAD~to appease the linter!
I just did that and the checks failed again.
You should also try with full build mode: start with a clean build folder:
$ cmake ../llvm -GNinja -DLLVM_ENABLE_PROJECTS="llvm;libcl;clang;compiler-rt" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release -DLLVM_LIBC_INCLUDE_SCUDO=ON -DLLVM_LIBC_FULL_BUILD=ON
$ ninja libc
$ ninja check-libc
And you should be able to test them individually:
$ ninja libc.test.src.math.smoke.fmaximumf128_test.__unit__
tag @jhuber6 for AMDGPU builtins, building & testing.
@lntue I will address your reviews; thanks!
@arsenm I assume you mean for the GPU implementation? The generic implementation looks correct already since we have to support both clang and GCC.
Thanks for the patch! Try
git clang-format HEAD~to appease the linter!I just did that and the checks failed again.
So what's happening is that the comment on the first line of a few files (see report) is too long. When you run the automated formatter, it's wrapping the line (and appears to do so in a way that doesn't reach a fixed point if the formatter is rerun).
Rather than commit changes suggested by the formatter where it's wrapping the first line comment, you should reject those changes (or not commit them; git commit -p will bring up an interactive mode where you accept/reject individual hunks of a diff) or just fix them directly to be 80 columns.
@arsenm I assume you mean for the GPU implementation? The generic implementation looks correct already since we have to support both clang and GCC.
Probably for this patch, we can remove all the specializations for GPU, and only add them later if they show performance benefits? @jhuber6
Thanks for the patch! Try
git clang-format HEAD~to appease the linter!I just did that and the checks failed again.
So what's happening is that the comment on the first line of a few files (see report) is too long. When you run the automated formatter, it's wrapping the line (and appears to do so in a way that doesn't reach a fixed point if the formatter is rerun).
Rather than commit changes suggested by the formatter where it's wrapping the first line comment, you should reject those changes (or not commit them;
git commit -pwill bring up an interactive mode where you accept/reject individual hunks of a diff) or just fix them directly to be 80 columns.
Thanks. Once I fix the comment do I just run git clang-format HEAD~? I have made two commits already. This command will format my first commit right with all the files?
@arsenm I assume you mean for the GPU implementation? The generic implementation looks correct already since we have to support both clang and GCC.
Probably for this patch, we can remove all the specializations for GPU, and only add them later if they show performance benefits? @jhuber6
The GPU should use __builtin_fmin and __builtin_fmax. This should be available for f64, f32, and f16. We don't support f128 on the GPU at all so it can be ignored. I think in general a lot of platforms have hardware for this, so we should use #if LIBC_HAS_BUILTIN(__builtin_fmin) where present (Though it may require some work around zero like before.
For now however I think that it's good to have a C implementation to fall back on.
Thanks. Once I fix the comment do I just run
git clang-format HEAD~? I have made two commits already. This command will format my first commit right with all the files?
git clang-format HEAD~<N> (without the <>) will format the last N commits. N is optional when N == 1.
So if you have 2 commits git clang-format HEAD~2 would format just the lines touched in the previous 2 commits.
@arsenm I assume you mean for the GPU implementation? The generic implementation looks correct already since we have to support both clang and GCC.
Probably for this patch, we can remove all the specializations for GPU, and only add them later if they show performance benefits? @jhuber6
The GPU should use
__builtin_fminand__builtin_fmax. This should be available for f64, f32, and f16. We don't supportf128on the GPU at all so it can be ignored. I think in general a lot of platforms have hardware for this, so we should use#if LIBC_HAS_BUILTIN(__builtin_fmin)where present (Though it may require some work around zero like before.For now however I think that it's good to have a C implementation to fall back on.
So I can remove the amdgpu stuff right?
Thanks. Once I fix the comment do I just run
git clang-format HEAD~? I have made two commits already. This command will format my first commit right with all the files?
git clang-format HEAD~<N>(without the<>) will format the lastNcommits.Nis optional whenN== 1.So if you have 2 commits
git clang-format HEAD~2would format just the lines touched in the previous 2 commits.
thanks
So I can remove the amdgpu stuff right?
I don't think most of these will compile. It depends on both clang understanding the builtin and the backend being able to emit the intrinsic. See https://godbolt.org/z/vKbxjb1Kb, you should be able to plug in whatever builtin to check if it works.
So I can remove the amdgpu stuff right?
Yes, we can add them back in a followup patch if needed.
So I can remove the amdgpu stuff right?
Yes, we can add them back in a followup patch if needed.
This doesn't update the gpu/entrypoints.txt so they wouldn't have been compiled either way. We should probably just make these use a generic interface and then upgrade the generic interface to use __builitin_fmax like we handle __builtin_fma.
So I can remove the amdgpu stuff right?
Yes, we can add them back in a followup patch if needed.
Ok.
My bad, I accidentally closed the pr. But I just reopened it.
But hey you all, I will start addressing your review today but not sure If I will be able to commit something. Thanks. Ill try to get this done asap.
:white_check_mark: With the latest revision this PR passed the Python code formatter.
@lntue ok I addressed your review
Thanks for the patch! Everything is clean now!
Thank you!
The GPU should use
__builtin_fminand__builtin_fmax.
No, these are different operations. Not sure if we have a wired up builtin for these