Skip to content

Commit a292e7e

Browse files
authored
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.
1 parent 6d1c6ec commit a292e7e

File tree

3 files changed

+37
-6
lines changed

3 files changed

+37
-6
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2312,8 +2312,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
23122312
const unsigned BuiltinIDIfNoAsmLabel =
23132313
FD->hasAttr<AsmLabelAttr>() ? 0 : BuiltinID;
23142314

2315-
bool ErrnoOverriden = false;
2316-
// True if math-errno is overriden via the
2315+
std::optional<bool> ErrnoOverriden;
2316+
// ErrnoOverriden is true if math-errno is overriden via the
23172317
// '#pragma float_control(precise, on)'. This pragma disables fast-math,
23182318
// which implies math-errno.
23192319
if (E->hasStoredFPFeatures()) {
@@ -2329,8 +2329,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
23292329
// using the '#pragma float_control(precise, off)', and
23302330
// attribute opt-none hasn't been seen.
23312331
bool ErrnoOverridenToFalseWithOpt =
2332-
!ErrnoOverriden && !OptNone &&
2333-
CGM.getCodeGenOpts().OptimizationLevel != 0;
2332+
ErrnoOverriden.has_value() && !ErrnoOverriden.value() && !OptNone &&
2333+
CGM.getCodeGenOpts().OptimizationLevel != 0;
23342334

23352335
// There are LLVM math intrinsics/instructions corresponding to math library
23362336
// 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,
23392339
// LLVM counterparts if the call is marked 'const' (known to never set errno).
23402340
// In case FP exceptions are enabled, the experimental versions of the
23412341
// intrinsics model those.
2342+
bool ConstAlways =
2343+
getContext().BuiltinInfo.isConst(BuiltinID);
2344+
2345+
// There's a special case with the fma builtins where they are always const
2346+
// if the target environment is GNU or the target is OS is Windows and we're
2347+
// targeting the MSVCRT.dll environment.
2348+
// FIXME: This list can be become outdated. Need to find a way to get it some
2349+
// other way.
2350+
switch (BuiltinID) {
2351+
case Builtin::BI__builtin_fma:
2352+
case Builtin::BI__builtin_fmaf:
2353+
case Builtin::BI__builtin_fmal:
2354+
case Builtin::BIfma:
2355+
case Builtin::BIfmaf:
2356+
case Builtin::BIfmal: {
2357+
auto &Trip = CGM.getTriple();
2358+
if (Trip.isGNUEnvironment() || Trip.isOSMSVCRT())
2359+
ConstAlways = true;
2360+
break;
2361+
}
2362+
default:
2363+
break;
2364+
}
2365+
23422366
bool ConstWithoutErrnoAndExceptions =
23432367
getContext().BuiltinInfo.isConstWithoutErrnoAndExceptions(BuiltinID);
23442368
bool ConstWithoutExceptions =
@@ -2362,14 +2386,17 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
23622386
bool ConstWithoutErrnoOrExceptions =
23632387
ConstWithoutErrnoAndExceptions || ConstWithoutExceptions;
23642388
bool GenerateIntrinsics =
2365-
FD->hasAttr<ConstAttr>() && !ErrnoOverriden && !OptNone;
2389+
(ConstAlways && !OptNone) ||
2390+
(!getLangOpts().MathErrno &&
2391+
!(ErrnoOverriden.has_value() && ErrnoOverriden.value()) && !OptNone);
23662392
if (!GenerateIntrinsics) {
23672393
GenerateIntrinsics =
23682394
ConstWithoutErrnoOrExceptions && !ConstWithoutErrnoAndExceptions;
23692395
if (!GenerateIntrinsics)
23702396
GenerateIntrinsics =
23712397
ConstWithoutErrnoOrExceptions &&
2372-
(!getLangOpts().MathErrno && !ErrnoOverriden && !OptNone);
2398+
(!getLangOpts().MathErrno &&
2399+
!(ErrnoOverriden.has_value() && ErrnoOverriden.value()) && !OptNone);
23732400
if (!GenerateIntrinsics)
23742401
GenerateIntrinsics =
23752402
ConstWithoutErrnoOrExceptions && ErrnoOverridenToFalseWithOpt;

clang/test/CodeGen/math-builtins.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm %s | FileCheck %s -check-prefix=NO__ERRNO
22
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s -check-prefix=HAS_ERRNO
3+
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm -disable-llvm-passes -O2 %s | FileCheck %s -check-prefix=NO__ERRNO
4+
// 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
35
// RUN: %clang_cc1 -triple x86_64-unknown-unknown-gnu -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_GNU
46
// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s --check-prefix=HAS_ERRNO_WIN
57

clang/test/CodeGen/math-libcalls.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-implicit-function-declaration -w -S -o - -emit-llvm %s | FileCheck %s --check-prefix=NO__ERRNO
22
// 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
3+
// 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
4+
// 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
35
// 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
46
// 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
57
// 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

0 commit comments

Comments
 (0)