@@ -194,6 +194,23 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
194194 break ;
195195 }
196196
197+ case Step::Type::Round: {
198+ assert (step.args .size () == 1 );
199+ const auto &arg = step.args [0 ];
200+ // x >= 0.0 ? round(x) : (x >= -0.5 ? -0.0 : floor(x + 0.5))
201+ llvm::Constant *zero = llvm::ConstantFP::get (m_ctx, llvm::APFloat (0.0 ));
202+ llvm::Constant *negativeZero = llvm::ConstantFP::get (m_ctx, llvm::APFloat (-0.0 ));
203+ llvm::Function *roundFunc = llvm::Intrinsic::getDeclaration (m_module.get (), llvm::Intrinsic::round, m_builder.getDoubleTy ());
204+ llvm::Function *floorFunc = llvm::Intrinsic::getDeclaration (m_module.get (), llvm::Intrinsic::floor, m_builder.getDoubleTy ());
205+ llvm::Value *num = removeNaN (castValue (arg.second , arg.first ));
206+ llvm::Value *notNegative = m_builder.CreateFCmpOGE (num, zero); // num >= 0.0
207+ llvm::Value *roundNum = m_builder.CreateCall (roundFunc, num); // round(num)
208+ llvm::Value *negativeCond = m_builder.CreateFCmpOGE (num, llvm::ConstantFP::get (m_ctx, llvm::APFloat (-0.5 ))); // num >= -0.5
209+ llvm::Value *negativeRound = m_builder.CreateCall (floorFunc, m_builder.CreateFAdd (num, llvm::ConstantFP::get (m_ctx, llvm::APFloat (0.5 )))); // floor(x + 0.5)
210+ step.functionReturnReg ->value = m_builder.CreateSelect (notNegative, roundNum, m_builder.CreateSelect (negativeCond, negativeZero, negativeRound));
211+ break ;
212+ }
213+
197214 case Step::Type::Yield:
198215 if (!m_warp) {
199216 freeHeap ();
@@ -567,6 +584,11 @@ void LLVMCodeBuilder::createMod()
567584 createOp (Step::Type::Mod, Compiler::StaticType::Number, Compiler::StaticType::Number, 2 );
568585}
569586
587+ void LLVMCodeBuilder::createRound ()
588+ {
589+ createOp (Step::Type::Round, Compiler::StaticType::Number, Compiler::StaticType::Number, 1 );
590+ }
591+
570592void LLVMCodeBuilder::beginIfStatement ()
571593{
572594 Step step (Step::Type::BeginIf);
0 commit comments