|
41 | 41 | #include "clang/Driver/SanitizerArgs.h" |
42 | 42 | #include "clang/Driver/Types.h" |
43 | 43 | #include "clang/Driver/XRayArgs.h" |
| 44 | +#include "llvm/ADT/ScopeExit.h" |
44 | 45 | #include "llvm/ADT/SmallSet.h" |
45 | 46 | #include "llvm/ADT/StringExtras.h" |
46 | 47 | #include "llvm/BinaryFormat/Magic.h" |
@@ -2854,6 +2855,14 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, |
2854 | 2855 | bool OFastEnabled, const ArgList &Args, |
2855 | 2856 | ArgStringList &CmdArgs, |
2856 | 2857 | const JobAction &JA) { |
| 2858 | + // List of veclibs which when used with -fveclib imply -fno-math-errno. |
| 2859 | + constexpr std::array VecLibImpliesNoMathErrno{llvm::StringLiteral("ArmPL"), |
| 2860 | + llvm::StringLiteral("SLEEF")}; |
| 2861 | + bool NoMathErrnoWasImpliedByVecLib = false; |
| 2862 | + const Arg *VecLibArg = nullptr; |
| 2863 | + // Track the arg (if any) that enabled errno after -fveclib for diagnostics. |
| 2864 | + const Arg *ArgThatEnabledMathErrnoAfterVecLib = nullptr; |
| 2865 | + |
2857 | 2866 | // Handle various floating point optimization flags, mapping them to the |
2858 | 2867 | // appropriate LLVM code generation flags. This is complicated by several |
2859 | 2868 | // "umbrella" flags, so we do this by stepping through the flags incrementally |
@@ -2960,6 +2969,12 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, |
2960 | 2969 | } |
2961 | 2970 |
|
2962 | 2971 | for (const Arg *A : Args) { |
| 2972 | + auto CheckMathErrnoForVecLib = |
| 2973 | + llvm::make_scope_exit([&, MathErrnoBeforeArg = MathErrno] { |
| 2974 | + if (NoMathErrnoWasImpliedByVecLib && !MathErrnoBeforeArg && MathErrno) |
| 2975 | + ArgThatEnabledMathErrnoAfterVecLib = A; |
| 2976 | + }); |
| 2977 | + |
2963 | 2978 | switch (A->getOption().getID()) { |
2964 | 2979 | // If this isn't an FP option skip the claim below |
2965 | 2980 | default: continue; |
@@ -3125,6 +3140,13 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, |
3125 | 3140 | TrappingMathPresent = true; |
3126 | 3141 | FPExceptionBehavior = "strict"; |
3127 | 3142 | break; |
| 3143 | + case options::OPT_fveclib: |
| 3144 | + VecLibArg = A; |
| 3145 | + NoMathErrnoWasImpliedByVecLib = |
| 3146 | + llvm::is_contained(VecLibImpliesNoMathErrno, A->getValue()); |
| 3147 | + if (NoMathErrnoWasImpliedByVecLib) |
| 3148 | + MathErrno = false; |
| 3149 | + break; |
3128 | 3150 | case options::OPT_fno_trapping_math: |
3129 | 3151 | if (!TrappingMathPresent && !FPExceptionBehavior.empty() && |
3130 | 3152 | FPExceptionBehavior != "ignore") |
@@ -3338,8 +3360,13 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, |
3338 | 3360 | if (ApproxFunc) |
3339 | 3361 | CmdArgs.push_back("-fapprox-func"); |
3340 | 3362 |
|
3341 | | - if (MathErrno) |
| 3363 | + if (MathErrno) { |
3342 | 3364 | CmdArgs.push_back("-fmath-errno"); |
| 3365 | + if (NoMathErrnoWasImpliedByVecLib) |
| 3366 | + D.Diag(clang::diag::warn_drv_math_errno_enabled_after_veclib) |
| 3367 | + << ArgThatEnabledMathErrnoAfterVecLib->getAsString(Args) |
| 3368 | + << VecLibArg->getAsString(Args); |
| 3369 | + } |
3343 | 3370 |
|
3344 | 3371 | if (AssociativeMath && ReciprocalMath && !SignedZeros && ApproxFunc && |
3345 | 3372 | !TrappingMath) |
|
0 commit comments