Files
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

174 lines
7.1 KiB
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
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// <utility>
// cmp_equal, cmp_not_equal, cmp_less, cmp_less_equal, cmp_greater,
// cmp_greater_equal, in_range applied to _BitInt(N).
//
// Exercises the four implementation branches of cmp_less/cmp_equal:
// 1. same-signedness shortcut (__t < __u)
// 2. both promote to int (branch via int)
// 3. both promote to long long (branch via long long)
// 4. fallback using make_unsigned_t (wider than long long)
//
// _BitInt widths chosen to land in each branch:
// - _BitInt(7) sizeof==1, < sizeof(int) -> branch 2
// - _BitInt(13) sizeof==2 -> branch 2
// - _BitInt(32) sizeof==4 == sizeof(int) -> branch 2 (signed) / 3 (unsigned)
// - _BitInt(33) sizeof==8 -> branch 3
// - _BitInt(63) sizeof==8 -> branch 3
// - _BitInt(65) sizeof==16 -> branch 4
// - _BitInt(128) sizeof==16 -> branch 4
// - _BitInt(200) sizeof==32 (requires __BITINT_MAXWIDTH__ >= 200)
// -> branch 4
#include <cassert>
#include <limits>
#include <utility>
#include "test_macros.h"
#if TEST_HAS_EXTENSION(bit_int)
template <class T, class U>
constexpr bool test_same_sign() {
// Branch 1: same signedness. Trivial equality/ordering.
static_assert(std::cmp_equal(T(0), U(0)));
static_assert(std::cmp_equal(T(42), U(42)));
static_assert(!std::cmp_equal(T(0), U(1)));
static_assert(std::cmp_less(T(0), U(1)));
static_assert(!std::cmp_less(T(1), U(0)));
static_assert(std::cmp_less_equal(T(1), U(1)));
static_assert(std::cmp_greater_equal(T(1), U(1)));
static_assert(std::cmp_not_equal(T(0), U(1)));
return true;
}
template <class S, class U>
constexpr bool test_mixed_sign() {
// Signed vs unsigned of the SAME width: negative signed values must
// compare less than any unsigned value, regardless of the promotion
// branch chosen.
constexpr auto s_min = std::numeric_limits<S>::min();
constexpr auto u_max = std::numeric_limits<U>::max();
static_assert(std::cmp_less(S(-1), U(0)));
static_assert(!std::cmp_equal(S(-1), U(-1))); // U(-1) wraps to u_max
static_assert(std::cmp_less(s_min, U(0)));
static_assert(std::cmp_greater(u_max, S(0)));
static_assert(std::cmp_greater(u_max, s_min));
static_assert(std::cmp_less_equal(S(-1), U(0)));
static_assert(std::cmp_greater_equal(U(0), S(-1)));
// Equal-value mixed-sign: a non-negative signed value must compare
// equal to the corresponding unsigned value.
static_assert(std::cmp_equal(S(7), U(7)));
static_assert(std::cmp_equal(U(7), S(7)));
return true;
}
template <class S, class U>
constexpr bool test_in_range() {
// in_range relies on numeric_limits<_Tp>::min/max, which requires
// the digits10 fix (#193002) to be correct for odd _BitInt widths.
// Signed target: value in range.
static_assert(std::in_range<S>(S(0)));
static_assert(std::in_range<S>(std::numeric_limits<S>::max()));
static_assert(std::in_range<S>(std::numeric_limits<S>::min()));
// Signed target: value out of range via a wider unsigned source.
static_assert(!std::in_range<S>(std::numeric_limits<U>::max()));
// Unsigned target: negative signed value is out of range.
static_assert(!std::in_range<U>(S(-1)));
// Unsigned target: zero is in range.
static_assert(std::in_range<U>(S(0)));
static_assert(std::in_range<U>(std::numeric_limits<U>::max()));
return true;
}
constexpr bool test() {
// Branch 2 territory (sizeof <= sizeof(int)).
test_same_sign<_BitInt(7), _BitInt(7)>();
test_same_sign<unsigned _BitInt(7), unsigned _BitInt(7)>();
test_same_sign<_BitInt(13), _BitInt(13)>();
test_mixed_sign<_BitInt(7), unsigned _BitInt(7)>();
test_mixed_sign<_BitInt(13), unsigned _BitInt(13)>();
test_in_range<_BitInt(7), unsigned _BitInt(7)>();
test_in_range<_BitInt(13), unsigned _BitInt(13)>();
// Equal-sizeof-as-int boundary: signed _BitInt(32) can promote to int,
// unsigned _BitInt(32) cannot (would lose the high bit), so it falls
// into branch 3.
test_same_sign<_BitInt(32), _BitInt(32)>();
test_same_sign<unsigned _BitInt(32), unsigned _BitInt(32)>();
test_mixed_sign<_BitInt(32), unsigned _BitInt(32)>();
test_in_range<_BitInt(32), unsigned _BitInt(32)>();
// Branch 3 territory (sizeof <= sizeof(long long)).
test_same_sign<_BitInt(33), _BitInt(33)>();
test_same_sign<_BitInt(63), _BitInt(63)>();
test_same_sign<unsigned _BitInt(63), unsigned _BitInt(63)>();
test_mixed_sign<_BitInt(33), unsigned _BitInt(33)>();
test_mixed_sign<_BitInt(63), unsigned _BitInt(63)>();
test_in_range<_BitInt(33), unsigned _BitInt(33)>();
test_in_range<_BitInt(63), unsigned _BitInt(63)>();
// Equal-sizeof-as-long-long boundary: _BitInt(64) signed promotes,
// unsigned _BitInt(64) does not, so the mixed-sign case lands in
// branch 4.
test_same_sign<_BitInt(64), _BitInt(64)>();
test_same_sign<unsigned _BitInt(64), unsigned _BitInt(64)>();
test_mixed_sign<_BitInt(64), unsigned _BitInt(64)>();
test_in_range<_BitInt(64), unsigned _BitInt(64)>();
# if __BITINT_MAXWIDTH__ >= 128
// Branch 4 territory (sizeof > sizeof(long long)).
test_same_sign<_BitInt(65), _BitInt(65)>();
test_same_sign<_BitInt(128), _BitInt(128)>();
test_same_sign<unsigned _BitInt(128), unsigned _BitInt(128)>();
test_mixed_sign<_BitInt(65), unsigned _BitInt(65)>();
test_mixed_sign<_BitInt(128), unsigned _BitInt(128)>();
test_in_range<_BitInt(65), unsigned _BitInt(65)>();
test_in_range<_BitInt(128), unsigned _BitInt(128)>();
# endif
# if __BITINT_MAXWIDTH__ >= 200
// Beyond __int128: verifies make_unsigned_t<_BitInt(N)> works on the
// fallback path for widths with no builtin mapping.
test_same_sign<_BitInt(200), _BitInt(200)>();
test_same_sign<unsigned _BitInt(200), unsigned _BitInt(200)>();
test_mixed_sign<_BitInt(200), unsigned _BitInt(200)>();
test_in_range<_BitInt(200), unsigned _BitInt(200)>();
# endif
// Cross-width: narrow signed _BitInt vs wide unsigned builtin.
// Negative source must be reported as less than any non-negative target.
static_assert(std::cmp_less(_BitInt(7)(-1), 0ull));
static_assert(std::cmp_less(_BitInt(13)(-1), 0u));
static_assert(std::cmp_less(_BitInt(63)(-1), 0ull));
// Cross-type round-trip equality.
static_assert(std::cmp_equal(_BitInt(13)(42), 42));
static_assert(std::cmp_equal(42, _BitInt(13)(42)));
static_assert(std::cmp_equal(unsigned _BitInt(13)(42), 42u));
return true;
}
#endif // TEST_HAS_EXTENSION(bit_int)
int main(int, char**) {
#if TEST_HAS_EXTENSION(bit_int)
test();
static_assert(test());
#endif
return 0;
}