From: Craig Topper Date: Mon, 20 May 2019 16:27:09 +0000 (+0000) Subject: [Intrinsics] Merge lround.i32 and lround.i64 into a single intrinsic with overloaded... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=625704901315d46151fbf48c7b4b9c9a5ff33221;p=clang [Intrinsics] Merge lround.i32 and lround.i64 into a single intrinsic with overloaded result type. Make result type for llvm.llround overloaded instead of fixing to i64 We shouldn't really make assumptions about possible sizes for long and long long. And longer term we should probably support vectorizing these intrinsics. By making the result types not fixed we can support vectors as well. Differential Revision: https://reviews.llvm.org/D62026 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@361169 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 43963576da..6a18312907 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/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/test/CodeGen/math-builtins.c b/test/CodeGen/math-builtins.c index 83e3d4a292..cb31288496 100644 --- a/test/CodeGen/math-builtins.c +++ b/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/test/CodeGen/math-libcalls.c b/test/CodeGen/math-libcalls.c index 176ff38972..405597e1f0 100644 --- a/test/CodeGen/math-libcalls.c +++ b/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]]