Type punning in block_ldlt_internal::find_maxloc
is undefined behaviour
#154
Labels
block_ldlt_internal::find_maxloc
is undefined behaviour
#154
A union is introduced in
spral/src/ssids/cpu/kernels/block_ldlt.hxx
Lines 104 to 109 in b89ab7b
int
to.i
and "read it as double" from.d
, for example:spral/src/ssids/cpu/kernels/block_ldlt.hxx
Lines 114 to 116 in b89ab7b
This is commonly done for type punning and I believe this was allowed in C and happens to work on most platforms even in C++. But it is undefined behaviour in C++ (https://www.youtube.com/watch?v=_qzMpk-22cc&t=570s). In general, the modern way to do this in C++20 is
std::bit_cast
. Probably wanting to support earlier standards, one could write their own version with that possible implementation usingstd::memcpy
.In this specific case, it seems strange to me that any type punning is done at all though. If we have AVX, couldn't we just load the int values into the AVX register using
_mm256_set1_epi32
, do the operations and then extract them with_mm256_extract_epi32
? Otherwise without AVX,SimdVec
just turns into a plaindouble
, which makes its use for the row and column indices inblock_ldlt_internal::find_maxloc
very akward. For no real reason theint
values are basically type-punned to unnecessarily largerdouble
type as which swaps are done, only to then be punned back intoint
.The text was updated successfully, but these errors were encountered: