Index: llvm/include/llvm/CodeGen/CommandFlags.inc =================================================================== --- llvm/include/llvm/CodeGen/CommandFlags.inc +++ llvm/include/llvm/CodeGen/CommandFlags.inc @@ -151,16 +151,17 @@ "attribute not to use exceptions"), cl::init(false)); -static cl::opt DenormalFPMath( +// FIXME: Doesn't have way to specify separate input and output modes. +static cl::opt DenormalFPMath( "denormal-fp-math", cl::desc("Select which denormal numbers the code is permitted to require"), - cl::init(FPDenormal::IEEE), - cl::values(clEnumValN(FPDenormal::IEEE, "ieee", + cl::init(DenormalMode::IEEE), + cl::values(clEnumValN(DenormalMode::IEEE, "ieee", "IEEE 754 denormal numbers"), - clEnumValN(FPDenormal::PreserveSign, "preserve-sign", + clEnumValN(DenormalMode::PreserveSign, "preserve-sign", "the sign of a flushed-to-zero number is preserved " "in the sign of 0"), - clEnumValN(FPDenormal::PositiveZero, "positive-zero", + clEnumValN(DenormalMode::PositiveZero, "positive-zero", "denormals are flushed to positive zero"))); static cl::opt EnableHonorSignDependentRoundingFPMath( @@ -291,7 +292,10 @@ Options.NoNaNsFPMath = EnableNoNaNsFPMath; Options.NoSignedZerosFPMath = EnableNoSignedZerosFPMath; Options.NoTrappingFPMath = EnableNoTrappingFPMath; - Options.FPDenormalMode = DenormalFPMath; + + // FIXME: Should have separate input and output flags + Options.setFPDenormalMode(DenormalMode(DenormalFPMath, DenormalFPMath)); + Options.HonorSignDependentRoundingFPMathOption = EnableHonorSignDependentRoundingFPMath; if (FloatABIForCalls != FloatABI::Default) Index: llvm/include/llvm/CodeGen/MachineFunction.h =================================================================== --- llvm/include/llvm/CodeGen/MachineFunction.h +++ llvm/include/llvm/CodeGen/MachineFunction.h @@ -575,10 +575,6 @@ return const_cast(this)->getInfo(); } - /// Returns the denormal handling type for the default rounding mode of the - /// function. - DenormalMode getDenormalMode(const fltSemantics &FPType) const; - /// getBlockNumbered - MachineBasicBlocks are automatically numbered when they /// are inserted into the machine function. The block number for a machine /// basic block can be found by using the MBB::getNumber method, this method Index: llvm/include/llvm/CodeGen/SelectionDAG.h =================================================================== --- llvm/include/llvm/CodeGen/SelectionDAG.h +++ llvm/include/llvm/CodeGen/SelectionDAG.h @@ -1730,9 +1730,7 @@ /// Return the current function's default denormal handling kind for the given /// floating point type. - DenormalMode getDenormalMode(EVT VT) const { - return MF->getDenormalMode(EVTToAPFloatSemantics(VT)); - } + DenormalMode getDenormalMode(EVT VT) const; bool shouldOptForSize() const; Index: llvm/include/llvm/Target/TargetOptions.h =================================================================== --- llvm/include/llvm/Target/TargetOptions.h +++ llvm/include/llvm/Target/TargetOptions.h @@ -14,6 +14,7 @@ #ifndef LLVM_TARGET_TARGETOPTIONS_H #define LLVM_TARGET_TARGETOPTIONS_H +#include "llvm/ADT/FloatingPointMode.h" #include "llvm/MC/MCTargetOptions.h" namespace llvm { @@ -54,15 +55,6 @@ }; } - namespace FPDenormal { - enum DenormalMode { - IEEE, // IEEE 754 denormal numbers - PreserveSign, // the sign of a flushed-to-zero number is preserved in - // the sign of 0 - PositiveZero // denormals are flushed to positive zero - }; - } - enum class EABI { Unknown, Default, // Default means not specified @@ -119,7 +111,8 @@ ExplicitEmulatedTLS(false), EnableIPRA(false), EmitStackSizeSection(false), EnableMachineOutliner(false), SupportsDefaultOutlining(false), EmitAddrsig(false), - EnableDebugEntryValues(false), ForceDwarfFrameSection(false) {} + EnableDebugEntryValues(false), ForceDwarfFrameSection(false), + FPDenormalMode(DenormalMode::IEEE, DenormalMode::IEEE) {} /// PrintMachineCode - This flag is enabled when the -print-machineinstrs /// option is specified on the command line, and should enable debugging @@ -295,9 +288,32 @@ /// Which debugger to tune for. DebuggerKind DebuggerTuning = DebuggerKind::Default; - /// FPDenormalMode - This flags specificies which denormal numbers the code - /// is permitted to require. - FPDenormal::DenormalMode FPDenormalMode = FPDenormal::IEEE; + private: + /// Flushing mode to assume in default FP environment. + DenormalMode FPDenormalMode; + + /// Flushing mode to assume in default FP environment, for float/vector of + /// float. + DenormalMode FP32DenormalMode; + + public: + void setFPDenormalMode(DenormalMode Mode) { + FPDenormalMode = Mode; + } + + void setFP32DenormalMode(DenormalMode Mode) { + FP32DenormalMode = Mode; + } + + DenormalMode getRawFPDenormalMode() const { + return FPDenormalMode; + } + + DenormalMode getRawFP32DenormalMode() const { + return FP32DenormalMode; + } + + DenormalMode getDenormalMode(const fltSemantics &FPType) const; /// What exception model to use ExceptionHandling ExceptionModel = ExceptionHandling::None; Index: llvm/lib/CodeGen/MachineFunction.cpp =================================================================== --- llvm/lib/CodeGen/MachineFunction.cpp +++ llvm/lib/CodeGen/MachineFunction.cpp @@ -270,23 +270,6 @@ return JumpTableInfo; } -DenormalMode MachineFunction::getDenormalMode(const fltSemantics &FPType) const { - if (&FPType == &APFloat::IEEEsingle()) { - Attribute Attr = F.getFnAttribute("denormal-fp-math-f32"); - StringRef Val = Attr.getValueAsString(); - if (!Val.empty()) - return parseDenormalFPAttribute(Val); - - // If the f32 variant of the attribute isn't specified, try to use the - // generic one. - } - - // TODO: Should probably avoid the connection to the IR and store directly - // in the MachineFunction. - Attribute Attr = F.getFnAttribute("denormal-fp-math"); - return parseDenormalFPAttribute(Attr.getValueAsString()); -} - /// Should we be emitting segmented stack stuff for the function bool MachineFunction::shouldSplitStack() const { return getFunction().hasFnAttribute("split-stack"); Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1030,6 +1030,10 @@ delete DbgInfo; } +DenormalMode SelectionDAG::getDenormalMode(EVT VT) const { + return TM.Options.getDenormalMode(EVTToAPFloatSemantics(VT)); +} + bool SelectionDAG::shouldOptForSize() const { return MF->getFunction().hasOptSize() || llvm::shouldOptimizeForSize(FLI->MBB->getBasicBlock(), PSI, BFI); Index: llvm/lib/CodeGen/TargetOptionsImpl.cpp =================================================================== --- llvm/lib/CodeGen/TargetOptionsImpl.cpp +++ llvm/lib/CodeGen/TargetOptionsImpl.cpp @@ -57,3 +57,9 @@ bool TargetOptions::HonorSignDependentRoundingFPMath() const { return !UnsafeFPMath && HonorSignDependentRoundingFPMathOption; } + +DenormalMode TargetOptions::getDenormalMode(const fltSemantics &FPType) const { + if (&FPType == &APFloat::IEEEsingle() && FP32DenormalMode.isValid()) + return FP32DenormalMode; + return FPDenormalMode; +} Index: llvm/lib/Target/ARM/ARMAsmPrinter.cpp =================================================================== --- llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -643,14 +643,14 @@ // Set FP Denormals. if (checkFunctionsAttributeConsistency(*MMI->getModule(), "denormal-fp-math", - "preserve-sign") || - TM.Options.FPDenormalMode == FPDenormal::PreserveSign) + "preserve-sign,preserve-sign") || + TM.Options.getRawFPDenormalMode() == DenormalMode::getPreserveSign()) ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, ARMBuildAttrs::PreserveFPSign); else if (checkFunctionsAttributeConsistency(*MMI->getModule(), "denormal-fp-math", - "positive-zero") || - TM.Options.FPDenormalMode == FPDenormal::PositiveZero) + "positive-zero,positive-zero") || + TM.Options.getRawFPDenormalMode() == DenormalMode::getPositiveZero()) ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, ARMBuildAttrs::PositiveZero); else if (!TM.Options.UnsafeFPMath) Index: llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp =================================================================== --- llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp +++ llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp @@ -122,7 +122,7 @@ return FtzEnabled; } - return MF.getDenormalMode(APFloat::IEEEsingle()).Output == + return getTargetMachine().Options.getDenormalMode(APFloat::IEEEsingle()).Output == DenormalMode::PreserveSign; } Index: llvm/lib/Target/TargetMachine.cpp =================================================================== --- llvm/lib/Target/TargetMachine.cpp +++ llvm/lib/Target/TargetMachine.cpp @@ -63,6 +63,20 @@ RESET_OPTION(NoInfsFPMath, "no-infs-fp-math"); RESET_OPTION(NoNaNsFPMath, "no-nans-fp-math"); RESET_OPTION(NoSignedZerosFPMath, "no-signed-zeros-fp-math"); + + Options.setFP32DenormalMode(DenormalMode::getInvalid()); + if (F.hasFnAttribute("denormal-fp-math-f32")) { + Options.setFPDenormalMode( + parseDenormalFPAttribute( + F.getFnAttribute("denormal-fp-math-f32").getValueAsString())); + } + + if (F.hasFnAttribute("denormal-fp-math")) { + Options.setFPDenormalMode( + parseDenormalFPAttribute( + F.getFnAttribute("denormal-fp-math").getValueAsString())); + } else + Options.setFPDenormalMode(DefaultOptions.getRawFPDenormalMode()); } /// Returns the code generation relocation model. The choices are static, PIC,