Fix math-errno issue (#66381)
Update handling of math errno. This change updates the logic for generation of math intrinics in place of math library function calls. The previous logic https://reviews.llvm.org/D151834 was incorrectly using intrinsics when math errno handling was needed at optimization levels above -O0. This also fixes issue mentioned in https://reviews.llvm.org/D151834 by @uabelho This is joint work with @andykaylor Andy.
This commit is contained in:
committed by
GitHub
parent
6d1c6ecbdc
commit
a292e7edf8
@@ -2312,8 +2312,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
|
||||
const unsigned BuiltinIDIfNoAsmLabel =
|
||||
FD->hasAttr<AsmLabelAttr>() ? 0 : BuiltinID;
|
||||
|
||||
bool ErrnoOverriden = false;
|
||||
// True if math-errno is overriden via the
|
||||
std::optional<bool> ErrnoOverriden;
|
||||
// ErrnoOverriden is true if math-errno is overriden via the
|
||||
// '#pragma float_control(precise, on)'. This pragma disables fast-math,
|
||||
// which implies math-errno.
|
||||
if (E->hasStoredFPFeatures()) {
|
||||
@@ -2329,8 +2329,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
|
||||
// using the '#pragma float_control(precise, off)', and
|
||||
// attribute opt-none hasn't been seen.
|
||||
bool ErrnoOverridenToFalseWithOpt =
|
||||
!ErrnoOverriden && !OptNone &&
|
||||
CGM.getCodeGenOpts().OptimizationLevel != 0;
|
||||
ErrnoOverriden.has_value() && !ErrnoOverriden.value() && !OptNone &&
|
||||
CGM.getCodeGenOpts().OptimizationLevel != 0;
|
||||
|
||||
// There are LLVM math intrinsics/instructions corresponding to math library
|
||||
// functions except the LLVM op will never set errno while the math library
|
||||
@@ -2339,6 +2339,30 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
|
||||
// LLVM counterparts if the call is marked 'const' (known to never set errno).
|
||||
// In case FP exceptions are enabled, the experimental versions of the
|
||||
// intrinsics model those.
|
||||
bool ConstAlways =
|
||||
getContext().BuiltinInfo.isConst(BuiltinID);
|
||||
|
||||
// There's a special case with the fma builtins where they are always const
|
||||
// if the target environment is GNU or the target is OS is Windows and we're
|
||||
// targeting the MSVCRT.dll environment.
|
||||
// FIXME: This list can be become outdated. Need to find a way to get it some
|
||||
// other way.
|
||||
switch (BuiltinID) {
|
||||
case Builtin::BI__builtin_fma:
|
||||
case Builtin::BI__builtin_fmaf:
|
||||
case Builtin::BI__builtin_fmal:
|
||||
case Builtin::BIfma:
|
||||
case Builtin::BIfmaf:
|
||||
case Builtin::BIfmal: {
|
||||
auto &Trip = CGM.getTriple();
|
||||
if (Trip.isGNUEnvironment() || Trip.isOSMSVCRT())
|
||||
ConstAlways = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
bool ConstWithoutErrnoAndExceptions =
|
||||
getContext().BuiltinInfo.isConstWithoutErrnoAndExceptions(BuiltinID);
|
||||
bool ConstWithoutExceptions =
|
||||
@@ -2362,14 +2386,17 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
|
||||
bool ConstWithoutErrnoOrExceptions =
|
||||
ConstWithoutErrnoAndExceptions || ConstWithoutExceptions;
|
||||
bool GenerateIntrinsics =
|
||||
FD->hasAttr<ConstAttr>() && !ErrnoOverriden && !OptNone;
|
||||
(ConstAlways && !OptNone) ||
|
||||
(!getLangOpts().MathErrno &&
|
||||
!(ErrnoOverriden.has_value() && ErrnoOverriden.value()) && !OptNone);
|
||||
if (!GenerateIntrinsics) {
|
||||
GenerateIntrinsics =
|
||||
ConstWithoutErrnoOrExceptions && !ConstWithoutErrnoAndExceptions;
|
||||
if (!GenerateIntrinsics)
|
||||
GenerateIntrinsics =
|
||||
ConstWithoutErrnoOrExceptions &&
|
||||
(!getLangOpts().MathErrno && !ErrnoOverriden && !OptNone);
|
||||
(!getLangOpts().MathErrno &&
|
||||
!(ErrnoOverriden.has_value() && ErrnoOverriden.value()) && !OptNone);
|
||||
if (!GenerateIntrinsics)
|
||||
GenerateIntrinsics =
|
||||
ConstWithoutErrnoOrExceptions && ErrnoOverridenToFalseWithOpt;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm %s | FileCheck %s -check-prefix=NO__ERRNO
|
||||
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s -check-prefix=HAS_ERRNO
|
||||
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm -disable-llvm-passes -O2 %s | FileCheck %s -check-prefix=NO__ERRNO
|
||||
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm -disable-llvm-passes -O2 -fmath-errno %s | FileCheck %s -check-prefix=HAS_ERRNO
|
||||
// RUN: %clang_cc1 -triple x86_64-unknown-unknown-gnu -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_GNU
|
||||
// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_WIN
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -S -o - -emit-llvm %s | FileCheck %s --check-prefix=NO__ERRNO
|
||||
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO
|
||||
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -S -o - -emit-llvm -disable-llvm-passes -O2 %s | FileCheck %s --check-prefix=NO__ERRNO
|
||||
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -S -o - -emit-llvm -disable-llvm-passes -O2 -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO
|
||||
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -S -o - -emit-llvm -ffp-exception-behavior=maytrap %s | FileCheck %s --check-prefix=HAS_MAYTRAP
|
||||
// RUN: %clang_cc1 -triple x86_64-unknown-unknown-gnu -Wno-implicit-function-declaration -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_GNU
|
||||
// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -Wno-implicit-function-declaration -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_WIN
|
||||
|
||||
Reference in New Issue
Block a user