diff --git a/src/Functions/if.cpp b/src/Functions/if.cpp index fba50385923..18ba75cbd7e 100644 --- a/src/Functions/if.cpp +++ b/src/Functions/if.cpp @@ -25,8 +25,6 @@ #include #include -#pragma clang diagnostic ignored "-Wundefined-reinterpret-cast" - namespace DB { namespace ErrorCodes @@ -59,7 +57,11 @@ concept is_native_int_or_decimal_v auto mask = static_cast(static_cast(vc) - 1); \ auto new_a = static_cast(va); \ auto new_b = static_cast(vb); \ - auto tmp = (~mask & (*reinterpret_cast(&new_a))) | (mask & (*reinterpret_cast(&new_b))); \ + UIntType uint_a; \ + std::memcpy(&uint_a, &new_a, sizeof(UIntType)); \ + UIntType uint_b; \ + std::memcpy(&uint_b, &new_b, sizeof(UIntType)); \ + UIntType tmp = (~mask & uint_a) | (mask & uint_b); \ (vr) = *(reinterpret_cast(&tmp)); template @@ -220,12 +222,18 @@ template (a) : static_cast(b); + /// + /// Therefore, we manually optimize it by avoiding branch miss when ResultType is Int8. Other types like (U)Int128|256 or Decimal128/256 also benefit from this optimization. if constexpr (std::is_same_v || is_over_big_int) { alignas(64) const ResultType ab[2] = {static_cast(a), static_cast(b)}; for (size_t i = 0; i < size; ++i) { - /// Introduce memory access to avoid branch miss res[i] = ab[!cond[i]]; } }