Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
38 changes: 38 additions & 0 deletions .github/workflows/sanitizer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: sanitizer
on: [push, pull_request]
concurrency:
group: ${{ github.workflow }}-${{ github.job }}-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash -l {0}
jobs:
build:
runs-on: ubuntu-latest
name: 'sanitizer - ${{ matrix.sanitizer }}'
strategy:
matrix:
sanitizer:
- address
- undefined
steps:
- name: Checkout xsimd
uses: actions/checkout@v3
- name: Configure build
run: |
mkdir _build
cd _build
cmake .. -DBUILD_TESTS=ON \
-DBUILD_BENCHMARK=ON \
-DBUILD_EXAMPLES=ON \
-DDOWNLOAD_DOCTEST=ON \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_CXX_FLAGS='-fsanitize=${{ matrix.sanitizer }}' \
-G Ninja
- name: Build
run: ninja -C _build
- name: Test
run: |
cd _build/test
./test_xsimd
8 changes: 7 additions & 1 deletion include/xsimd/arch/common/xsimd_common_math.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ namespace xsimd
{
return fast_cast(self, out, A {});
}
#if defined(__clang__) || __GNUC__
template <class A, class T_out, class T_in>
XSIMD_INLINE batch<T_out, A> batch_cast(batch<T_in, A> const& self, batch<T_out, A> const&, requires_arch<common>, with_slow_conversion) noexcept
__attribute__((no_sanitize("undefined")));
#endif
template <class A, class T_out, class T_in>
XSIMD_INLINE batch<T_out, A> batch_cast(batch<T_in, A> const& self, batch<T_out, A> const&, requires_arch<common>, with_slow_conversion) noexcept
{
Expand All @@ -126,7 +131,8 @@ namespace xsimd
alignas(A::alignment()) T_in buffer_in[batch_type_in::size];
alignas(A::alignment()) T_out buffer_out[batch_type_out::size];
self.store_aligned(&buffer_in[0]);
std::copy(std::begin(buffer_in), std::end(buffer_in), std::begin(buffer_out));
for (size_t i = 0; i < batch_type_in::size; ++i)
buffer_out[i] = static_cast<T_out>(buffer_in[i]);
return batch_type_out::load_aligned(buffer_out);
}

Expand Down
4 changes: 2 additions & 2 deletions test/test_batch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -879,12 +879,12 @@ struct batch_test
for (size_t i = 0; i < size; ++i)
{
bool negative_lhs = std::is_signed<T>::value && (i % 2 == 1);
lhs[i] = value_type(i) * (negative_lhs ? -10 : 10);
lhs[i] = value_type(i) * (negative_lhs ? -3 : 3);
if (lhs[i] == value_type(0))
{
lhs[i] += value_type(1);
}
rhs[i] = value_type(i) + value_type(4);
rhs[i] = value_type(i) + value_type(2);
}
scalar = value_type(3);
}
Expand Down
15 changes: 11 additions & 4 deletions test/test_batch_cast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace detail
is_convertible(T_in value)
{
int64_t signed_value = static_cast<int64_t>(value);
return signed_value <= static_cast<int64_t>(std::numeric_limits<T_out>::max()) && signed_value >= static_cast<int64_t>(std::numeric_limits<T_out>::lowest());
return signed_value < static_cast<int64_t>(std::numeric_limits<T_out>::max()) && signed_value >= static_cast<int64_t>(std::numeric_limits<T_out>::lowest());
}

template <class T_out, class T_in>
Expand All @@ -43,7 +43,7 @@ namespace detail
inline typename std::enable_if<std::is_floating_point<T_in>::value && std::is_integral<T_out>::value, bool>::type
is_convertible(T_in value)
{
return value <= static_cast<T_in>(std::numeric_limits<T_out>::max()) && value >= static_cast<T_in>(std::numeric_limits<T_out>::lowest());
return value < static_cast<T_in>(std::numeric_limits<T_out>::max()) && value >= static_cast<T_in>(std::numeric_limits<T_out>::lowest());
}

template <class T_out, class T_in>
Expand Down Expand Up @@ -328,12 +328,19 @@ struct batch_cast_test
using B_common_in = xsimd::batch<T_in>;
using B_common_out = xsimd::batch<T_out>;

T_in in_test_value = static_cast<T_in>(test_value);
auto clamp = [](T v)
{
return static_cast<T_in>(xsimd::min(v, static_cast<T>(std::numeric_limits<T_in>::max() - 1)));
};

T_in in_test_value = clamp(test_value);
if (detail::is_convertible<T_out>(in_test_value))
{
B_common_out res = xsimd::batch_cast<T_out>(B_common_in(in_test_value));
INFO(name);
CHECK_SCALAR_EQ(res.get(0), static_cast<T_out>(in_test_value));
T_out scalar_ref = static_cast<T_out>(in_test_value);
T_out scalar_res = res.get(0);
CHECK_SCALAR_EQ(scalar_ref, scalar_res);
}
}

Expand Down
8 changes: 4 additions & 4 deletions test/test_batch_int.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,8 @@ struct batch_int_test
array_type expected;
std::transform(lhs.cbegin(), lhs.cend(), expected.begin(),
[nb_sh](const value_type& v)
{ return v << nb_sh; });
batch_type res = batch_lhs() << nb_sh;
{ return xsimd::abs(v) << nb_sh; });
batch_type res = abs(batch_lhs()) << nb_sh;
INFO("batch << scalar");
CHECK_BATCH_EQ(res, expected);
}
Expand All @@ -249,8 +249,8 @@ struct batch_int_test
array_type expected;
std::transform(lhs.cbegin(), lhs.cend(), shift.cbegin(), expected.begin(),
[](const value_type& l, const value_type& r)
{ return l << r; });
batch_type res = batch_lhs() << batch_shift();
{ return xsimd::abs(l) << r; });
batch_type res = abs(batch_lhs()) << batch_shift();
INFO("batch << batch");
CHECK_BATCH_EQ(res, expected);
}
Expand Down
4 changes: 2 additions & 2 deletions test/test_power.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ struct power_test
for (size_t i = 0; i < nb_input; ++i)
{
zero_input[i] = 0;
lhs_input[i] = value_type(i) / 4 + value_type(1.2) * std::sqrt(value_type(i + 0.25));
lhs_input[i] = value_type(i / 4 + 1.2 * std::sqrt(i + 0.25));
zlhs_input[i] = lhs_input[i] * (i % 2);
rhs_input[i] = value_type(10.2) / (i + 2) + value_type(0.25);
rhs_input[i] = value_type(10.2 / (i + 2) + 0.25);
}

expected.resize(nb_input);
Expand Down
8 changes: 6 additions & 2 deletions test/test_select.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,14 @@ struct select_test
nb_input = size * 10000;
lhs_input.resize(nb_input);
rhs_input.resize(nb_input);
auto clamp = [](double v)
{
return static_cast<value_type>(std::min(v, static_cast<double>(std::numeric_limits<value_type>::max())));
};
for (size_t i = 0; i < nb_input; ++i)
{
lhs_input[i] = value_type(i) / 4 + value_type(1.2) * std::sqrt(value_type(i + 0.25));
rhs_input[i] = value_type(10.2) / (i + 2) + value_type(0.25);
lhs_input[i] = clamp(i / 4 + 1.2 * std::sqrt(i + 0.25));
rhs_input[i] = clamp(10.2 / (i + 2) + 0.25);
}
expected.resize(nb_input);
res.resize(nb_input);
Expand Down
Loading