Index: include/clang/Basic/Builtins.def =================================================================== --- include/clang/Basic/Builtins.def +++ include/clang/Basic/Builtins.def @@ -105,9 +105,9 @@ BUILTIN(__builtin_copysign, "ddd", "ncF") BUILTIN(__builtin_copysignf, "fff", "ncF") BUILTIN(__builtin_copysignl, "LdLdLd", "ncF") -BUILTIN(__builtin_fabs , "dd" , "ncF") -BUILTIN(__builtin_fabsf, "ff" , "ncF") -BUILTIN(__builtin_fabsl, "LdLd", "ncF") +BUILTIN(__builtin_fabs , "dd" , "nc") +BUILTIN(__builtin_fabsf, "ff" , "nc") +BUILTIN(__builtin_fabsl, "LdLd", "nc") BUILTIN(__builtin_fmod , "ddd" , "Fnc") BUILTIN(__builtin_fmodf, "fff" , "Fnc") BUILTIN(__builtin_fmodl, "LdLdLd", "Fnc") @@ -163,9 +163,9 @@ BUILTIN(__builtin_cbrt , "dd", "Fnc") BUILTIN(__builtin_cbrtf, "ff", "Fnc") BUILTIN(__builtin_cbrtl, "LdLd", "Fnc") -BUILTIN(__builtin_ceil , "dd" , "Fnc") -BUILTIN(__builtin_ceilf, "ff" , "Fnc") -BUILTIN(__builtin_ceill, "LdLd", "Fnc") +BUILTIN(__builtin_ceil , "dd" , "nc") +BUILTIN(__builtin_ceilf, "ff" , "nc") +BUILTIN(__builtin_ceill, "LdLd", "nc") BUILTIN(__builtin_cos , "dd" , "Fnc") BUILTIN(__builtin_cosf, "ff" , "Fnc") BUILTIN(__builtin_cosh , "dd" , "Fnc") @@ -190,18 +190,18 @@ BUILTIN(__builtin_fdim, "ddd", "Fnc") BUILTIN(__builtin_fdimf, "fff", "Fnc") BUILTIN(__builtin_fdiml, "LdLdLd", "Fnc") -BUILTIN(__builtin_floor , "dd" , "Fnc") -BUILTIN(__builtin_floorf, "ff" , "Fnc") -BUILTIN(__builtin_floorl, "LdLd", "Fnc") +BUILTIN(__builtin_floor , "dd" , "nc") +BUILTIN(__builtin_floorf, "ff" , "nc") +BUILTIN(__builtin_floorl, "LdLd", "nc") BUILTIN(__builtin_fma, "dddd", "Fnc") BUILTIN(__builtin_fmaf, "ffff", "Fnc") BUILTIN(__builtin_fmal, "LdLdLdLd", "Fnc") -BUILTIN(__builtin_fmax, "ddd", "Fnc") -BUILTIN(__builtin_fmaxf, "fff", "Fnc") -BUILTIN(__builtin_fmaxl, "LdLdLd", "Fnc") -BUILTIN(__builtin_fmin, "ddd", "Fnc") -BUILTIN(__builtin_fminf, "fff", "Fnc") -BUILTIN(__builtin_fminl, "LdLdLd", "Fnc") +BUILTIN(__builtin_fmax, "ddd", "nc") +BUILTIN(__builtin_fmaxf, "fff", "nc") +BUILTIN(__builtin_fmaxl, "LdLdLd", "nc") +BUILTIN(__builtin_fmin, "ddd", "nc") +BUILTIN(__builtin_fminf, "fff", "nc") +BUILTIN(__builtin_fminl, "LdLdLd", "nc") BUILTIN(__builtin_hypot , "ddd" , "Fnc") BUILTIN(__builtin_hypotf, "fff" , "Fnc") BUILTIN(__builtin_hypotl, "LdLdLd", "Fnc") @@ -238,9 +238,9 @@ BUILTIN(__builtin_lround , "Lid", "Fnc") BUILTIN(__builtin_lroundf, "Lif", "Fnc") BUILTIN(__builtin_lroundl, "LiLd", "Fnc") -BUILTIN(__builtin_nearbyint , "dd", "Fnc") -BUILTIN(__builtin_nearbyintf, "ff", "Fnc") -BUILTIN(__builtin_nearbyintl, "LdLd", "Fnc") +BUILTIN(__builtin_nearbyint , "dd", "nc") +BUILTIN(__builtin_nearbyintf, "ff", "nc") +BUILTIN(__builtin_nearbyintl, "LdLd", "nc") BUILTIN(__builtin_nextafter , "ddd", "Fnc") BUILTIN(__builtin_nextafterf, "fff", "Fnc") BUILTIN(__builtin_nextafterl, "LdLdLd", "Fnc") @@ -253,12 +253,12 @@ BUILTIN(__builtin_remquo , "dddi*", "Fn") BUILTIN(__builtin_remquof, "fffi*", "Fn") BUILTIN(__builtin_remquol, "LdLdLdi*", "Fn") -BUILTIN(__builtin_rint , "dd", "Fnc") -BUILTIN(__builtin_rintf, "ff", "Fnc") -BUILTIN(__builtin_rintl, "LdLd", "Fnc") -BUILTIN(__builtin_round, "dd" , "Fnc") -BUILTIN(__builtin_roundf, "ff" , "Fnc") -BUILTIN(__builtin_roundl, "LdLd" , "Fnc") +BUILTIN(__builtin_rint , "dd", "nc") +BUILTIN(__builtin_rintf, "ff", "nc") +BUILTIN(__builtin_rintl, "LdLd", "nc") +BUILTIN(__builtin_round, "dd" , "nc") +BUILTIN(__builtin_roundf, "ff" , "nc") +BUILTIN(__builtin_roundl, "LdLd" , "nc") BUILTIN(__builtin_scalbln , "ddLi", "Fnc") BUILTIN(__builtin_scalblnf, "ffLi", "Fnc") BUILTIN(__builtin_scalblnl, "LdLdLi", "Fnc") @@ -283,9 +283,9 @@ BUILTIN(__builtin_tgamma , "dd", "Fnc") BUILTIN(__builtin_tgammaf, "ff", "Fnc") BUILTIN(__builtin_tgammal, "LdLd", "Fnc") -BUILTIN(__builtin_trunc , "dd", "Fnc") -BUILTIN(__builtin_truncf, "ff", "Fnc") -BUILTIN(__builtin_truncl, "LdLd", "Fnc") +BUILTIN(__builtin_trunc , "dd", "nc") +BUILTIN(__builtin_truncf, "ff", "nc") +BUILTIN(__builtin_truncl, "LdLd", "nc") // C99 complex builtins BUILTIN(__builtin_cabs, "dXd", "Fnc") Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -146,6 +146,39 @@ return RValue::get(Result); } +// Emit an intrinsic that has 1 float or double. +static Value *emitUnaryFPBuiltin(CodeGenFunction &CGF, + const CallExpr *E, + unsigned IntrinsicID) { + llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); + + Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); + return CGF.Builder.CreateCall(F, Src0); +} + +// Emit an intrinsic that has 2 float or double operands. +static Value *emitBinaryFPBuiltin(CodeGenFunction &CGF, + const CallExpr *E, + unsigned IntrinsicID) { + llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); + llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1)); + + Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); + return CGF.Builder.CreateCall2(F, Src0, Src1); +} + +// Emit an intrinsic that has 3 float or double operands. +static Value *emitTernaryFPBuiltin(CodeGenFunction &CGF, + const CallExpr *E, + unsigned IntrinsicID) { + llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); + llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1)); + llvm::Value *Src2 = CGF.EmitScalarExpr(E->getArg(2)); + + Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); + return CGF.Builder.CreateCall3(F, Src0, Src1, Src2); +} + /// EmitFAbs - Emit a call to @llvm.fabs(). static Value *EmitFAbs(CodeGenFunction &CGF, Value *V, QualType ValTy) { Value *F = CGF.CGM.getIntrinsic(Intrinsic::fabs, V->getType()); @@ -245,6 +278,11 @@ return RValue::get(Result); } + case Builtin::BI__builtin_fabs: + case Builtin::BI__builtin_fabsf: + case Builtin::BI__builtin_fabsl: { + return RValue::get(emitUnaryFPBuiltin(*this, E, Intrinsic::fabs)); + } case Builtin::BI__builtin_fmod: case Builtin::BI__builtin_fmodf: case Builtin::BI__builtin_fmodl: { @@ -253,7 +291,51 @@ Value *Result = Builder.CreateFRem(Arg1, Arg2, "fmod"); return RValue::get(Result); } - + case Builtin::BI__builtin_copysign: + case Builtin::BI__builtin_copysignf: + case Builtin::BI__builtin_copysignl: { + return RValue::get(emitBinaryFPBuiltin(*this, E, Intrinsic::copysign)); + } + case Builtin::BI__builtin_ceil: + case Builtin::BI__builtin_ceilf: + case Builtin::BI__builtin_ceill: { + return RValue::get(emitUnaryFPBuiltin(*this, E, Intrinsic::ceil)); + } + case Builtin::BI__builtin_floor: + case Builtin::BI__builtin_floorf: + case Builtin::BI__builtin_floorl: { + return RValue::get(emitUnaryFPBuiltin(*this, E, Intrinsic::floor)); + } + case Builtin::BI__builtin_trunc: + case Builtin::BI__builtin_truncf: + case Builtin::BI__builtin_truncl: { + return RValue::get(emitUnaryFPBuiltin(*this, E, Intrinsic::trunc)); + } + case Builtin::BI__builtin_rint: + case Builtin::BI__builtin_rintf: + case Builtin::BI__builtin_rintl: { + return RValue::get(emitUnaryFPBuiltin(*this, E, Intrinsic::rint)); + } + case Builtin::BI__builtin_nearbyint: + case Builtin::BI__builtin_nearbyintf: + case Builtin::BI__builtin_nearbyintl: { + return RValue::get(emitUnaryFPBuiltin(*this, E, Intrinsic::nearbyint)); + } + case Builtin::BI__builtin_round: + case Builtin::BI__builtin_roundf: + case Builtin::BI__builtin_roundl: { + return RValue::get(emitUnaryFPBuiltin(*this, E, Intrinsic::round)); + } + case Builtin::BI__builtin_fmin: + case Builtin::BI__builtin_fminf: + case Builtin::BI__builtin_fminl: { + return RValue::get(emitBinaryFPBuiltin(*this, E, Intrinsic::minnum)); + } + case Builtin::BI__builtin_fmax: + case Builtin::BI__builtin_fmaxf: + case Builtin::BI__builtin_fmaxl: { + return RValue::get(emitBinaryFPBuiltin(*this, E, Intrinsic::maxnum)); + } case Builtin::BI__builtin_conj: case Builtin::BI__builtin_conjf: case Builtin::BI__builtin_conjl: { @@ -6088,28 +6170,6 @@ } } -// Emit an intrinsic that has 1 float or double. -static Value *emitUnaryFPBuiltin(CodeGenFunction &CGF, - const CallExpr *E, - unsigned IntrinsicID) { - llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); - - Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); - return CGF.Builder.CreateCall(F, Src0); -} - -// Emit an intrinsic that has 3 float or double operands. -static Value *emitTernaryFPBuiltin(CodeGenFunction &CGF, - const CallExpr *E, - unsigned IntrinsicID) { - llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); - llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1)); - llvm::Value *Src2 = CGF.EmitScalarExpr(E->getArg(2)); - - Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); - return CGF.Builder.CreateCall3(F, Src0, Src1, Src2); -} - // Emit an intrinsic that has 1 float or double operand, and 1 integer. static Value *emitFPIntBuiltin(CodeGenFunction &CGF, const CallExpr *E, Index: test/CodeGen/builtins.c =================================================================== --- test/CodeGen/builtins.c +++ test/CodeGen/builtins.c @@ -211,6 +211,99 @@ resld = __builtin_fmodl(LD,LD); // CHECK: frem x86_fp80 + + + resf = __builtin_fminf(F, F); + // CHECK: call float @llvm.minnum.f32 + + resd = __builtin_fmin(D, D); + // CHECK: call double @llvm.minnum.f64 + + resld = __builtin_fminl(LD, LD); + // CHECK: call x86_fp80 @llvm.minnum.f80 + + resf = __builtin_fmaxf(F, F); + // CHECK: call float @llvm.maxnum.f32 + + resd = __builtin_fmax(D, D); + // CHECK: call double @llvm.maxnum.f64 + + resld = __builtin_fmaxl(LD, LD); + // CHECK: call x86_fp80 @llvm.maxnum.f80 + + resf = __builtin_fabsf(F); + // CHECK: call float @llvm.fabs.f32 + + resd = __builtin_fabs(D); + // CHECK: call double @llvm.fabs.f64 + + resld = __builtin_fabsl(LD); + // CHECK: call x86_fp80 @llvm.fabs.f80 + + resf = __builtin_copysignf(F, F); + // CHECK: call float @llvm.copysign.f32 + + resd = __builtin_copysign(D, D); + // CHECK: call double @llvm.copysign.f64 + + resld = __builtin_copysignl(LD, LD); + // CHECK: call x86_fp80 @llvm.copysign.f80 + + + resf = __builtin_ceilf(F); + // CHECK: call float @llvm.ceil.f32 + + resd = __builtin_ceil(D); + // CHECK: call double @llvm.ceil.f64 + + resld = __builtin_ceill(LD); + // CHECK: call x86_fp80 @llvm.ceil.f80 + + resf = __builtin_floorf(F); + // CHECK: call float @llvm.floor.f32 + + resd = __builtin_floor(D); + // CHECK: call double @llvm.floor.f64 + + resld = __builtin_floorl(LD); + // CHECK: call x86_fp80 @llvm.floor.f80 + + resf = __builtin_truncf(F); + // CHECK: call float @llvm.trunc.f32 + + resd = __builtin_trunc(D); + // CHECK: call double @llvm.trunc.f64 + + resld = __builtin_truncl(LD); + // CHECK: call x86_fp80 @llvm.trunc.f80 + + resf = __builtin_rintf(F); + // CHECK: call float @llvm.rint.f32 + + resd = __builtin_rint(D); + // CHECK: call double @llvm.rint.f64 + + resld = __builtin_rintl(LD); + // CHECK: call x86_fp80 @llvm.rint.f80 + + resf = __builtin_nearbyintf(F); + // CHECK: call float @llvm.nearbyint.f32 + + resd = __builtin_nearbyint(D); + // CHECK: call double @llvm.nearbyint.f64 + + resld = __builtin_nearbyintl(LD); + // CHECK: call x86_fp80 @llvm.nearbyint.f80 + + resf = __builtin_roundf(F); + // CHECK: call float @llvm.round.f32 + + resd = __builtin_round(D); + // CHECK: call double @llvm.round.f64 + + resld = __builtin_roundl(LD); + // CHECK: call x86_fp80 @llvm.round.f80 + } // CHECK-LABEL: define void @test_builtin_longjmp