llvm-project icon indicating copy to clipboard operation
llvm-project copied to clipboard

[libc][math][c23] add c23 floating point fmaximum and fminimum functions.

Open jobhdez opened this issue 1 year ago • 26 comments

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.

jobhdez avatar Mar 20 '24 21:03 jobhdez

@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]

llvmbot avatar Mar 20 '24 21:03 llvmbot

:white_check_mark: With the latest revision this PR passed the C/C++ code formatter.

github-actions[bot] avatar Mar 20 '24 21:03 github-actions[bot]

Thanks for the patch! Try git clang-format HEAD~ to appease the linter!

nickdesaulniers avatar Mar 20 '24 21:03 nickdesaulniers

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?

ghost avatar Mar 20 '24 21:03 ghost

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.

nickdesaulniers avatar Mar 20 '24 21:03 nickdesaulniers

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.

nickdesaulniers avatar Mar 20 '24 21:03 nickdesaulniers

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

ghost avatar Mar 20 '24 22:03 ghost

Thanks for the patch! Try git clang-format HEAD~ to appease the linter!

I just did that and the checks failed again.

ghost avatar Mar 20 '24 22:03 ghost

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__

lntue avatar Mar 20 '24 22:03 lntue

tag @jhuber6 for AMDGPU builtins, building & testing.

lntue avatar Mar 20 '24 23:03 lntue

@lntue I will address your reviews; thanks!

ghost avatar Mar 20 '24 23:03 ghost

@arsenm I assume you mean for the GPU implementation? The generic implementation looks correct already since we have to support both clang and GCC.

michaelrj-google avatar Mar 21 '24 15:03 michaelrj-google

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.

nickdesaulniers avatar Mar 21 '24 16:03 nickdesaulniers

@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

lntue avatar Mar 21 '24 16:03 lntue

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.

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?

ghost avatar Mar 21 '24 19:03 ghost

@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.

jhuber6 avatar Mar 21 '24 19:03 jhuber6

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.

nickdesaulniers avatar Mar 21 '24 20:03 nickdesaulniers

@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.

So I can remove the amdgpu stuff right?

ghost avatar Mar 21 '24 20:03 ghost

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.

thanks

ghost avatar Mar 21 '24 20:03 ghost

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.

jhuber6 avatar Mar 21 '24 20:03 jhuber6

So I can remove the amdgpu stuff right?

Yes, we can add them back in a followup patch if needed.

michaelrj-google avatar Mar 21 '24 21:03 michaelrj-google

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.

jhuber6 avatar Mar 21 '24 21:03 jhuber6

So I can remove the amdgpu stuff right?

Yes, we can add them back in a followup patch if needed.

Ok.

ghost avatar Mar 21 '24 21:03 ghost

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.

ghost avatar Mar 21 '24 21:03 ghost

:white_check_mark: With the latest revision this PR passed the Python code formatter.

github-actions[bot] avatar Mar 24 '24 05:03 github-actions[bot]

@lntue ok I addressed your review

ghost avatar Mar 24 '24 05:03 ghost

Thanks for the patch! Everything is clean now!

Thank you!

ghost avatar Mar 25 '24 19:03 ghost

The GPU should use __builtin_fmin and __builtin_fmax.

No, these are different operations. Not sure if we have a wired up builtin for these

arsenm avatar Mar 26 '24 14:03 arsenm