enable modulo jit

This commit is contained in:
taiyang-li 2024-10-16 16:01:19 +08:00
parent d06b8666b4
commit 9df69dc6c2
2 changed files with 53 additions and 15 deletions

View File

@ -204,6 +204,38 @@ struct ResultOfIf
std::conditional_t<!is_decimal<A> && !is_decimal<B>,
ConstructedType, Error>>>;
};
/** Type casting for `modulo` function:
* UInt<x>, UInt<y> -> UInt<max(x,y)>
* Int<x>, Int<y> -> Int<max(x,y)>
* UInt<x>, Int<y> -> Int<max(x*2, y)>
* UInt64, Int<x> -> Error
* Float<x>, Float<y> -> Float64
* Float<x>, [U]Int<y> -> Float64
*/
template <typename A, typename B>
struct ResultOfModuloNativePromotion
{
static_assert(std::is_arithmetic_v<A> && std::is_arithmetic_v<B>);
static constexpr bool has_float = std::is_floating_point_v<A> || std::is_floating_point_v<B>;
static constexpr bool has_integer = is_integer<A> || is_integer<B>;
static constexpr bool has_signed = is_signed_v<A> || is_signed_v<B>;
static constexpr bool has_unsigned = !is_signed_v<A> || !is_signed_v<B>;
static constexpr size_t max_size_of_unsigned_integer = max(is_signed_v<A> ? 0 : sizeof(A), is_signed_v<B> ? 0 : sizeof(B));
static constexpr size_t max_size_of_signed_integer = max(is_signed_v<A> ? sizeof(A) : 0, is_signed_v<B> ? sizeof(B) : 0);
static constexpr size_t max_size_of_integer = max(is_integer<A> ? sizeof(A) : 0, is_integer<B> ? sizeof(B) : 0);
using ConstructedType = typename Construct<
has_signed,
false,
(has_signed ^ has_unsigned) ? max(max_size_of_unsigned_integer * 2, max_size_of_signed_integer) : max(sizeof(A), sizeof(B))>::Type;
using Type = std::conditional_t<
std::is_same_v<A, B>,
A,
std::conditional_t<has_float, Float64, std::conditional_t<sizeof(ConstructedType) <= 8, ConstructedType, Error>>>;
};
/** Before applying operator `%` and bitwise operations, operands are casted to whole numbers. */
template <typename A> struct ToInteger

View File

@ -2371,11 +2371,11 @@ ColumnPtr executeStringInteger(const ColumnsWithTypeAndName & arguments, const A
{
if constexpr (is_modulo)
{
using PromotedType = std::conditional_t<
std::is_floating_point_v<typename ResultDataType::FieldType>,
Float64,
NumberTraits::ResultOfIf<typename LeftDataType::FieldType, typename RightDataType::FieldType>>;
return std::is_integral_v<PromotedType> || std::is_floating_point_v<PromotedType>;
using LeftType = typename LeftDataType::FieldType;
using RightType = typename RightDataType::FieldType;
using PromotedType = NumberTraits::ResultOfModuloNativePromotion<LeftType, RightType>;
if constexpr (std::is_arithmetic_v<PromotedType>)
return true;
}
else
return true;
@ -2406,25 +2406,31 @@ ColumnPtr executeStringInteger(const ColumnsWithTypeAndName & arguments, const A
auto & b = static_cast<llvm::IRBuilder<> &>(builder);
if constexpr (is_modulo)
{
using PromotedType = std::conditional_t<
std::is_floating_point_v<typename ResultDataType::FieldType>,
Float64,
NumberTraits::ResultOfIf<typename LeftDataType::FieldType, typename RightDataType::FieldType>>;
auto promoted_type = std::make_shared<DataTypeNumber<PromotedType>>();
auto * lval = nativeCast(b, arguments[0], promoted_type);
auto * rval = nativeCast(b, arguments[1], promoted_type);
result = OpSpec::compile(b, lval, rval, std::is_signed_v<PromotedType>);
using LeftType = typename LeftDataType::FieldType;
using RightType = typename RightDataType::FieldType;
using PromotedType = NumberTraits::ResultOfModuloNativePromotion<LeftType, RightType>;
if constexpr (std::is_arithmetic_v<PromotedType>)
{
DataTypePtr promoted_type = std::make_shared<DataTypeNumber<PromotedType>>();
if (result_type->isNullable())
promoted_type = std::make_shared<DataTypeNullable>(promoted_type);
auto * lval = nativeCast(b, arguments[0], promoted_type);
auto * rval = nativeCast(b, arguments[1], promoted_type);
result
= nativeCast(b, promoted_type, OpSpec::compile(b, lval, rval, std::is_signed_v<PromotedType>), result_type);
return true;
}
}
else
{
auto * lval = nativeCast(b, arguments[0], result_type);
auto * rval = nativeCast(b, arguments[1], result_type);
result = OpSpec::compile(b, lval, rval, std::is_signed_v<typename ResultDataType::FieldType>);
return true;
}
return true;
}
}
return false;
});