[CodeGen] map sqrt libcalls to llvm.sqrt when errno is not set
The LLVM sqrt intrinsic definition changed with:
D28797
...so we don't have to use any relaxed FP settings other than errno handling.
This patch sidesteps a question raised in PR27435:
https://bugs.llvm.org/show_bug.cgi?id=27435
Is a programmer using __builtin_sqrt() invoking the compiler's intrinsic definition of sqrt or the mathlib definition of sqrt?
But we have an answer now: the builtin should match the behavior of the libm function including errno handling.
Differential Revision: https://reviews.llvm.org/D39204
llvm-svn: 317031
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 1de7c6e..bc37afa 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2072,24 +2072,21 @@
return RValue::get(nullptr);
}
- // Library functions with special handling.
case Builtin::BIsqrt:
case Builtin::BIsqrtf:
- case Builtin::BIsqrtl: {
- // Transform a call to sqrt* into a @llvm.sqrt.* intrinsic call, but only
- // in finite- or unsafe-math mode (the intrinsic has different semantics
- // for handling negative numbers compared to the library function, so
- // -fmath-errno=0 is not enough).
- if (!FD->hasAttr<ConstAttr>())
- break;
- if (!(CGM.getCodeGenOpts().UnsafeFPMath ||
- CGM.getCodeGenOpts().NoNaNsFPMath))
- break;
- Value *Arg0 = EmitScalarExpr(E->getArg(0));
- llvm::Type *ArgType = Arg0->getType();
- Value *F = CGM.getIntrinsic(Intrinsic::sqrt, ArgType);
- return RValue::get(Builder.CreateCall(F, Arg0));
- }
+ case Builtin::BIsqrtl:
+ // Builtins have the same semantics as library functions. The LLVM intrinsic
+ // has the same semantics as the library function except it does not set
+ // errno. Thus, we can transform either sqrt or __builtin_sqrt to @llvm.sqrt
+ // if the call is 'const' (the call must not set errno).
+ //
+ // FIXME: The builtin cases are not here because they are marked 'const' in
+ // Builtins.def. So that means they are wrongly defined to have different
+ // semantics than the library functions. If we included them here, we would
+ // turn them into LLVM intrinsics regardless of whether -fmath-errno was on.
+ if (FD->hasAttr<ConstAttr>())
+ return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::sqrt));
+ break;
case Builtin::BI__builtin_pow:
case Builtin::BI__builtin_powf: