[libc-commits] [libc] 495c57f - [libc] Make add_with_carry and sub_with_borrow constexpr. (#81898)
via libc-commits
libc-commits at lists.llvm.org
Thu Feb 15 11:00:29 PST 2024
Author: lntue
Date: 2024-02-15T14:00:25-05:00
New Revision: 495c57ffedfedc98751f07295b7b6ce95bf3eb9c
URL: https://github.com/llvm/llvm-project/commit/495c57ffedfedc98751f07295b7b6ce95bf3eb9c
DIFF: https://github.com/llvm/llvm-project/commit/495c57ffedfedc98751f07295b7b6ce95bf3eb9c.diff
LOG: [libc] Make add_with_carry and sub_with_borrow constexpr. (#81898)
Added:
Modified:
libc/src/__support/math_extras.h
Removed:
################################################################################
diff --git a/libc/src/__support/math_extras.h b/libc/src/__support/math_extras.h
index 8ec30396ffdb46..ae367994706c0f 100644
--- a/libc/src/__support/math_extras.h
+++ b/libc/src/__support/math_extras.h
@@ -56,11 +56,9 @@ add_with_carry_const(T a, T b, T carry_in) {
return {sum, carry_out};
}
-// This version is not always valid for constepxr because it's overriden below
-// if builtins are available.
template <typename T>
-LIBC_INLINE cpp::enable_if_t<cpp::is_integral_v<T> && cpp::is_unsigned_v<T>,
- SumCarry<T>>
+LIBC_INLINE constexpr cpp::enable_if_t<
+ cpp::is_integral_v<T> && cpp::is_unsigned_v<T>, SumCarry<T>>
add_with_carry(T a, T b, T carry_in) {
return add_with_carry_const<T>(a, b, carry_in);
}
@@ -69,48 +67,68 @@ add_with_carry(T a, T b, T carry_in) {
// https://clang.llvm.org/docs/LanguageExtensions.html#multiprecision-arithmetic-builtins
template <>
-LIBC_INLINE SumCarry<unsigned char>
+LIBC_INLINE constexpr SumCarry<unsigned char>
add_with_carry<unsigned char>(unsigned char a, unsigned char b,
unsigned char carry_in) {
- SumCarry<unsigned char> result{0, 0};
- result.sum = __builtin_addcb(a, b, carry_in, &result.carry);
- return result;
+ if (__builtin_is_constant_evaluated()) {
+ return add_with_carry_const<unsigned char>(a, b, carry_in);
+ } else {
+ SumCarry<unsigned char> result{0, 0};
+ result.sum = __builtin_addcb(a, b, carry_in, &result.carry);
+ return result;
+ }
}
template <>
-LIBC_INLINE SumCarry<unsigned short>
+LIBC_INLINE constexpr SumCarry<unsigned short>
add_with_carry<unsigned short>(unsigned short a, unsigned short b,
unsigned short carry_in) {
- SumCarry<unsigned short> result{0, 0};
- result.sum = __builtin_addcs(a, b, carry_in, &result.carry);
- return result;
+ if (__builtin_is_constant_evaluated()) {
+ return add_with_carry_const<unsigned short>(a, b, carry_in);
+ } else {
+ SumCarry<unsigned short> result{0, 0};
+ result.sum = __builtin_addcs(a, b, carry_in, &result.carry);
+ return result;
+ }
}
template <>
-LIBC_INLINE SumCarry<unsigned int>
+LIBC_INLINE constexpr SumCarry<unsigned int>
add_with_carry<unsigned int>(unsigned int a, unsigned int b,
unsigned int carry_in) {
- SumCarry<unsigned int> result{0, 0};
- result.sum = __builtin_addc(a, b, carry_in, &result.carry);
- return result;
+ if (__builtin_is_constant_evaluated()) {
+ return add_with_carry_const<unsigned int>(a, b, carry_in);
+ } else {
+ SumCarry<unsigned int> result{0, 0};
+ result.sum = __builtin_addc(a, b, carry_in, &result.carry);
+ return result;
+ }
}
template <>
-LIBC_INLINE SumCarry<unsigned long>
+LIBC_INLINE constexpr SumCarry<unsigned long>
add_with_carry<unsigned long>(unsigned long a, unsigned long b,
unsigned long carry_in) {
- SumCarry<unsigned long> result{0, 0};
- result.sum = __builtin_addcl(a, b, carry_in, &result.carry);
- return result;
+ if (__builtin_is_constant_evaluated()) {
+ return add_with_carry_const<unsigned long>(a, b, carry_in);
+ } else {
+ SumCarry<unsigned long> result{0, 0};
+ result.sum = __builtin_addcl(a, b, carry_in, &result.carry);
+ return result;
+ }
}
template <>
-LIBC_INLINE SumCarry<unsigned long long>
+LIBC_INLINE constexpr SumCarry<unsigned long long>
add_with_carry<unsigned long long>(unsigned long long a, unsigned long long b,
unsigned long long carry_in) {
- SumCarry<unsigned long long> result{0, 0};
- result.sum = __builtin_addcll(a, b, carry_in, &result.carry);
- return result;
+ if (__builtin_is_constant_evaluated()) {
+ return add_with_carry_const<unsigned long long>(a, b, carry_in);
+ } else {
+ SumCarry<unsigned long long> result{0, 0};
+ result.sum = __builtin_addcll(a, b, carry_in, &result.carry);
+ return result;
+ }
}
#endif // LIBC_HAS_BUILTIN(__builtin_addc)
@@ -135,8 +153,8 @@ sub_with_borrow_const(T a, T b, T borrow_in) {
// This version is not always valid for constepxr because it's overriden below
// if builtins are available.
template <typename T>
-LIBC_INLINE cpp::enable_if_t<cpp::is_integral_v<T> && cpp::is_unsigned_v<T>,
- DiffBorrow<T>>
+LIBC_INLINE constexpr cpp::enable_if_t<
+ cpp::is_integral_v<T> && cpp::is_unsigned_v<T>, DiffBorrow<T>>
sub_with_borrow(T a, T b, T borrow_in) {
return sub_with_borrow_const<T>(a, b, borrow_in);
}
@@ -145,48 +163,68 @@ sub_with_borrow(T a, T b, T borrow_in) {
// https://clang.llvm.org/docs/LanguageExtensions.html#multiprecision-arithmetic-builtins
template <>
-LIBC_INLINE DiffBorrow<unsigned char>
+LIBC_INLINE constexpr DiffBorrow<unsigned char>
sub_with_borrow<unsigned char>(unsigned char a, unsigned char b,
unsigned char borrow_in) {
- DiffBorrow<unsigned char> result{0, 0};
- result.
diff = __builtin_subcb(a, b, borrow_in, &result.borrow);
- return result;
+ if (__builtin_is_constant_evaluated()) {
+ return sub_with_borrow_const<unsigned char>(a, b, borrow_in);
+ } else {
+ DiffBorrow<unsigned char> result{0, 0};
+ result.
diff = __builtin_subcb(a, b, borrow_in, &result.borrow);
+ return result;
+ }
}
template <>
-LIBC_INLINE DiffBorrow<unsigned short>
+LIBC_INLINE constexpr DiffBorrow<unsigned short>
sub_with_borrow<unsigned short>(unsigned short a, unsigned short b,
unsigned short borrow_in) {
- DiffBorrow<unsigned short> result{0, 0};
- result.
diff = __builtin_subcs(a, b, borrow_in, &result.borrow);
- return result;
+ if (__builtin_is_constant_evaluated()) {
+ return sub_with_borrow_const<unsigned short>(a, b, borrow_in);
+ } else {
+ DiffBorrow<unsigned short> result{0, 0};
+ result.
diff = __builtin_subcs(a, b, borrow_in, &result.borrow);
+ return result;
+ }
}
template <>
-LIBC_INLINE DiffBorrow<unsigned int>
+LIBC_INLINE constexpr DiffBorrow<unsigned int>
sub_with_borrow<unsigned int>(unsigned int a, unsigned int b,
unsigned int borrow_in) {
- DiffBorrow<unsigned int> result{0, 0};
- result.
diff = __builtin_subc(a, b, borrow_in, &result.borrow);
- return result;
+ if (__builtin_is_constant_evaluated()) {
+ return sub_with_borrow_const<unsigned int>(a, b, borrow_in);
+ } else {
+ DiffBorrow<unsigned int> result{0, 0};
+ result.
diff = __builtin_subc(a, b, borrow_in, &result.borrow);
+ return result;
+ }
}
template <>
-LIBC_INLINE DiffBorrow<unsigned long>
+LIBC_INLINE constexpr DiffBorrow<unsigned long>
sub_with_borrow<unsigned long>(unsigned long a, unsigned long b,
unsigned long borrow_in) {
- DiffBorrow<unsigned long> result{0, 0};
- result.
diff = __builtin_subcl(a, b, borrow_in, &result.borrow);
- return result;
+ if (__builtin_is_constant_evaluated()) {
+ return sub_with_borrow_const<unsigned long>(a, b, borrow_in);
+ } else {
+ DiffBorrow<unsigned long> result{0, 0};
+ result.
diff = __builtin_subcl(a, b, borrow_in, &result.borrow);
+ return result;
+ }
}
template <>
-LIBC_INLINE DiffBorrow<unsigned long long>
+LIBC_INLINE constexpr DiffBorrow<unsigned long long>
sub_with_borrow<unsigned long long>(unsigned long long a, unsigned long long b,
unsigned long long borrow_in) {
- DiffBorrow<unsigned long long> result{0, 0};
- result.
diff = __builtin_subcll(a, b, borrow_in, &result.borrow);
- return result;
+ if (__builtin_is_constant_evaluated()) {
+ return sub_with_borrow_const<unsigned long long>(a, b, borrow_in);
+ } else {
+ DiffBorrow<unsigned long long> result{0, 0};
+ result.
diff = __builtin_subcll(a, b, borrow_in, &result.borrow);
+ return result;
+ }
}
#endif // LIBC_HAS_BUILTIN(__builtin_subc)
More information about the libc-commits
mailing list