Merge branch 'master' into i

This commit is contained in:
Elad 2026-07-01 12:12:36 +03:00 committed by GitHub
commit 8abdab5f28
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -3694,11 +3694,22 @@ public:
// Infinite-precision shift left
template <typename T, typename U, typename CT = llvm_common_t<T, U>>
auto inf_shl(T&& a, U&& b)
value_t<CT> inf_shl(T&& a, U&& b)
{
static constexpr u32 esz = llvm_value_t<CT>::esize;
return expr(select(b < esz, a << b, splat<CT>(0)), [](llvm::Value*& value, llvm::Module* _m) -> llvm_match_tuple<T, U>
#ifdef ARCH_ARM64
auto sh = eval(std::forward<U>(b));
auto k = get_known_bits(sh);
const auto max_shift = llvm::APInt(k.Zero.getBitWidth(), esz * 2 - 1);
if ((k.Zero | max_shift).isAllOnes())
{
return ushl(std::forward<T>(a), sh);
}
#endif
auto result = expr(select(b < esz, a << b, splat<CT>(0)), [](llvm::Value*& value, llvm::Module* _m) -> llvm_match_tuple<T, U>
{
static const auto M = match<CT>();
@ -3716,15 +3727,28 @@ public:
value = nullptr;
return {};
});
return eval(result);
}
// Infinite-precision logical shift right (unsigned)
template <typename T, typename U, typename CT = llvm_common_t<T, U>>
auto inf_lshr(T&& a, U&& b)
value_t<CT> inf_lshr(T&& a, U&& b)
{
static constexpr u32 esz = llvm_value_t<CT>::esize;
return expr(select(b < esz, a >> b, splat<CT>(0)), [](llvm::Value*& value, llvm::Module* _m) -> llvm_match_tuple<T, U>
#ifdef ARCH_ARM64
auto sh = eval(std::forward<U>(b));
auto k = get_known_bits(sh);
const auto max_shift = llvm::APInt(k.Zero.getBitWidth(), esz * 2 - 1);
if ((k.Zero | max_shift).isAllOnes())
{
return ushl(std::forward<T>(a), -sh);
}
#endif
auto result = expr(select(b < esz, a >> b, splat<CT>(0)), [](llvm::Value*& value, llvm::Module* _m) -> llvm_match_tuple<T, U>
{
static const auto M = match<CT>();
@ -3742,6 +3766,8 @@ public:
value = nullptr;
return {};
});
return eval(result);
}
// Infinite-precision arithmetic shift right (signed)
@ -4021,6 +4047,18 @@ template <typename T1, typename T2, typename T3>
return sve_mlal<u32[4]>(llvm::Intrinsic::aarch64_sve_umlalt, acc, a, b);
}
template <typename T1, typename T2, typename T = llvm_common_t<T1, T2>>
value_t<T> ushl(T1 a, T2 b)
{
value_t<T> result;
const auto data0 = a.eval(m_ir);
const auto data1 = b.eval(m_ir);
result.value = m_ir->CreateCall(get_intrinsic<T>(llvm::Intrinsic::aarch64_neon_ushl), {data0, data1});
return result;
}
template <typename T1, typename T2>
auto addp(T1 a, T2 b)
{