Index: cfe/trunk/lib/CodeGen/CGBuiltin.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CGBuiltin.cpp +++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp @@ -391,6 +391,18 @@ return CGF.Builder.CreateCall(F, {Src0, Src1}); } +// Emit an intrinsic that has overloaded integer result and fp operand. +static Value *emitFPToIntRoundBuiltin(CodeGenFunction &CGF, + const CallExpr *E, + unsigned IntrinsicID) { + llvm::Type *ResultType = CGF.ConvertType(E->getType()); + llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); + + Function *F = CGF.CGM.getIntrinsic(IntrinsicID, + {ResultType, Src0->getType()}); + return CGF.Builder.CreateCall(F, Src0); +} + /// EmitFAbs - Emit a call to @llvm.fabs(). static Value *EmitFAbs(CodeGenFunction &CGF, Value *V) { Function *F = CGF.CGM.getIntrinsic(Intrinsic::fabs, V->getType()); @@ -1726,13 +1738,8 @@ case Builtin::BIlroundl: case Builtin::BI__builtin_lround: case Builtin::BI__builtin_lroundf: - case Builtin::BI__builtin_lroundl: { - llvm::Type *ResultType = ConvertType(E->getType()); - int Width = ResultType->getPrimitiveSizeInBits(); - return RValue::get(emitUnaryBuiltin(*this, E, - Width == 32 ? Intrinsic::lround_i32 - : Intrinsic::lround_i64)); - } + case Builtin::BI__builtin_lroundl: + return RValue::get(emitFPToIntRoundBuiltin(*this, E, Intrinsic::lround)); case Builtin::BIllround: case Builtin::BIllroundf: @@ -1740,7 +1747,7 @@ case Builtin::BI__builtin_llround: case Builtin::BI__builtin_llroundf: case Builtin::BI__builtin_llroundl: - return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::llround)); + return RValue::get(emitFPToIntRoundBuiltin(*this, E, Intrinsic::llround)); default: break; Index: cfe/trunk/test/CodeGen/math-builtins.c =================================================================== --- cfe/trunk/test/CodeGen/math-builtins.c +++ cfe/trunk/test/CodeGen/math-builtins.c @@ -362,9 +362,9 @@ __builtin_llround(f); __builtin_llroundf(f); __builtin_llroundl(f); -// NO__ERRNO: declare i64 @llvm.llround.f64(double) [[READNONE_INTRINSIC]] -// NO__ERRNO: declare i64 @llvm.llround.f32(float) [[READNONE_INTRINSIC]] -// NO__ERRNO: declare i64 @llvm.llround.f80(x86_fp80) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare i64 @llvm.llround.i64.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare i64 @llvm.llround.i64.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare i64 @llvm.llround.i64.f80(x86_fp80) [[READNONE_INTRINSIC]] // HAS_ERRNO: declare i64 @llround(double) [[NOT_READNONE]] // HAS_ERRNO: declare i64 @llroundf(float) [[NOT_READNONE]] // HAS_ERRNO: declare i64 @llroundl(x86_fp80) [[NOT_READNONE]] Index: cfe/trunk/test/CodeGen/math-libcalls.c =================================================================== --- cfe/trunk/test/CodeGen/math-libcalls.c +++ cfe/trunk/test/CodeGen/math-libcalls.c @@ -317,9 +317,9 @@ llround(f); llroundf(f); llroundl(f); -// NO__ERRNO: declare i64 @llvm.llround.f64(double) [[READNONE_INTRINSIC]] -// NO__ERRNO: declare i64 @llvm.llround.f32(float) [[READNONE_INTRINSIC]] -// NO__ERRNO: declare i64 @llvm.llround.f80(x86_fp80) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare i64 @llvm.llround.i64.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare i64 @llvm.llround.i64.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare i64 @llvm.llround.i64.f80(x86_fp80) [[READNONE_INTRINSIC]] // HAS_ERRNO: declare i64 @llround(double) [[NOT_READNONE]] // HAS_ERRNO: declare i64 @llroundf(float) [[NOT_READNONE]] // HAS_ERRNO: declare i64 @llroundl(x86_fp80) [[NOT_READNONE]] Index: llvm/trunk/docs/LangRef.rst =================================================================== --- llvm/trunk/docs/LangRef.rst +++ llvm/trunk/docs/LangRef.rst @@ -12398,8 +12398,7 @@ Arguments: """""""""" -The argument is a floating-point number and return is i32 for -``llvm.lround.i32`` and i64 for ``llvm.lround.i64``. +The argument is a floating-point number and return is an integer type. Semantics: """""""""" @@ -12418,11 +12417,11 @@ :: - declare i64 @llvm.lround.f32(float %Val) - declare i64 @llvm.lround.f64(double %Val) - declare i64 @llvm.lround.f80(float %Val) - declare i64 @llvm.lround.f128(double %Val) - declare i64 @llvm.lround.ppcf128(double %Val) + declare i64 @llvm.lround.i64.f32(float %Val) + declare i64 @llvm.lround.i64.f64(double %Val) + declare i64 @llvm.lround.i64.f80(float %Val) + declare i64 @llvm.lround.i64.f128(double %Val) + declare i64 @llvm.lround.i64.ppcf128(double %Val) Overview: """"""""" @@ -12433,7 +12432,7 @@ Arguments: """""""""" -The argument is a floating-point number and return is i64. +The argument is a floating-point number and return is an integer type. Semantics: """""""""" Index: llvm/trunk/include/llvm/IR/Intrinsics.td =================================================================== --- llvm/trunk/include/llvm/IR/Intrinsics.td +++ llvm/trunk/include/llvm/IR/Intrinsics.td @@ -539,9 +539,8 @@ def int_canonicalize : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>; - def int_lround_i32 : Intrinsic<[llvm_i32_ty], [llvm_anyfloat_ty]>; - def int_lround_i64 : Intrinsic<[llvm_i64_ty], [llvm_anyfloat_ty]>; - def int_llround : Intrinsic<[llvm_i64_ty], [llvm_anyfloat_ty]>; + def int_lround : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>; + def int_llround : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>; } def int_minnum : Intrinsic<[llvm_anyfloat_ty], Index: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -6034,18 +6034,16 @@ getValue(I.getArgOperand(0)))); return; } - case Intrinsic::lround_i32: - case Intrinsic::lround_i64: + case Intrinsic::lround: case Intrinsic::llround: { unsigned Opcode; - MVT RetVT; switch (Intrinsic) { default: llvm_unreachable("Impossible intrinsic"); // Can't reach here. - case Intrinsic::lround_i32: Opcode = ISD::LROUND; RetVT = MVT::i32; break; - case Intrinsic::lround_i64: Opcode = ISD::LROUND; RetVT = MVT::i64; break; - case Intrinsic::llround: Opcode = ISD::LLROUND; RetVT = MVT::i64; break; + case Intrinsic::lround: Opcode = ISD::LROUND; break; + case Intrinsic::llround: Opcode = ISD::LLROUND; break; } + EVT RetVT = TLI.getValueType(DAG.getDataLayout(), I.getType()); setValue(&I, DAG.getNode(Opcode, sdl, RetVT, getValue(I.getArgOperand(0)))); return; Index: llvm/trunk/lib/IR/Verifier.cpp =================================================================== --- llvm/trunk/lib/IR/Verifier.cpp +++ llvm/trunk/lib/IR/Verifier.cpp @@ -4620,6 +4620,14 @@ } break; } + case Intrinsic::lround: + case Intrinsic::llround: { + Type *ValTy = Call.getArgOperand(0)->getType(); + Type *ResultTy = Call.getType(); + Assert(!ValTy->isVectorTy() && !ResultTy->isVectorTy(), + "Intrinsic does not support vectors", &Call); + break; + } }; }