Skip to content

[libc][stdfix] Implement idivfx functions in LLVM libc #133005

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

Merged
merged 28 commits into from
Apr 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b974968
feat: implement generic idivfx
krishna2803 Mar 25, 2025
f9b0de4
feat: implement idivr
krishna2803 Mar 25, 2025
ec355df
chore: update CMakeLists.txt
krishna2803 Mar 25, 2025
fc30ed0
chore: update entrypoints
krishna2803 Mar 25, 2025
6a3c052
chore: implement sanity check tests for idivr
krishna2803 Mar 25, 2025
6bcec01
fix: SIGFPE
krishna2803 Mar 25, 2025
078e558
fix: update test
krishna2803 Mar 25, 2025
7b54572
feat: implement idivlr
krishna2803 Mar 25, 2025
65eb2ea
feat: implement idivk
krishna2803 Mar 25, 2025
693ce40
feat: implement idivlk
krishna2803 Mar 25, 2025
e59067d
chore: update entrypoints
krishna2803 Mar 25, 2025
05ba8d3
chore: add more tests
krishna2803 Mar 25, 2025
c245ea5
fix: idivlk typo
krishna2803 Mar 25, 2025
85ee5ed
fix: idivlr typo
krishna2803 Mar 25, 2025
aebbcc7
feat: implement idivu{r,lr,k,lk}
krishna2803 Mar 25, 2025
276793b
chore: update entrypoints
krishna2803 Mar 25, 2025
3e3c403
fix: idivulk typo
krishna2803 Mar 25, 2025
b1145cf
fix: add cast to tests
krishna2803 Mar 25, 2025
d30de69
chore: add idiv{ur,uk,ulk,ulr} tests
krishna2803 Mar 25, 2025
cce1821
refactor: rename fixed_point::idivfx to fixed_point::idiv
krishna2803 Mar 25, 2025
dc7713c
chore: add type generic macros
krishna2803 Mar 25, 2025
c31a661
fix: fixed_point::div function for negative values
krishna2803 Mar 25, 2025
2d341ee
feat: improve and add more tests
krishna2803 Mar 25, 2025
44bb098
docs: update idivfx
krishna2803 Mar 25, 2025
01cacf5
revert: "chore: add type generic macros"
krishna2803 Mar 27, 2025
26baea9
chore: add gaurd for zero denominator
krishna2803 Mar 28, 2025
832669c
chore: update tests
krishna2803 Mar 28, 2025
04c1742
refactor: use proxy headers for signals
krishna2803 Apr 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions libc/config/baremetal/arm/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,14 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.countlsuhk
libc.src.stdfix.countlsuk
libc.src.stdfix.countlsulk
libc.src.stdfix.idivr
libc.src.stdfix.idivlr
libc.src.stdfix.idivk
libc.src.stdfix.idivlk
libc.src.stdfix.idivur
libc.src.stdfix.idivulr
libc.src.stdfix.idivuk
libc.src.stdfix.idivulk
)
endif()

Expand Down
8 changes: 8 additions & 0 deletions libc/config/baremetal/riscv/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,14 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.countlsuhk
libc.src.stdfix.countlsuk
libc.src.stdfix.countlsulk
libc.src.stdfix.idivr
libc.src.stdfix.idivlr
libc.src.stdfix.idivk
libc.src.stdfix.idivlk
libc.src.stdfix.idivur
libc.src.stdfix.idivulr
libc.src.stdfix.idivuk
libc.src.stdfix.idivulk
)
endif()

Expand Down
8 changes: 8 additions & 0 deletions libc/config/linux/riscv/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,14 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.countlsuhk
libc.src.stdfix.countlsuk
libc.src.stdfix.countlsulk
libc.src.stdfix.idivr
libc.src.stdfix.idivlr
libc.src.stdfix.idivk
libc.src.stdfix.idivulk
Copy link
Member

Choose a reason for hiding this comment

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

This looks duplicated, I think you mean libc.src.stdfix.idivlk

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sorry for the bug! i'll put up a patch

libc.src.stdfix.idivur
libc.src.stdfix.idivulr
libc.src.stdfix.idivuk
libc.src.stdfix.idivulk
)
endif()

Expand Down
8 changes: 8 additions & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,14 @@ if(LIBC_COMPILER_HAS_FIXED_POINT)
libc.src.stdfix.countlsuhk
libc.src.stdfix.countlsuk
libc.src.stdfix.countlsulk
libc.src.stdfix.idivr
libc.src.stdfix.idivlr
libc.src.stdfix.idivk
libc.src.stdfix.idivlk
libc.src.stdfix.idivur
libc.src.stdfix.idivulr
libc.src.stdfix.idivuk
libc.src.stdfix.idivulk
)
endif()

Expand Down
2 changes: 1 addition & 1 deletion libc/docs/headers/stdfix.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ The following functions are included in the ISO/IEC TR 18037:2008 standard.
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| divi\* | | | | | | | | | | | | |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| idiv\* | | | | | | | | | | | | |
| idiv\* | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
| muli | | | | | | | | | | | | |
+---------------+----------------+-------------+---------------+------------+----------------+-------------+----------------+-------------+---------------+------------+----------------+-------------+
Expand Down
64 changes: 64 additions & 0 deletions libc/include/stdfix.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,70 @@ functions:
arguments:
- type: unsigned long accum
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: idivr
standards:
- stdc_ext
return_type: int
arguments:
- type: fract
- type: fract
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: idivlr
standards:
- stdc_ext
return_type: long int
arguments:
- type: long fract
- type: long fract
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: idivk
standards:
- stdc_ext
return_type: int
arguments:
- type: accum
- type: accum
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: idivlk
standards:
- stdc_ext
return_type: long int
arguments:
- type: long accum
- type: long accum
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: idivur
standards:
- stdc_ext
return_type: unsigned int
arguments:
- type: unsigned fract
- type: unsigned fract
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: idivulr
standards:
- stdc_ext
return_type: unsigned long int
arguments:
- type: unsigned long fract
- type: unsigned long fract
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: idivuk
standards:
- stdc_ext
return_type: unsigned int
arguments:
- type: unsigned accum
- type: unsigned accum
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: idivulk
standards:
- stdc_ext
return_type: unsigned long int
arguments:
- type: unsigned long accum
- type: unsigned long accum
guard: LIBC_COMPILER_HAS_FIXED_POINT
- name: roundhk
standards:
- stdc_ext
Expand Down
1 change: 1 addition & 0 deletions libc/src/__support/fixed_point/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ add_header_library(
.fx_rep
libc.include.llvm-libc-macros.stdfix_macros
libc.src.__support.macros.attributes
libc.src.__support.macros.null_check
libc.src.__support.macros.optimization
libc.src.__support.CPP.type_traits
libc.src.__support.CPP.bit
Expand Down
23 changes: 23 additions & 0 deletions libc/src/__support/fixed_point/fx_bits.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "src/__support/CPP/type_traits.h"
#include "src/__support/macros/attributes.h" // LIBC_INLINE
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL
#include "src/__support/macros/null_check.h" // LIBC_CRASH_ON_VALUE
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include "src/__support/math_extras.h"

Expand Down Expand Up @@ -201,6 +202,28 @@ bitsfx(T f) {
return cpp::bit_cast<XType, T>(f);
}

// divide the two fixed-point types and return an integer result
template <typename T, typename XType>
LIBC_INLINE constexpr cpp::enable_if_t<cpp::is_fixed_point_v<T>, XType>
idiv(T x, T y) {
using FXBits = FXBits<T>;
using FXRep = FXRep<T>;
using CompType = typename FXRep::CompType;

// If the value of the second operand of the / operator is zero, the
// behavior is undefined. Ref: ISO/IEC TR 18037:2008(E) p.g. 16
LIBC_CRASH_ON_VALUE(y, FXRep::ZERO());

CompType x_comp = static_cast<CompType>(FXBits(x).get_bits());
CompType y_comp = static_cast<CompType>(FXBits(y).get_bits());

// If an integer result of one of these functions overflows, the behavior is
// undefined. Ref: ISO/IEC TR 18037:2008(E) p.g. 16
CompType result = x_comp / y_comp;

return static_cast<XType>(result);
}

} // namespace fixed_point
} // namespace LIBC_NAMESPACE_DECL

Expand Down
9 changes: 9 additions & 0 deletions libc/src/__support/macros/null_check.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,19 @@
if (LIBC_UNLIKELY((ptr) == nullptr)) \
__builtin_trap(); \
} while (0)
#define LIBC_CRASH_ON_VALUE(var, value) \
do { \
if (LIBC_UNLIKELY((var) == (value))) \
__builtin_trap(); \
} while (0)

Comment on lines +22 to +27
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure this is necessary. Can you explain why this would be more useful than LIBC_ASSERT which provides better diagnostics for runtime assertions?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For this, I just followed what tue suggested. Since divide by 0 is UB as mentioned in the standard, we thought of making this macro, similar to LIBC_CRASH_ON_NULLPTR. Should I change it to LIBC_ASSERT for this case?

Copy link
Contributor

Choose a reason for hiding this comment

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

This is an option for hardening against UB, and it needs a different macro from LIBC_ASSERT because assertions will be omitted for non-debug build.

#else
#define LIBC_CRASH_ON_NULLPTR(ptr) \
do { \
} while (0)
#define LIBC_CRASH_ON_VALUE(var, value) \
do { \
} while (0)
#endif

#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_NULL_CHECK_H
14 changes: 14 additions & 0 deletions libc/src/stdfix/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,20 @@ foreach(suffix IN ITEMS hr r lr hk k lk uhr ur ulr uhk uk ulk)
)
endforeach()

foreach(suffix IN ITEMS r lr k lk ur ulr uk ulk)
add_entrypoint_object(
idiv${suffix}
HDRS
idiv${suffix}.h
SRCS
idiv${suffix}.cpp
COMPILE_OPTIONS
${libc_opt_high_flag}
DEPENDS
libc.src.__support.fixed_point.fx_bits
)
endforeach()

add_entrypoint_object(
uhksqrtus
HDRS
Expand Down
21 changes: 21 additions & 0 deletions libc/src/stdfix/idivk.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation of idivk 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 "idivk.h"
#include "include/llvm-libc-macros/stdfix-macros.h" // accum
#include "src/__support/common.h" // LLVM_LIBC_FUNCTION
#include "src/__support/fixed_point/fx_bits.h" // fixed_point
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, idivk, (accum x, accum y)) {
return fixed_point::idiv<accum, int>(x, y);
}

} // namespace LIBC_NAMESPACE_DECL
21 changes: 21 additions & 0 deletions libc/src/stdfix/idivk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation header for idivk ------------------------*- 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_IDIVK_H
#define LLVM_LIBC_SRC_STDFIX_IDIVK_H

#include "include/llvm-libc-macros/stdfix-macros.h" // accum
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL

namespace LIBC_NAMESPACE_DECL {

int idivk(accum x, accum y);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_STDFIX_IDIVK_H
21 changes: 21 additions & 0 deletions libc/src/stdfix/idivlk.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation of idivlk 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 "idivlk.h"
#include "include/llvm-libc-macros/stdfix-macros.h" // long accum
#include "src/__support/common.h" // LLVM_LIBC_FUNCTION
#include "src/__support/fixed_point/fx_bits.h" // fixed_point
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(long int, idivlk, (long accum x, long accum y)) {
return fixed_point::idiv<long accum, long int>(x, y);
}

} // namespace LIBC_NAMESPACE_DECL
21 changes: 21 additions & 0 deletions libc/src/stdfix/idivlk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation header for idivlk -----------------------*- 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_IDIVLK_H
#define LLVM_LIBC_SRC_STDFIX_IDIVLK_H

#include "include/llvm-libc-macros/stdfix-macros.h" // long accum
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL

namespace LIBC_NAMESPACE_DECL {

long int idivlk(long accum x, long accum y);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_STDFIX_IDIVLK_H
21 changes: 21 additions & 0 deletions libc/src/stdfix/idivlr.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation of idivlr 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 "idivlr.h"
#include "include/llvm-libc-macros/stdfix-macros.h" // long fract
#include "src/__support/common.h" // LLVM_LIBC_FUNCTION
#include "src/__support/fixed_point/fx_bits.h" // fixed_point
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(long int, idivlr, (long fract x, long fract y)) {
return fixed_point::idiv<long fract, long int>(x, y);
}

} // namespace LIBC_NAMESPACE_DECL
21 changes: 21 additions & 0 deletions libc/src/stdfix/idivlr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation header for idivlr -----------------------*- 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_IDIVLR_H
#define LLVM_LIBC_SRC_STDFIX_IDIVLR_H

#include "include/llvm-libc-macros/stdfix-macros.h" // long fract
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL

namespace LIBC_NAMESPACE_DECL {

long int idivlr(long fract x, long fract y);

} // namespace LIBC_NAMESPACE_DECL

#endif // LLVM_LIBC_SRC_STDFIX_IDIVLR_H
21 changes: 21 additions & 0 deletions libc/src/stdfix/idivr.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation of idivr 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 "idivr.h"
#include "include/llvm-libc-macros/stdfix-macros.h" // fract
#include "src/__support/common.h" // LLVM_LIBC_FUNCTION
#include "src/__support/fixed_point/fx_bits.h" // fixed_point
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, idivr, (fract x, fract y)) {
return fixed_point::idiv<fract, int>(x, y);
}

} // namespace LIBC_NAMESPACE_DECL
Loading
Loading