Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -1364,6 +1364,22 @@ return RValue::get(Builder.CreateCall(F, Arg0)); } + case Builtin::BI__builtin_sqrt: + case Builtin::BI__builtin_sqrtf: + case Builtin::BI__builtin_sqrtl: { + // Lib functions with the __builtin prefix don't set errno, so we can safely + // use the intrinsic here. We just need to add a check for x < -0.0 + Value *Arg0 = EmitScalarExpr(E->getArg(0)); + llvm::Type *ArgType = Arg0->getType(); + Value *F = CGM.getIntrinsic(Intrinsic::sqrt, ArgType); + Value *Sqrt = Builder.CreateCall(F, Arg0); + Value *Cmp = Builder.CreateFCmpOLT(Arg0, + ConstantFP::getNegativeZero(ArgType)); + return RValue::get(Builder.CreateSelect(Cmp, ConstantFP::getNaN(ArgType), + Sqrt)); + + } + case Builtin::BI__builtin_pow: case Builtin::BI__builtin_powf: case Builtin::BI__builtin_powl: Index: test/CodeGen/builtins.c =================================================================== --- test/CodeGen/builtins.c +++ test/CodeGen/builtins.c @@ -236,3 +236,25 @@ // CHECK: call i64 @llvm.readcyclecounter() return __builtin_readcyclecounter(); } + +// CHECK-LABEL: define void @test_float_builtin_libcalls +void test_float_builtin_libcalls(float F, double D, long double LD) { + volatile float resf; + volatile double resd; + volatile long double resld; + + resf = __builtin_sqrtf(F); + // CHECK-DAG: [[SQRTF:%.*]] = call float @llvm.sqrt.f32(float + // CHECK-DAG: [[FCMPF:%.*]] = fcmp olt float {{.*}}, -0.000000e+00 + // CHECK: select i1 [[FCMPF]], float 0x7FF8000000000000, float [[SQRTF]] + + resd = __builtin_sqrt(D); + // CHECK-DAG: [[SQRTD:%.*]] = call double @llvm.sqrt.f64(double + // CHECK-DAG: [[FCMPD:%.*]] = fcmp olt double {{.*}}, -0.000000e+00 + // CHECK: select i1 [[FCMPD]], double 0x7FF8000000000000, double [[SQRTD]] + + resld = __builtin_sqrtl(LD); + // CHECK-DAG: [[SQRTL:%.*]] = call x86_fp80 @llvm.sqrt.f80(x86_fp80 + // CHECK-DAG: [[FCMPL:%.*]] = fcmp olt x86_fp80 {{.*}}, 0xK80000000000000000000 + // CHECK: select i1 [[FCMPL]], x86_fp80 0xK7FFFC000000000000000, x86_fp80 [[SQRTL]] +}