[libc-commits] [libc] [libc] Add support for `powi` as an LLVM libc extension on the GPU (PR #98236)

Joseph Huber via libc-commits libc-commits at lists.llvm.org
Tue Jul 9 18:47:12 PDT 2024


https://github.com/jhuber6 updated https://github.com/llvm/llvm-project/pull/98236

>From f54105be8d53cac24cc3459ef0408bde73dab577 Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Tue, 9 Jul 2024 17:43:39 -0500
Subject: [PATCH] [libc] Add support for `powi` as an LLVM libc extension on
 the GPU

Summary:
This function is used by the CUDA / HIP / OpenMP headers and exists as
an NVIDIA extension basically. This function is implemented in the C23
standard as `pown`, but for now we need to provide `powi` for backwards
compatibility. In the future this entrypoint will just be a redirect to
`pown` once that is implemented.
---
 libc/config/gpu/entrypoints.txt     |  2 ++
 libc/docs/math/index.rst            |  2 ++
 libc/spec/llvm_libc_ext.td          |  3 +++
 libc/src/math/CMakeLists.txt        |  2 ++
 libc/src/math/amdgpu/CMakeLists.txt | 24 ++++++++++++++++++++++++
 libc/src/math/amdgpu/declarations.h |  2 ++
 libc/src/math/amdgpu/powi.cpp       | 20 ++++++++++++++++++++
 libc/src/math/amdgpu/powif.cpp      | 20 ++++++++++++++++++++
 libc/src/math/nvptx/CMakeLists.txt  | 24 ++++++++++++++++++++++++
 libc/src/math/nvptx/declarations.h  |  2 ++
 libc/src/math/nvptx/powi.cpp        | 18 ++++++++++++++++++
 libc/src/math/nvptx/powif.cpp       | 18 ++++++++++++++++++
 libc/src/math/powi.h                | 18 ++++++++++++++++++
 libc/src/math/powif.h               | 18 ++++++++++++++++++
 14 files changed, 173 insertions(+)
 create mode 100644 libc/src/math/amdgpu/powi.cpp
 create mode 100644 libc/src/math/amdgpu/powif.cpp
 create mode 100644 libc/src/math/nvptx/powi.cpp
 create mode 100644 libc/src/math/nvptx/powif.cpp
 create mode 100644 libc/src/math/powi.h
 create mode 100644 libc/src/math/powif.h

diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt
index 62f3f0df247cc..166144d634344 100644
--- a/libc/config/gpu/entrypoints.txt
+++ b/libc/config/gpu/entrypoints.txt
@@ -313,6 +313,8 @@ set(TARGET_LIBM_ENTRYPOINTS
     libc.src.math.nexttowardf
     libc.src.math.pow
     libc.src.math.powf
+    libc.src.math.powi
+    libc.src.math.powif
     libc.src.math.remainder
     libc.src.math.remainderf
     libc.src.math.remquo
diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst
index 7914a3d7e6d1a..70412e4ed203d 100644
--- a/libc/docs/math/index.rst
+++ b/libc/docs/math/index.rst
@@ -320,6 +320,8 @@ Higher Math Functions
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | pow       | |check|          |                 |                        |                      |                        | 7.12.7.5               | F.10.4.5                   |
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
+| powi\*    |                  |                 |                        |                      |                        |                        |                            |
++-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | pown      |                  |                 |                        |                      |                        | 7.12.7.6               | F.10.4.6                   |
 +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
 | powr      |                  |                 |                        |                      |                        | 7.12.7.7               | F.10.4.7                   |
diff --git a/libc/spec/llvm_libc_ext.td b/libc/spec/llvm_libc_ext.td
index c0374cb631191..86215029831ca 100644
--- a/libc/spec/llvm_libc_ext.td
+++ b/libc/spec/llvm_libc_ext.td
@@ -76,6 +76,9 @@ def LLVMLibcExt : StandardSpec<"llvm_libc_ext"> {
           GuardedFunctionSpec<"f16sqrt", RetValSpec<Float16Type>, [ArgSpec<DoubleType>], "LIBC_TYPES_HAS_FLOAT16">,
           GuardedFunctionSpec<"f16sqrtf", RetValSpec<Float16Type>, [ArgSpec<FloatType>], "LIBC_TYPES_HAS_FLOAT16">,
           GuardedFunctionSpec<"f16sqrtl", RetValSpec<Float16Type>, [ArgSpec<LongDoubleType>], "LIBC_TYPES_HAS_FLOAT16">,
+
+          FunctionSpec<"powi", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntType>]>,
+          FunctionSpec<"powif", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntType>]>,
       ]
   >;
 
diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt
index 74c2e4efda617..3a13ccbedec5a 100644
--- a/libc/src/math/CMakeLists.txt
+++ b/libc/src/math/CMakeLists.txt
@@ -342,6 +342,8 @@ add_math_entrypoint_object(nextupf128)
 
 add_math_entrypoint_object(pow)
 add_math_entrypoint_object(powf)
+add_math_entrypoint_object(powi)
+add_math_entrypoint_object(powif)
 
 add_math_entrypoint_object(remainder)
 add_math_entrypoint_object(remainderf)
diff --git a/libc/src/math/amdgpu/CMakeLists.txt b/libc/src/math/amdgpu/CMakeLists.txt
index 202177f54b11a..2ceb12785c607 100644
--- a/libc/src/math/amdgpu/CMakeLists.txt
+++ b/libc/src/math/amdgpu/CMakeLists.txt
@@ -468,6 +468,30 @@ add_entrypoint_object(
   VENDOR
 )
 
+add_entrypoint_object(
+  powi
+  SRCS
+    powi.cpp
+  HDRS
+    ../powi.h
+  COMPILE_OPTIONS
+    ${bitcode_link_flags}
+    -O2
+  VENDOR
+)
+
+add_entrypoint_object(
+  powif
+  SRCS
+    powif.cpp
+  HDRS
+    ../powif.h
+  COMPILE_OPTIONS
+    ${bitcode_link_flags}
+    -O2
+  VENDOR
+)
+
 add_entrypoint_object(
   sinh
   SRCS
diff --git a/libc/src/math/amdgpu/declarations.h b/libc/src/math/amdgpu/declarations.h
index 5d7f3c9609d23..81d788d943f22 100644
--- a/libc/src/math/amdgpu/declarations.h
+++ b/libc/src/math/amdgpu/declarations.h
@@ -65,6 +65,8 @@ float __ocml_nextafter_f32(float, float);
 double __ocml_nextafter_f64(double, double);
 float __ocml_pow_f32(float, float);
 double __ocml_pow_f64(double, double);
+float __ocml_pown_f32(float, int);
+double __ocml_pown_f64(double, int);
 float __ocml_sin_f32(float);
 double __ocml_sin_f64(double);
 float __ocml_sincos_f32(float, float *);
diff --git a/libc/src/math/amdgpu/powi.cpp b/libc/src/math/amdgpu/powi.cpp
new file mode 100644
index 0000000000000..b13cb52aaaf6a
--- /dev/null
+++ b/libc/src/math/amdgpu/powi.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the powi 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/powi.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, powi, (double x, int y)) {
+  return __ocml_pown_f64(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/amdgpu/powif.cpp b/libc/src/math/amdgpu/powif.cpp
new file mode 100644
index 0000000000000..7682f0e1a27a6
--- /dev/null
+++ b/libc/src/math/amdgpu/powif.cpp
@@ -0,0 +1,20 @@
+//===-- Implementation of the powi 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/powif.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, powif, (float x, int y)) {
+  return __ocml_pown_f32(x, y);
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/nvptx/CMakeLists.txt b/libc/src/math/nvptx/CMakeLists.txt
index bf37c52f09e44..4295ebf9ff630 100644
--- a/libc/src/math/nvptx/CMakeLists.txt
+++ b/libc/src/math/nvptx/CMakeLists.txt
@@ -421,6 +421,30 @@ add_entrypoint_object(
   VENDOR
 )
 
+add_entrypoint_object(
+  powi
+  SRCS
+    powi.cpp
+  HDRS
+    ../powi.h
+  COMPILE_OPTIONS
+    ${bitcode_link_flags}
+    -O2
+  VENDOR
+)
+
+add_entrypoint_object(
+  powif
+  SRCS
+    powif.cpp
+  HDRS
+    ../powif.h
+  COMPILE_OPTIONS
+    ${bitcode_link_flags}
+    -O2
+  VENDOR
+)
+
 add_entrypoint_object(
   sinh
   SRCS
diff --git a/libc/src/math/nvptx/declarations.h b/libc/src/math/nvptx/declarations.h
index d41b16c8eec9f..cf8f6e09e492a 100644
--- a/libc/src/math/nvptx/declarations.h
+++ b/libc/src/math/nvptx/declarations.h
@@ -64,6 +64,8 @@ double __nv_nextafter(double, double);
 float __nv_nextafterf(float, float);
 double __nv_pow(double, double);
 float __nv_powf(float, float);
+double __nv_powi(double, int);
+float __nv_powif(float, int);
 double __nv_sin(double);
 float __nv_sinf(float);
 void __nv_sincos(double, double *, double *);
diff --git a/libc/src/math/nvptx/powi.cpp b/libc/src/math/nvptx/powi.cpp
new file mode 100644
index 0000000000000..b7871ab9da92e
--- /dev/null
+++ b/libc/src/math/nvptx/powi.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the powi 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/powi.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(double, powi, (double x, int y)) { return __nv_powi(x, y); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/nvptx/powif.cpp b/libc/src/math/nvptx/powif.cpp
new file mode 100644
index 0000000000000..0143745479cec
--- /dev/null
+++ b/libc/src/math/nvptx/powif.cpp
@@ -0,0 +1,18 @@
+//===-- Implementation of the powif 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/powif.h"
+#include "src/__support/common.h"
+
+#include "declarations.h"
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(float, powif, (float x, int y)) { return __nv_powif(x, y); }
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/math/powi.h b/libc/src/math/powi.h
new file mode 100644
index 0000000000000..1ee7140f06489
--- /dev/null
+++ b/libc/src/math/powi.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for powi --------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_MATH_POWI_H
+#define LLVM_LIBC_SRC_MATH_POWI_H
+
+namespace LIBC_NAMESPACE {
+
+double powi(double x, int y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_POW_H
diff --git a/libc/src/math/powif.h b/libc/src/math/powif.h
new file mode 100644
index 0000000000000..417012a34fecc
--- /dev/null
+++ b/libc/src/math/powif.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for powif -------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_MATH_POWIF_H
+#define LLVM_LIBC_SRC_MATH_POWIF_H
+
+namespace LIBC_NAMESPACE {
+
+float powif(float x, int y);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_MATH_POW_H



More information about the libc-commits mailing list