Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libc][stdfix] Implement fixed point fxbits functions in llvm-libc #114912

Conversation

smallp-o-p
Copy link
Contributor

No description provided.

Copy link

github-actions bot commented Nov 5, 2024

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the LLVM GitHub User Guide.

You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums.

@llvmbot llvmbot added the libc label Nov 5, 2024
@llvmbot
Copy link
Member

llvmbot commented Nov 5, 2024

@llvm/pr-subscribers-libc

Author: William Tran-Viet (smallp-o-p)

Changes

Patch is 40.56 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/114912.diff

46 Files Affected:

  • (modified) libc/config/baremetal/arm/entrypoints.txt (+12)
  • (modified) libc/config/baremetal/riscv/entrypoints.txt (+12)
  • (modified) libc/config/linux/riscv/entrypoints.txt (+12)
  • (modified) libc/config/linux/x86_64/entrypoints.txt (+12)
  • (modified) libc/include/llvm-libc-macros/stdfix-macros.h (+13)
  • (modified) libc/newhdrgen/yaml/stdfix.yaml (+84)
  • (modified) libc/src/__support/fixed_point/fx_bits.h (+5-1)
  • (modified) libc/src/stdfix/CMakeLists.txt (+15)
  • (added) libc/src/stdfix/hkbits.cpp (+19)
  • (added) libc/src/stdfix/hkbits.h (+21)
  • (added) libc/src/stdfix/hrbits.cpp (+19)
  • (added) libc/src/stdfix/hrbits.h (+21)
  • (added) libc/src/stdfix/kbits.cpp (+19)
  • (added) libc/src/stdfix/kbits.h (+21)
  • (added) libc/src/stdfix/lkbits.cpp (+19)
  • (added) libc/src/stdfix/lkbits.h (+21)
  • (added) libc/src/stdfix/lrbits.cpp (+19)
  • (added) libc/src/stdfix/lrbits.h (+21)
  • (added) libc/src/stdfix/rbits.cpp (+19)
  • (added) libc/src/stdfix/rbits.h (+21)
  • (added) libc/src/stdfix/uhkbits.cpp (+19)
  • (added) libc/src/stdfix/uhkbits.h (+21)
  • (added) libc/src/stdfix/uhrbits.cpp (+19)
  • (added) libc/src/stdfix/uhrbits.h (+21)
  • (added) libc/src/stdfix/ukbits.cpp (+19)
  • (added) libc/src/stdfix/ukbits.h (+21)
  • (added) libc/src/stdfix/ulkbits.cpp (+19)
  • (added) libc/src/stdfix/ulkbits.h (+21)
  • (added) libc/src/stdfix/ulrbits.cpp (+19)
  • (added) libc/src/stdfix/ulrbits.h (+21)
  • (added) libc/src/stdfix/urbits.cpp (+19)
  • (added) libc/src/stdfix/urbits.h (+21)
  • (modified) libc/test/src/stdfix/CMakeLists.txt (+18)
  • (added) libc/test/src/stdfix/FxBitsTest.h (+54)
  • (added) libc/test/src/stdfix/hkbits_test.cpp (+12)
  • (added) libc/test/src/stdfix/hrbits_test.cpp (+12)
  • (added) libc/test/src/stdfix/kbits_test.cpp (+12)
  • (added) libc/test/src/stdfix/lkbits_test.cpp (+12)
  • (added) libc/test/src/stdfix/lrbits_test.cpp (+12)
  • (added) libc/test/src/stdfix/rbits_test.cpp (+12)
  • (added) libc/test/src/stdfix/uhkbits_test.cpp (+13)
  • (added) libc/test/src/stdfix/uhrbits_test.cpp (+13)
  • (added) libc/test/src/stdfix/ukbits_test.cpp (+12)
  • (added) libc/test/src/stdfix/ulkbits_test.cpp (+12)
  • (added) libc/test/src/stdfix/ulrbits_test.cpp (+12)
  • (added) libc/test/src/stdfix/urbits_test.cpp (+12)
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 68030f7f1775b5..b85ae1119345dd 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -455,6 +455,18 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.sqrtulr
     libc.src.stdfix.uhksqrtus
     libc.src.stdfix.uksqrtui
+    libc.src.stdfix.hrbits
+    libc.src.stdfix.uhrbits
+    libc.src.stdfix.rbits
+    libc.src.stdfix.urbits
+    libc.src.stdfix.lrbits
+    libc.src.stdfix.ulrbits
+    libc.src.stdfix.hkbits
+    libc.src.stdfix.uhkbits
+    libc.src.stdfix.kbits
+    libc.src.stdfix.ukbits
+    libc.src.stdfix.lkbits
+    libc.src.stdfix.ulkbits
   )
 endif()
 
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index 5894b591072ef0..199a030ee6371e 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -450,6 +450,18 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.sqrtulr
     libc.src.stdfix.uhksqrtus
     libc.src.stdfix.uksqrtui
+    libc.src.stdfix.hrbits
+    libc.src.stdfix.uhrbits
+    libc.src.stdfix.rbits
+    libc.src.stdfix.urbits
+    libc.src.stdfix.lrbits
+    libc.src.stdfix.ulrbits
+    libc.src.stdfix.hkbits
+    libc.src.stdfix.uhkbits
+    libc.src.stdfix.kbits
+    libc.src.stdfix.ukbits
+    libc.src.stdfix.lkbits
+    libc.src.stdfix.ulkbits   
   )
 endif()
 
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 5c09edf7cfb266..7263f69fb08268 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -704,6 +704,18 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.sqrtulr
     libc.src.stdfix.uhksqrtus
     libc.src.stdfix.uksqrtui
+    libc.src.stdfix.hrbits
+    libc.src.stdfix.uhrbits
+    libc.src.stdfix.rbits
+    libc.src.stdfix.urbits
+    libc.src.stdfix.lrbits
+    libc.src.stdfix.ulrbits
+    libc.src.stdfix.hkbits
+    libc.src.stdfix.uhkbits
+    libc.src.stdfix.kbits
+    libc.src.stdfix.ukbits
+    libc.src.stdfix.lkbits
+    libc.src.stdfix.ulkbits
   )
 endif()
 
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index a2fb97d04584d5..536884779c433e 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -808,6 +808,18 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
     libc.src.stdfix.sqrtulr
     libc.src.stdfix.uhksqrtus
     libc.src.stdfix.uksqrtui
+    libc.src.stdfix.hrbits
+    libc.src.stdfix.uhrbits
+    libc.src.stdfix.rbits
+    libc.src.stdfix.urbits
+    libc.src.stdfix.lrbits
+    libc.src.stdfix.ulrbits
+    libc.src.stdfix.hkbits
+    libc.src.stdfix.uhkbits
+    libc.src.stdfix.kbits
+    libc.src.stdfix.ukbits
+    libc.src.stdfix.lkbits
+    libc.src.stdfix.ulkbits
   )
 endif()
 
diff --git a/libc/include/llvm-libc-macros/stdfix-macros.h b/libc/include/llvm-libc-macros/stdfix-macros.h
index 554ebe544a42ed..9bfb58672b3c01 100644
--- a/libc/include/llvm-libc-macros/stdfix-macros.h
+++ b/libc/include/llvm-libc-macros/stdfix-macros.h
@@ -323,6 +323,19 @@
 #define ULACCUM_EPSILON 0x1.0p-32ULK
 #endif // ULACCUM_EPSILON
 
+typedef signed char int_hr_t;
+typedef signed short int int_r_t;
+typedef signed int int_lr_t;
+typedef signed short int_hk_t;
+typedef signed int int_k_t;
+typedef signed long int_lk_t;
+typedef unsigned char uint_uhr_t;
+typedef unsigned short int uint_ur_t;
+typedef unsigned int uint_ulr_t;
+typedef unsigned short int uint_uhk_t;
+typedef unsigned int uint_uk_t;
+typedef unsigned long uint_ulk_t;
+
 #endif // LIBC_COMPILER_HAS_FIXED_POINT
 
 #endif // LLVM_LIBC_MACROS_STDFIX_MACROS_H
diff --git a/libc/newhdrgen/yaml/stdfix.yaml b/libc/newhdrgen/yaml/stdfix.yaml
index ca6658939e2278..02fb7adb1fed8c 100644
--- a/libc/newhdrgen/yaml/stdfix.yaml
+++ b/libc/newhdrgen/yaml/stdfix.yaml
@@ -62,6 +62,90 @@ functions:
     arguments:
       - type: accum
     guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: hrbits
+    standards:
+      - stdc_ext
+    return_type: short fract
+    arguments:
+      - type: int_hr_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: uhrbits
+    standards:
+      - stdc_ext
+    return_type: unsigned short fract
+    arguments:
+      - type: uint_uhr_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: rbits
+    standards:
+      - stdc_ext
+    return_type: fract
+    arguments:
+      - type: int_r_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: urbits
+    standards:
+      - stdc_ext
+    return_type: unsigned fract
+    arguments:
+      - type: uint_ur_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: lrbits
+    standards:
+      - stdc_ext
+    return_type: long fract
+    arguments:
+      - type: int_lr_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: ulrbits
+    standards:
+      - stdc_ext
+    return_type: unsigned long fract
+    arguments:
+      - type: uint_ulr_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: hkbits
+    standards:
+      - stdc_ext
+    return_type: short accum
+    arguments:
+      - type: int_hk_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: uhkbits
+    standards:
+      - stdc_ext
+    return_type: unsigned short accum
+    arguments:
+      - type: uint_uhk_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: kbits
+    standards:
+      - stdc_ext
+    return_type: accum
+    arguments:
+      - type: int_k_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: ukbits
+    standards:
+      - stdc_ext
+    return_type: unsigned accum
+    arguments:
+      - type: uint_uk_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: lkbits
+    standards:
+      - stdc_ext
+    return_type: long accum
+    arguments:
+      - type: uint_ulr_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
+  - name: ulkbits
+    standards:
+      - stdc_ext
+    return_type: unsigned long accum
+    arguments:
+      - type: uint_ulk_t
+    guard: LIBC_COMPILER_HAS_FIXED_POINT
   - name: roundhk
     standards:
       - stdc_ext
diff --git a/libc/src/__support/fixed_point/fx_bits.h b/libc/src/__support/fixed_point/fx_bits.h
index 0a4c21fb6a14f7..913c65ea5b599b 100644
--- a/libc/src/__support/fixed_point/fx_bits.h
+++ b/libc/src/__support/fixed_point/fx_bits.h
@@ -12,7 +12,7 @@
 #include "include/llvm-libc-macros/stdfix-macros.h"
 #include "src/__support/CPP/bit.h"
 #include "src/__support/CPP/type_traits.h"
-#include "src/__support/macros/attributes.h"   // LIBC_INLINE
+#include "src/__support/macros/attributes.h" // LIBC_INLINE
 #include "src/__support/macros/config.h"
 #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
 #include "src/__support/math_extras.h"
@@ -163,6 +163,10 @@ template <typename T> LIBC_INLINE constexpr T round(T x, int n) {
   return bit_and((x + round_bit), rounding_mask);
 }
 
+template <typename T, typename XType> LIBC_INLINE constexpr T fx_bits(XType x) {
+  return cpp::bit_cast<T, XType>(x);
+}
+
 } // namespace fixed_point
 } // namespace LIBC_NAMESPACE_DECL
 
diff --git a/libc/src/stdfix/CMakeLists.txt b/libc/src/stdfix/CMakeLists.txt
index 10d76ae31349f9..7b2793196ab04c 100644
--- a/libc/src/stdfix/CMakeLists.txt
+++ b/libc/src/stdfix/CMakeLists.txt
@@ -44,6 +44,21 @@ foreach(suffix IN ITEMS hr r lr hk k lk uhr ur ulr uhk uk ulk)
   )
 endforeach()
 
+foreach(prefix IN ITEMS hr r lr hk k lk uhr ur ulr uhk uk ulk)
+  add_entrypoint_object(
+    ${prefix}bits
+    HDRS
+      ${prefix}bits.h
+    SRCS
+      ${prefix}bits.cpp
+    COMPILE_OPTIONS
+      -O3
+    DEPENDS
+      libc.src.__support.CPP.bit
+      libc.src.__support.fixed_point.fx_bits
+  )
+endforeach()
+
 add_entrypoint_object(
   uhksqrtus
   HDRS
diff --git a/libc/src/stdfix/hkbits.cpp b/libc/src/stdfix/hkbits.cpp
new file mode 100644
index 00000000000000..e74530e1628cfa
--- /dev/null
+++ b/libc/src/stdfix/hkbits.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of hkbits function ---------------------------------===//
+//
+// 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 "hkbits.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(short accum, hkbits, (int_hk_t x)) {
+  return fixed_point::fx_bits<short accum, int_hk_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/hkbits.h b/libc/src/stdfix/hkbits.h
new file mode 100644
index 00000000000000..219d86f9d663df
--- /dev/null
+++ b/libc/src/stdfix/hkbits.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for hkbits ------------------------*- 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_STDFIX_HKBITS_H
+#define LLVM_LIBC_SRC_STDFIX_HKBITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+short accum hkbits(int_hk_t x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_HKBITS_H
diff --git a/libc/src/stdfix/hrbits.cpp b/libc/src/stdfix/hrbits.cpp
new file mode 100644
index 00000000000000..0b429805416b89
--- /dev/null
+++ b/libc/src/stdfix/hrbits.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of hrbits function ---------------------------------===//
+//
+// 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 "hrbits.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(short fract, hrbits, (int_hr_t x)) {
+  return fixed_point::fx_bits<short fract, int_hr_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/hrbits.h b/libc/src/stdfix/hrbits.h
new file mode 100644
index 00000000000000..32ae781e54a0ef
--- /dev/null
+++ b/libc/src/stdfix/hrbits.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for hrbits ------------------------*- 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_STDFIX_HRBITS_H
+#define LLVM_LIBC_SRC_STDFIX_HRBITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+short fract hrbits(int_hr_t x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_HRBITS_H
diff --git a/libc/src/stdfix/kbits.cpp b/libc/src/stdfix/kbits.cpp
new file mode 100644
index 00000000000000..8a4be67899dafb
--- /dev/null
+++ b/libc/src/stdfix/kbits.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of kbits function ----------------------------------===//
+//
+// 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 "kbits.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(accum, kbits, (int_k_t x)) {
+  return fixed_point::fx_bits<accum, int_k_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/kbits.h b/libc/src/stdfix/kbits.h
new file mode 100644
index 00000000000000..c56faa01e42c41
--- /dev/null
+++ b/libc/src/stdfix/kbits.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for kbits -------------------------*- 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_STDFIX_KBITS_H
+#define LLVM_LIBC_SRC_STDFIX_KBITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+accum kbits(int_k_t x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_KBITS_H
diff --git a/libc/src/stdfix/lkbits.cpp b/libc/src/stdfix/lkbits.cpp
new file mode 100644
index 00000000000000..828bd6d1d20c1e
--- /dev/null
+++ b/libc/src/stdfix/lkbits.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of lkbits function ---------------------------------===//
+//
+// 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 "lkbits.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(long accum, lkbits, (int_lk_t x)) {
+  return fixed_point::fx_bits<long accum, int_lk_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/lkbits.h b/libc/src/stdfix/lkbits.h
new file mode 100644
index 00000000000000..bbe0f4cee10e8a
--- /dev/null
+++ b/libc/src/stdfix/lkbits.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for lkbits ------------------------*- 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_STDFIX_LKBITS_H
+#define LLVM_LIBC_SRC_STDFIX_LKBITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+long accum lkbits(int_lk_t x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_LKBITS_H
diff --git a/libc/src/stdfix/lrbits.cpp b/libc/src/stdfix/lrbits.cpp
new file mode 100644
index 00000000000000..206f26cb1c7aa9
--- /dev/null
+++ b/libc/src/stdfix/lrbits.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of lrbits function ---------------------------------===//
+//
+// 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 "lrbits.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(long fract, lrbits, (int_lr_t x)) {
+  return fixed_point::fx_bits<long fract, int_lr_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/lrbits.h b/libc/src/stdfix/lrbits.h
new file mode 100644
index 00000000000000..7a91e4df72fd29
--- /dev/null
+++ b/libc/src/stdfix/lrbits.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for lrbits ------------------------*- 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_STDFIX_LRBITS_H
+#define LLVM_LIBC_SRC_STDFIX_LRBITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+long fract lrbits(int_lr_t x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_LRBITS_H
diff --git a/libc/src/stdfix/rbits.cpp b/libc/src/stdfix/rbits.cpp
new file mode 100644
index 00000000000000..f00634b1b83c18
--- /dev/null
+++ b/libc/src/stdfix/rbits.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of rbits function ----------------------------------===//
+//
+// 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 "rbits.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(fract, rbits, (int_r_t x)) {
+  return fixed_point::fx_bits<fract, int_r_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/rbits.h b/libc/src/stdfix/rbits.h
new file mode 100644
index 00000000000000..10dd4e4459f570
--- /dev/null
+++ b/libc/src/stdfix/rbits.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for rbits -------------------------*- 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_STDFIX_RBITS_H
+#define LLVM_LIBC_SRC_STDFIX_RBITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+fract rbits(int_r_t x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_RBITS_H
diff --git a/libc/src/stdfix/uhkbits.cpp b/libc/src/stdfix/uhkbits.cpp
new file mode 100644
index 00000000000000..1549dcc864f9f0
--- /dev/null
+++ b/libc/src/stdfix/uhkbits.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of uhkbits function --------------------------------===//
+//
+// 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 "uhkbits.h"
+#include "src/__support/common.h"
+#include "src/__support/fixed_point/fx_bits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+LLVM_LIBC_FUNCTION(unsigned short accum, uhkbits, (uint_uhk_t x)) {
+  return fixed_point::fx_bits<unsigned short accum, uint_uhk_t>(x);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdfix/uhkbits.h b/libc/src/stdfix/uhkbits.h
new file mode 100644
index 00000000000000..751fac75d4589f
--- /dev/null
+++ b/libc/src/stdfix/uhkbits.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for uhkbits -----------------------*- 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_STDFIX_UHKBITS_H
+#define LLVM_LIBC_SRC_STDFIX_UHKBITS_H
+
+#include "include/llvm-libc-macros/stdfix-macros.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+unsigned short accum uhkbits(uint_uhk_t x);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDFIX_UHKBITS_H
diff --git a/libc/src/stdfix/uhrbits.cpp b/libc/src/stdfix/uhrbits.cpp
new file mode 100644
index 00000000000000..c73189d50dc03b
--...
[truncated]

@lntue lntue self-requested a review November 5, 2024 14:30
Copy link
Contributor

@michaelrj-google michaelrj-google left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a good start, I've left a few comments

Copy link
Contributor

@lntue lntue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You also need to add the types and the functions to libc/spec/stdc_ext.td

@smallp-o-p smallp-o-p force-pushed the 113360-Implement-fixed-point-fxbits-functions-in-llvm-libc branch from 2a4cb94 to fdd7f3e Compare November 8, 2024 03:46
Copy link
Contributor

@michaelrj-google michaelrj-google left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs some small changes, but looks almost ready.

@smallp-o-p smallp-o-p force-pushed the 113360-Implement-fixed-point-fxbits-functions-in-llvm-libc branch from fdd7f3e to 809e487 Compare November 9, 2024 00:35
@smallp-o-p smallp-o-p force-pushed the 113360-Implement-fixed-point-fxbits-functions-in-llvm-libc branch from 809e487 to b9e2b53 Compare November 9, 2024 00:37
@lntue lntue merged commit c11b6e8 into llvm:main Nov 11, 2024
7 checks passed
Copy link

@smallp-o-p Congratulations on having your first Pull Request (PR) merged into the LLVM Project!

Your changes will be combined with recent changes from other authors, then tested by our build bots. If there is a problem with a build, you may receive a report in an email or a comment on this PR.

Please check whether problems have been caused by your change specifically, as the builds can include changes from many authors. It is not uncommon for your change to be included in a build that fails due to someone else's changes, or infrastructure issues.

How to do this, and the rest of the post-merge process, is covered in detail here.

If your change does cause a problem, it may be reverted, or you can revert it yourself. This is a normal part of LLVM development. You can fix your changes and open a new PR to merge them again.

If you don't get any reports, no action is required from you. Your changes are working as expected, well done!

@@ -15,13 +15,26 @@ def UnsignedShortAccumType : NamedType<"unsigned short accum">;
def UnsignedAccumType : NamedType<"unsigned accum">;
def UnsignedLongAccumType : NamedType<"unsigned long accum">;

def IntHrT : NamedType <"int_hr_t">;
def IntRT : NamedTypes<"int_r_t">;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Buildbots are failing with:

llvm-project/libc/spec/stdc_ext.td:19:13: error: Couldn't find class 'NamedTypes'
def IntRT : NamedTypes<"int_r_t">;
            ^

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/NamedTypes/NamedType/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pushed 8366be7

nickdesaulniers added a commit that referenced this pull request Nov 11, 2024
GuardedFunctionSpec<"lkbits", RetValSpec<LongAccumType>, [ArgSpec<IntLkT>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"uhrbits", RetValSpec<UnsignedShortFractType>, [ArgSpec<UIntUhrT>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"urbits", RetValSpec<UnsignedFractType>, [ArgSpec<UIntUrT>], "LIBC_COMPILER_HAS_FIXED_POINT">,
GuardedFunctionSpec<"ukbits", RetValSpec<UnsignedAccumType>, [ArgSpec<UIntUkT>], "LIBC_COMPILER_HAS_FIXED_POINT">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing a comma on the end.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nickdesaulniers added a commit that referenced this pull request Nov 11, 2024

namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(long accum, lkbits, (int_lk_t x)) {
return cpp::bit_cast<long accum, int_lk_t>(x);
Copy link
Member

@nickdesaulniers nickdesaulniers Nov 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this is breaking the riscv32 build bots

libc/src/stdfix/lkbits.cpp:16:10: error: no matching function for call to 'bit_cast'
   16 |   return cpp::bit_cast<long accum, int_lk_t>(x);
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
llvm-project/libc/src/__support/CPP/bit.h:38:1: note: candidate template ignored: substitution failure [with To = long _Accum, From = int_lk_t]: implicit instantiation of undefined template '__llvm_libc_20_0_0_git::cpp::enable_if<false, long _Accum>'
   38 | bit_cast(const From &from) {
      | ^

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can disable the riscv32 entrypoint for further investigation?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're seeing this error on our linux/mac/windows clang builders as well. Is there a possible size mismatch between the template parameters?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's due to int_lk_t being 4 bytes on 32bit platforms while long _Accum seems to always be 8 bytes.

cc @PiJoules Is that supposed to be right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From a discussion with @smallp-o-p on #libc in LLVM discord:

yeah i did some ad-hoc checking on godbolt and very inconveniently long is 4 bytes while long _Accum and its unsigned counterpart are always 8 bytes

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't assume that a long is large enough to hold the bits of a long _Accum since they are completely different types independent of each other. The same goes for the other integral typedefs. Individual platforms can define different numbers of integral + fractional bits to the fixed point types as long as they conform the rules of minimal required bits and nondecreasing bits with increasing rank. A.3 Possible Data Type Implementations gives an example for typical 24-bit DSP where the long fixed point types might not fit in a 32-bit int.

Unfortunately, I don't think there's a C preprocessor way we can do size checks for the different ints at compile time. If we did, then we could compare those sizes against the fixed point FBIT and IBIT macros and setup a #if chain of comparisons to select the correct type. I think the correct way to do this might be to have the compiler emit predefined macros for either:

  1. __SIZEOF_<FX_TYPE>__ which evaluates to the size of a fixed point type in bits, then we could do the #if chain comparing against __SIZEOF_SHORT/INT/LONG__ to select the right type. This approach doesn't account for padding bits, but we likely won't have any fixed point type where padding is so large that we'd need an even larger int type.
  2. __<FX_TYPE>_TYPE__ which evaluates to the appropriately sized int type (ie. #define __INT_LR_TYPE__ int). This might be the easier approach.

I think for unblocking this PR that using a long long is fine for now since clang has only one version of long _Accum that anyone uses.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're comparing __SIZEOF_<FX_TYPE>__ would it make sense to then use the appropriate bit int? (e.g. uint32_t, uint64_t)

nickdesaulniers added a commit to nickdesaulniers/llvm-project that referenced this pull request Nov 11, 2024
nickdesaulniers added a commit that referenced this pull request Nov 11, 2024
nickdesaulniers added a commit to nickdesaulniers/llvm-project that referenced this pull request Nov 12, 2024
I should have disabled this in llvm#115781. Mea culpa.

Link: llvm#114912
Link: llvm#115778
Link: llvm#115781
nickdesaulniers added a commit that referenced this pull request Nov 12, 2024
I should have disabled this in #115781. Mea culpa.

Link: #114912
Link: #115778
Link: #115781
Groverkss pushed a commit to iree-org/llvm-project that referenced this pull request Nov 15, 2024
Groverkss pushed a commit to iree-org/llvm-project that referenced this pull request Nov 15, 2024
Groverkss pushed a commit to iree-org/llvm-project that referenced this pull request Nov 15, 2024
Groverkss pushed a commit to iree-org/llvm-project that referenced this pull request Nov 15, 2024
Groverkss pushed a commit to iree-org/llvm-project that referenced this pull request Nov 15, 2024
@smallp-o-p smallp-o-p deleted the 113360-Implement-fixed-point-fxbits-functions-in-llvm-libc branch November 30, 2024 22:00
PiJoules added a commit to PiJoules/llvm-project that referenced this pull request Feb 27, 2025
PiJoules added a commit that referenced this pull request Feb 27, 2025
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Feb 27, 2025
jph-13 pushed a commit to jph-13/llvm-project that referenced this pull request Feb 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants