diff options
-rw-r--r-- | clang/lib/CodeGen/CGBuiltin.cpp | 23 | ||||
-rw-r--r-- | clang/test/CodeGen/math-builtins.c | 6 | ||||
-rw-r--r-- | clang/test/CodeGen/math-libcalls.c | 6 | ||||
-rw-r--r-- | llvm/docs/LangRef.rst | 15 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Intrinsics.td | 5 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 8 |
7 files changed, 42 insertions, 31 deletions
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 43963576dac..6a183129073 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -391,6 +391,18 @@ static Value *emitFPIntBuiltin(CodeGenFunction &CGF, 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 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, 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 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, 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; diff --git a/clang/test/CodeGen/math-builtins.c b/clang/test/CodeGen/math-builtins.c index 83e3d4a2929..cb31288496a 100644 --- a/clang/test/CodeGen/math-builtins.c +++ b/clang/test/CodeGen/math-builtins.c @@ -362,9 +362,9 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) { __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]] diff --git a/clang/test/CodeGen/math-libcalls.c b/clang/test/CodeGen/math-libcalls.c index 176ff38972d..405597e1f03 100644 --- a/clang/test/CodeGen/math-libcalls.c +++ b/clang/test/CodeGen/math-libcalls.c @@ -317,9 +317,9 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) { 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]] diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 07d755c1d78..3f35752b450 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -12398,8 +12398,7 @@ nearest integer. 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 @@ floating-point type. Not all targets support all types however. :: - 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 @@ nearest integer. 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: """""""""" diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index a1e37b66c5f..2957478ef5b 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -539,9 +539,8 @@ let IntrProperties = [IntrNoMem, IntrSpeculatable] in { 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], diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 938aeafb435..33980040051 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -6034,18 +6034,16 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, 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; diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index f7004cf4eae..67d43ce7740 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -4620,6 +4620,14 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) { } 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; + } }; } |