Fixed compilable function

This commit is contained in:
Maksim Kita 2021-05-05 23:08:31 +03:00
parent 4db7e49ccf
commit 7778172a1f
6 changed files with 33 additions and 21 deletions

View File

@ -1243,7 +1243,7 @@ public:
WhichDataType data_type_lhs(types[0]);
WhichDataType data_type_rhs(types[1]);
auto is_big_integer = [](WhichDataType type) { return type.isUInt64() || type.isInt64() || type.isUUID(); };
auto is_big_integer = [](WhichDataType type) { return type.isUInt64() || type.isInt64(); };
if ((is_big_integer(data_type_lhs) && data_type_rhs.isFloat())
|| (is_big_integer(data_type_rhs) && data_type_lhs.isFloat())

View File

@ -26,10 +26,13 @@ struct GreatestBaseImpl
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool is_signed)
{
if (!left->getType()->isIntegerTy())
/// XXX maxnum is basically fmax(), it may or may not match whatever apply() does
/// XXX CreateMaxNum is broken on LLVM 5.0 and 6.0 (generates minnum instead; fixed in 7)
return b.CreateBinaryIntrinsic(llvm::Intrinsic::maxnum, left, right);
return b.CreateSelect(is_signed ? b.CreateICmpSGT(left, right) : b.CreateICmpUGT(left, right), left, right);
{
/// Follows the IEEE-754 semantics for maxNum except for the handling of signaling NaNs. This matches the behavior of libc fmax.
return b.CreateMaxNum(left, right);
}
auto * compare_value = is_signed ? b.CreateICmpSGT(left, right) : b.CreateICmpUGT(left, right);
return b.CreateSelect(compare_value, left, right);
}
#endif
};

View File

@ -26,9 +26,13 @@ struct LeastBaseImpl
static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool is_signed)
{
if (!left->getType()->isIntegerTy())
/// XXX minnum is basically fmin(), it may or may not match whatever apply() does
{
/// Follows the IEEE-754 semantics for minNum, except for handling of signaling NaNs. This matchs the behavior of libc fmin.
return b.CreateMinNum(left, right);
return b.CreateSelect(is_signed ? b.CreateICmpSLT(left, right) : b.CreateICmpULT(left, right), left, right);
}
auto * compare_value = is_signed ? b.CreateICmpSLT(left, right) : b.CreateICmpULT(left, right);
return b.CreateSelect(compare_value, left, right);
}
#endif
};

View File

@ -367,26 +367,26 @@ static CompileDAG getCompilableDAG(
break;
}
bool should_visit_children_first = frame.next_child_to_visit < node->children.size();
bool all_children_visited = frame.next_child_to_visit == node->children.size();
if (should_visit_children_first)
if (all_children_visited)
continue;
CompileDAG::Node compile_node;
compile_node.function = node->function_base;
compile_node.result_type = node->result_type;
if (node->type == ActionsDAG::ActionType::FUNCTION)
if (isCompilableConstant(*node))
{
compile_node.type = CompileDAG::CompileType::CONSTANT;
compile_node.column = node->column;
}
else if (node->type == ActionsDAG::ActionType::FUNCTION)
{
compile_node.type = CompileDAG::CompileType::FUNCTION;
for (const auto * child : node->children)
compile_node.arguments.push_back(visited_node_to_compile_dag_position[child]);
}
else if (isCompilableConstant(*node))
{
compile_node.type = CompileDAG::CompileType::CONSTANT;
compile_node.column = node->column;
}
else
{
compile_node.type = CompileDAG::CompileType::INPUT;
@ -431,9 +431,9 @@ void ActionsDAG::compileFunctions(size_t min_count_to_compile_expression)
std::stack<Frame> stack;
std::unordered_set<const Node *> visited_nodes;
/** Algorithm is go throught each node in ActionsDAG, and for each node iterate thought all children.
* and update data with their compilable status.
* After this procedure in data for each node is initialized.
/** Algorithm is to iterate over each node in ActionsDAG, and update node compilable status.
* Node is compilable if all its children are compilable and node is also compilable.
* After this procedure data for each node is initialized.
*/
for (auto & node : nodes)
@ -462,9 +462,9 @@ void ActionsDAG::compileFunctions(size_t min_count_to_compile_expression)
break;
}
bool should_visit_children_first = current_frame.next_child_to_visit < current_node->children.size();
bool all_children_visited = current_frame.next_child_to_visit == current_node->children.size();
if (should_visit_children_first)
if (!all_children_visited)
continue;
auto & current_node_data = node_to_data[current_node];

View File

@ -16,6 +16,11 @@
namespace DB
{
namespace ErrorCodes
{
extern const int LOGICAL_ERROR;
}
llvm::Value * CompileDAG::compile(llvm::IRBuilderBase & builder, Values input_nodes_values) const
{
assert(input_nodes_values.size() == getInputNodesCount());

View File

@ -103,7 +103,7 @@ static void compileFunction(llvm::Module & module, const IFunctionBaseImpl & f)
Values arguments;
arguments.reserve(arg_types.size());
for (size_t i = 0; i < arg_types.size(); ++i) // NOLINT
for (size_t i = 0; i < arg_types.size(); ++i)
{
auto & column = columns[i];
auto type = arg_types[i];