summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp23
-rw-r--r--clang/test/CodeGen/math-builtins.c6
-rw-r--r--clang/test/CodeGen/math-libcalls.c6
-rw-r--r--llvm/docs/LangRef.rst15
-rw-r--r--llvm/include/llvm/IR/Intrinsics.td5
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp10
-rw-r--r--llvm/lib/IR/Verifier.cpp8
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;
+ }
};
}
OpenPOWER on IntegriCloud