[BACKEND] float division is now approximate by default (#446)
This commit is contained in:
@@ -319,6 +319,13 @@ void generator::visit_binary_operator(ir::binary_operator*x) {
|
||||
vals_[x][idx] = add(lhs, rhs);
|
||||
else if(op == ll::Mul)
|
||||
vals_[x][idx] = mul(lhs, rhs);
|
||||
else if(op == ll::FDiv && !x->get_fdiv_ieee_rounding() &&
|
||||
x->get_type()->get_scalar_ty()->is_fp32_ty()){
|
||||
InlineAsm *ptx = InlineAsm::get(FunctionType::get(f32_ty, {f32_ty, f32_ty}, false),
|
||||
" div.full.f32 $0, $1, $2;", "=r,r,r", false);
|
||||
vals_[x][idx] = builder_->CreateCall(ptx, {lhs, rhs});
|
||||
|
||||
}
|
||||
else
|
||||
vals_[x][idx] = bin_op(op, lhs, rhs);
|
||||
}
|
||||
|
@@ -204,6 +204,18 @@ ir::value *dispatch::floordiv(ir::value *input, ir::value *other, ir::builder *b
|
||||
throw_unreachable("floordiv");
|
||||
}
|
||||
|
||||
ir::value *dispatch::fdiv(ir::value *input, ir::value *other, constant_int *ieee_rounding, ir::builder *builder){
|
||||
ir::type *input_scalar_ty = input->get_type()->get_scalar_ty();
|
||||
ir::type *other_scalar_ty = other->get_type()->get_scalar_ty();
|
||||
if(!input_scalar_ty->is_floating_point_ty() || !other_scalar_ty->is_floating_point_ty())
|
||||
throw semantic_error("both operands of fdiv must have floating point scalar type");
|
||||
binary_op_type_checking(input, other, builder, false, false, false, DivOrMod::YES);
|
||||
ir::value* ret = builder->create_fdiv(input, other);
|
||||
if(ir::binary_operator* binop = dynamic_cast<ir::binary_operator*>(ret))
|
||||
binop->set_fdiv_ieee_rounding(ieee_rounding->get_value());
|
||||
return ret;
|
||||
}
|
||||
|
||||
ir::value *dispatch::mod(ir::value *input, ir::value *other, ir::builder *builder) {
|
||||
binary_op_type_checking(input, other, builder, false, false, true, DivOrMod::YES);
|
||||
ir::type *scalar_ty = input->get_type()->get_scalar_ty();
|
||||
|
@@ -134,7 +134,7 @@ bool binary_operator::is_int_add_sub() const {
|
||||
|
||||
|
||||
binary_operator::binary_operator(binary_op_t op, value *lhs, value *rhs, type *ty, const std::string &name, instruction *next)
|
||||
: instruction(ty, INST_BINOP, 2, name, next), op_(op){
|
||||
: instruction(ty, INST_BINOP, 2, name, next), op_(op), fdiv_ieee_rnd_(false){
|
||||
set_operand(0, lhs);
|
||||
set_operand(1, rhs);
|
||||
}
|
||||
|
Reference in New Issue
Block a user