virtual void AddCCKextLibArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const;
+ /// If a runtime library exists that sets global flags for unsafe floating
+ /// point math, return true.
+ ///
+ /// This checks for presence of the -Ofast, -ffast-math or -funsafe-math flags.
+ virtual bool isFastMathRuntimeAvailable(
+ const llvm::opt::ArgList &Args, std::string &Path) const;
+
/// AddFastMathRuntimeIfAvailable - If a runtime library exists that sets
/// global flags for unsafe floating point math, add it and return true.
///
/// This checks for presence of the -Ofast, -ffast-math or -funsafe-math flags.
- virtual bool AddFastMathRuntimeIfAvailable(
- const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const;
+ bool addFastMathRuntimeIfAvailable(
+ const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const;
/// addProfileRTLibs - When -fprofile-instr-profile is specified, try to pass
/// a suitable profile runtime library to the linker.
CmdArgs.push_back("-lcc_kext");
}
-bool ToolChain::AddFastMathRuntimeIfAvailable(const ArgList &Args,
- ArgStringList &CmdArgs) const {
+bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args,
+ std::string &Path) const {
// Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed
// (to keep the linker options consistent with gcc and clang itself).
if (!isOptimizationLevelFast(Args)) {
// Check if -ffast-math or -funsafe-math.
Arg *A =
- Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math,
- options::OPT_funsafe_math_optimizations,
- options::OPT_fno_unsafe_math_optimizations);
+ Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math,
+ options::OPT_funsafe_math_optimizations,
+ options::OPT_fno_unsafe_math_optimizations);
if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
return false;
}
// If crtfastmath.o exists add it to the arguments.
- std::string Path = GetFilePath("crtfastmath.o");
- if (Path == "crtfastmath.o") // Not found.
- return false;
+ Path = GetFilePath("crtfastmath.o");
+ return (Path != "crtfastmath.o"); // Not found.
+}
+
+bool ToolChain::addFastMathRuntimeIfAvailable(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+ std::string Path;
+ if (isFastMathRuntimeAvailable(Args, Path)) {
+ CmdArgs.push_back(Args.MakeArgString(Path));
+ return true;
+ }
- CmdArgs.push_back(Args.MakeArgString(Path));
- return true;
+ return false;
}
SanitizerMask ToolChain::getSupportedSanitizers() const {
}
// Add crtfastmath.o if available and fast math is enabled.
- ToolChain.AddFastMathRuntimeIfAvailable(Args, CmdArgs);
+ ToolChain.addFastMathRuntimeIfAvailable(Args, CmdArgs);
}
Args.AddAllArgs(CmdArgs, options::OPT_L);
Twine("-u", llvm::getInstrProfRuntimeHookVarName())));
ToolChain::addProfileRTLibs(Args, CmdArgs);
}
+
+llvm::DenormalMode Linux::getDefaultDenormalModeForType(
+ const llvm::opt::ArgList &DriverArgs,
+ Action::OffloadKind DeviceOffloadKind,
+ const llvm::fltSemantics *FPType) const {
+ switch (getTriple().getArch()) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64: {
+ std::string Unused;
+ // DAZ and FTZ are turned on in crtfastmath.o
+ if (!DriverArgs.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
+ isFastMathRuntimeAvailable(DriverArgs, Unused))
+ return llvm::DenormalMode::getPreserveSign();
+ return llvm::DenormalMode::getIEEE();
+ }
+ default:
+ return llvm::DenormalMode::getIEEE();
+ }
+}
std::vector<std::string> ExtraOpts;
+ llvm::DenormalMode getDefaultDenormalModeForType(
+ const llvm::opt::ArgList &DriverArgs,
+ Action::OffloadKind DeviceOffloadKind,
+ const llvm::fltSemantics *FPType = nullptr) const override;
+
protected:
Tool *buildAssembler() const override;
Tool *buildLinker() const override;
if (!Args.hasArg(options::OPT_nostartfiles)) {
// Add crtfastmath.o if available and fast math is enabled.
- TC.AddFastMathRuntimeIfAvailable(Args, CmdArgs);
+ TC.addFastMathRuntimeIfAvailable(Args, CmdArgs);
CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtend.o")));
}
// capable of unit splitting.
bool canSplitThinLTOUnit() const override { return false; }
+ llvm::DenormalMode getDefaultDenormalModeForType(
+ const llvm::opt::ArgList &DriverArgs,
+ Action::OffloadKind DeviceOffloadKind,
+ const llvm::fltSemantics *FPType) const override {
+ // DAZ and FTZ are on by default.
+ return llvm::DenormalMode::getPreserveSign();
+ }
+
protected:
Tool *buildAssembler() const override;
Tool *buildLinker() const override;
--- /dev/null
+// RUN: %clang -### -target arm-unknown-linux-gnu -c %s -v 2>&1 | FileCheck -check-prefix=CHECK-IEEE %s
+// RUN: %clang -### -target i386-unknown-linux-gnu -c %s -v 2>&1 | FileCheck -check-prefix=CHECK-IEEE %s
+
+// RUN: %clang -### -target x86_64-unknown-linux-gnu --sysroot=%S/Inputs/basic_linux_tree -c %s -v 2>&1 | FileCheck -check-prefix=CHECK-IEEE %s
+
+// crtfastmath enables ftz and daz
+// RUN: %clang -### -target x86_64-unknown-linux-gnu -ffast-math --sysroot=%S/Inputs/basic_linux_tree -c %s -v 2>&1 | FileCheck -check-prefix=CHECK-PRESERVESIGN %s
+
+// crt not linked in with nostartfiles
+// RUN: %clang -### -target x86_64-unknown-linux-gnu -ffast-math -nostartfiles --sysroot=%S/Inputs/basic_linux_tree -c %s -v 2>&1 | FileCheck -check-prefix=CHECK-IEEE %s
+
+// If there's no crtfastmath, don't assume ftz/daz
+// RUN: %clang -### -target x86_64-unknown-linux-gnu -ffast-math --sysroot=/dev/null -c %s -v 2>&1 | FileCheck -check-prefix=CHECK-IEEE %s
+
+// RUN: %clang -### -target x86_64-scei-ps4 -c %s -v 2>&1 | FileCheck -check-prefix=CHECK-PRESERVESIGN %s
+
+
+// CHECK-IEEE: -fdenormal-fp-math=ieee,ieee
+// CHECK-PRESERVESIGN: -fdenormal-fp-math=preserve-sign,preserve-sign