-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Fix math-errno issue #66381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix math-errno issue #66381
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-codegen ChangesNone -- Full diff: https://github.com//pull/66381.diff3 Files Affected:
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 8b19bf85d47a19f..c69ccdb0eb522bf 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -2313,14 +2313,18 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, FD->hasAttr<AsmLabelAttr>() ? 0 : BuiltinID; bool ErrnoOverriden = false; + bool ErrnoOverrideValue = false; // 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()) { FPOptionsOverride OP = E->getFPFeatures(); - if (OP.hasMathErrnoOverride()) - ErrnoOverriden = OP.getMathErrnoOverride(); + if (OP.hasMathErrnoOverride()) { + ErrnoOverriden = true; + ErrnoOverrideValue = OP.getMathErrnoOverride(); + } } + // True if 'atttibute__((optnone)) is used. This attibute overrides // fast-math which implies math-errno. bool OptNone = CurFuncDecl && CurFuncDecl->hasAttr<OptimizeNoneAttr>(); @@ -2329,8 +2333,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 && !ErrnoOverrideValue && !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 +2343,28 @@ 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. + 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 +2388,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 && ErrnoOverrideValue) && + !OptNone); if (!GenerateIntrinsics) { GenerateIntrinsics = ConstWithoutErrnoOrExceptions && !ConstWithoutErrnoAndExceptions; if (!GenerateIntrinsics) GenerateIntrinsics = ConstWithoutErrnoOrExceptions && - (!getLangOpts().MathErrno && !ErrnoOverriden && !OptNone); + (!getLangOpts().MathErrno && + !(ErrnoOverriden && ErrnoOverrideValue) && !OptNone); if (!GenerateIntrinsics) GenerateIntrinsics = ConstWithoutErrnoOrExceptions && ErrnoOverridenToFalseWithOpt; diff --git a/clang/test/CodeGen/math-builtins.c b/clang/test/CodeGen/math-builtins.c index 962e311698f5755..554c604219957ca 100644 --- a/clang/test/CodeGen/math-builtins.c +++ b/clang/test/CodeGen/math-builtins.c @@ -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 diff --git a/clang/test/CodeGen/math-libcalls.c b/clang/test/CodeGen/math-libcalls.c index fa8f49d8a2c9ff4..02df4fe5fea6018 100644 --- a/clang/test/CodeGen/math-libcalls.c +++ b/clang/test/CodeGen/math-libcalls.c @@ -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 |
I've verified that this patch fixes the problem I (@uabelho in Phab) reported in Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic makes sense to me, but it would be nice if we had a second set of eyes on this given how dense the code is. @jcranmer-intel how does this seem to you?
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.