diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 68722ad963312..65551bd7761a9 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -502,6 +502,10 @@ def err_sls_hardening_arm_not_supported : Error< def warn_drv_large_data_threshold_invalid_code_model: Warning< "'%0' only applies to medium and large code models">, InGroup; +def warn_drv_math_errno_enabled_after_veclib: Warning< + "math errno enabled by '%0' after it was implicitly disabled by '%1'," + " this may limit the utilization of the vector library">, + InGroup; def note_drv_command_failed_diag_msg : Note< "diagnostic msg: %0">; diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 8273701e7b096..72eada50a56cc 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -125,6 +125,7 @@ def FloatZeroConversion : DiagGroup<"float-zero-conversion">; def FloatConversion : DiagGroup<"float-conversion", [FloatOverflowConversion, FloatZeroConversion]>; +def MathErrnoEnabledWithVecLib : DiagGroup<"math-errno-enabled-with-veclib">; def FrameAddress : DiagGroup<"frame-address">; def FreeNonHeapObject : DiagGroup<"free-nonheap-object">; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 70f2fb6bdc4db..0cb7c0c0ae04f 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3411,6 +3411,9 @@ def fno_experimental_isel : Flag<["-"], "fno-experimental-isel">, Group, + HelpTextForVariants<[ClangOption, CC1Option], + "Use the given vector functions library. " + "Note: -fveclib={ArmPL,SLEEF} implies -fno-math-errno">, Values<"Accelerate,libmvec,MASSV,SVML,SLEEF,Darwin_libsystem_m,ArmPL,AMDLIBM,none">, NormalizedValuesScope<"llvm::driver::VectorLibrary">, NormalizedValues<["Accelerate", "LIBMVEC", "MASSV", "SVML", "SLEEF", diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index d032fd7a59f33..06c44a660e98f 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -41,6 +41,7 @@ #include "clang/Driver/SanitizerArgs.h" #include "clang/Driver/Types.h" #include "clang/Driver/XRayArgs.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringExtras.h" #include "llvm/BinaryFormat/Magic.h" @@ -2854,6 +2855,14 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, bool OFastEnabled, const ArgList &Args, ArgStringList &CmdArgs, const JobAction &JA) { + // List of veclibs which when used with -fveclib imply -fno-math-errno. + constexpr std::array VecLibImpliesNoMathErrno{llvm::StringLiteral("ArmPL"), + llvm::StringLiteral("SLEEF")}; + bool NoMathErrnoWasImpliedByVecLib = false; + const Arg *VecLibArg = nullptr; + // Track the arg (if any) that enabled errno after -fveclib for diagnostics. + const Arg *ArgThatEnabledMathErrnoAfterVecLib = nullptr; + // Handle various floating point optimization flags, mapping them to the // appropriate LLVM code generation flags. This is complicated by several // "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, } for (const Arg *A : Args) { + auto CheckMathErrnoForVecLib = + llvm::make_scope_exit([&, MathErrnoBeforeArg = MathErrno] { + if (NoMathErrnoWasImpliedByVecLib && !MathErrnoBeforeArg && MathErrno) + ArgThatEnabledMathErrnoAfterVecLib = A; + }); + switch (A->getOption().getID()) { // If this isn't an FP option skip the claim below default: continue; @@ -3125,6 +3140,13 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, TrappingMathPresent = true; FPExceptionBehavior = "strict"; break; + case options::OPT_fveclib: + VecLibArg = A; + NoMathErrnoWasImpliedByVecLib = + llvm::is_contained(VecLibImpliesNoMathErrno, A->getValue()); + if (NoMathErrnoWasImpliedByVecLib) + MathErrno = false; + break; case options::OPT_fno_trapping_math: if (!TrappingMathPresent && !FPExceptionBehavior.empty() && FPExceptionBehavior != "ignore") @@ -3338,8 +3360,13 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D, if (ApproxFunc) CmdArgs.push_back("-fapprox-func"); - if (MathErrno) + if (MathErrno) { CmdArgs.push_back("-fmath-errno"); + if (NoMathErrnoWasImpliedByVecLib) + D.Diag(clang::diag::warn_drv_math_errno_enabled_after_veclib) + << ArgThatEnabledMathErrnoAfterVecLib->getAsString(Args) + << VecLibArg->getAsString(Args); + } if (AssociativeMath && ReciprocalMath && !SignedZeros && ApproxFunc && !TrappingMath) diff --git a/clang/test/Driver/autocomplete.c b/clang/test/Driver/autocomplete.c index c8ceaaf404672..8cc604dbff875 100644 --- a/clang/test/Driver/autocomplete.c +++ b/clang/test/Driver/autocomplete.c @@ -114,6 +114,7 @@ // WARNING-NEXT: -Wmain-return-type // WARNING-NEXT: -Wmalformed-warning-check // WARNING-NEXT: -Wmany-braces-around-scalar-init +// WARNING-NEXT: -Wmath-errno-enabled-with-veclib // WARNING-NEXT: -Wmathematical-notation-identifier-extension // WARNING-NEXT: -Wmax-tokens // WARNING-NEXT: -Wmax-unsigned-zero diff --git a/clang/test/Driver/fveclib.c b/clang/test/Driver/fveclib.c index 9b0f1ce13aa2b..8b233b0023398 100644 --- a/clang/test/Driver/fveclib.c +++ b/clang/test/Driver/fveclib.c @@ -49,3 +49,56 @@ // RUN: %clang -### --target=aarch64-linux-gnu -fveclib=ArmPL -flto %s 2>&1 | FileCheck --check-prefix=CHECK-LTO-ARMPL %s // CHECK-LTO-ARMPL: "-plugin-opt=-vector-library=ArmPL" + + +/* Verify that -fmath-errno is set correctly for the vector library. */ + +// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fveclib=LIBMVEC %s 2>&1 | FileCheck --check-prefix=CHECK-ERRNO-LIBMVEC %s +// CHECK-ERRNO-LIBMVEC: "-fveclib=LIBMVEC" +// CHECK-ERRNO-LIBMVEC-SAME: "-fmath-errno" + +// RUN: %clang -### --target=powerpc64-unknown-linux-gnu -fveclib=MASSV %s 2>&1 | FileCheck --check-prefix=CHECK-ERRNO-MASSV %s +// CHECK-ERRNO-MASSV: "-fveclib=MASSV" +// CHECK-ERRNO-MASSV-SAME: "-fmath-errno" + +// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fveclib=SVML %s 2>&1 | FileCheck --check-prefix=CHECK-ERRNO-SVML %s +// CHECK-ERRNO-SVML: "-fveclib=SVML" +// CHECK-ERRNO-SVML-SAME: "-fmath-errno" + +// RUN: %clang -### --target=aarch64-linux-gnu -fveclib=SLEEF %s 2>&1 | FileCheck --check-prefix=CHECK-ERRNO-SLEEF %s +// CHECK-ERRNO-SLEEF-NOT: "-fmath-errno" +// CHECK-ERRNO-SLEEF: "-fveclib=SLEEF" +// CHECK-ERRNO-SLEEF-NOT: "-fmath-errno" + +// RUN: %clang -### --target=aarch64-linux-gnu -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-ERRNO-ARMPL %s +// CHECK-ERRNO-ARMPL-NOT: "-fmath-errno" +// CHECK-ERRNO-ARMPL: "-fveclib=ArmPL" +// CHECK-ERRNO-ARMPL-NOT: "-fmath-errno" + +// RUN: %clang -### --target=aarch64-linux-gnu -fveclib=ArmPL -fmath-errno %s 2>&1 | FileCheck --check-prefix=CHECK-REENABLE-ERRNO-ARMPL %s +// CHECK-REENABLE-ERRNO-ARMPL: math errno enabled by '-fmath-errno' after it was implicitly disabled by '-fveclib=ArmPL', this may limit the utilization of the vector library [-Wmath-errno-enabled-with-veclib] +// CHECK-REENABLE-ERRNO-ARMPL: "-fveclib=ArmPL" +// CHECK-REENABLE-ERRNO-ARMPL-SAME: "-fmath-errno" + +// RUN: %clang -### --target=aarch64-linux-gnu -fveclib=SLEEF -fmath-errno %s 2>&1 | FileCheck --check-prefix=CHECK-REENABLE-ERRNO-SLEEF %s +// CHECK-REENABLE-ERRNO-SLEEF: math errno enabled by '-fmath-errno' after it was implicitly disabled by '-fveclib=SLEEF', this may limit the utilization of the vector library [-Wmath-errno-enabled-with-veclib] +// CHECK-REENABLE-ERRNO-SLEEF: "-fveclib=SLEEF" +// CHECK-REENABLE-ERRNO-SLEEF-SAME: "-fmath-errno" + +// RUN: %clang -### --target=aarch64-linux-gnu -fveclib=ArmPL -fno-fast-math %s 2>&1 | FileCheck --check-prefix=CHECK-REENABLE-ERRNO-NFM %s +// CHECK-REENABLE-ERRNO-NFM: math errno enabled by '-fno-fast-math' after it was implicitly disabled by '-fveclib=ArmPL', this may limit the utilization of the vector library [-Wmath-errno-enabled-with-veclib] +// CHECK-REENABLE-ERRNO-NFM: "-fveclib=ArmPL" +// CHECK-REENABLE-ERRNO-NFM-SAME: "-fmath-errno" + +// RUN: %clang -### --target=aarch64-linux-gnu -fveclib=ArmPL -ffp-model=strict %s 2>&1 | FileCheck --check-prefix=CHECK-REENABLE-ERRNO-FP-MODEL %s +// CHECK-REENABLE-ERRNO-FP-MODEL: math errno enabled by '-ffp-model=strict' after it was implicitly disabled by '-fveclib=ArmPL', this may limit the utilization of the vector library [-Wmath-errno-enabled-with-veclib] +// CHECK-REENABLE-ERRNO-FP-MODEL: "-fveclib=ArmPL" +// CHECK-REENABLE-ERRNO-FP-MODEL-SAME: "-fmath-errno" + +/* Verify the warning points at the last arg to enable -fmath-errno. */ +// RUN: %clang -### --target=aarch64-linux-gnu -fveclib=ArmPL -fno-fast-math -fno-math-errno -ffp-model=strict %s 2>&1 | FileCheck --check-prefix=CHECK-ENABLED-LAST %s +// CHECK-ENABLED-LAST: math errno enabled by '-ffp-model=strict' after it was implicitly disabled by '-fveclib=ArmPL', this may limit the utilization of the vector library [-Wmath-errno-enabled-with-veclib] + +/* Verify no warning when math-errno is re-enabled for a different veclib (that does not imply -fno-math-errno). */ +// RUN: %clang -### --target=aarch64-linux-gnu -fveclib=ArmPL -fmath-errno -fveclib=LIBMVEC %s 2>&1 | FileCheck --check-prefix=CHECK-REPEAT-VECLIB %s +// CHECK-REPEAT-VECLIB-NOT: math errno enabled