From 0ab5b5b8581d9f2951575f7245824e6e4fc57dec Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Wed, 11 Mar 2020 17:12:20 -0400 Subject: [PATCH] Fix denormal-fp-math flag and attribute interaction Make these behave the same way unsafe-fp-math and co. The command line flag should add the attribute to functions that do not already have it, and leave existing attributes. The attribute is the actual implementation, but the flag is useful in some testing situations. AMDGPU has a variety of tests with denormals enabled/disabled that would require a painful level of test duplication without a flag. This doesn't expose setting the separate input/output modes, or add a flag for the f32 version yet. Tests will be included in future patch. --- llvm/include/llvm/CodeGen/CommandFlags.h | 3 ++- llvm/include/llvm/Target/TargetOptions.h | 43 +++++++++++++++++++++----------- llvm/lib/CodeGen/CommandFlags.cpp | 28 +++++++++++++++------ llvm/lib/Target/ARM/ARMAsmPrinter.cpp | 9 +++---- 4 files changed, 55 insertions(+), 28 deletions(-) diff --git a/llvm/include/llvm/CodeGen/CommandFlags.h b/llvm/include/llvm/CodeGen/CommandFlags.h index cdec268..f6d2216 100644 --- a/llvm/include/llvm/CodeGen/CommandFlags.h +++ b/llvm/include/llvm/CodeGen/CommandFlags.h @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/FloatingPointMode.h" #include "llvm/ADT/StringExtras.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" @@ -62,7 +63,7 @@ bool getEnableNoSignedZerosFPMath(); bool getEnableNoTrappingFPMath(); -llvm::FPDenormal::DenormalMode getDenormalFPMath(); +DenormalMode::DenormalModeKind getDenormalFPMath(); bool getEnableHonorSignDependentRoundingFPMath(); diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h index 7282040..b7c5fb2 100644 --- a/llvm/include/llvm/Target/TargetOptions.h +++ b/llvm/include/llvm/Target/TargetOptions.h @@ -14,11 +14,13 @@ #ifndef LLVM_TARGET_TARGETOPTIONS_H #define LLVM_TARGET_TARGETOPTIONS_H +#include "llvm/ADT/FloatingPointMode.h" #include "llvm/MC/MCTargetOptions.h" #include namespace llvm { + struct fltSemantics; class MachineFunction; class MemoryBuffer; class Module; @@ -57,15 +59,6 @@ namespace llvm { }; } - 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 BasicBlockSection { All, // Use Basic Block Sections for all basic blocks. A section // for every basic block can significantly bloat object file sizes. @@ -134,8 +127,7 @@ namespace llvm { EmulatedTLS(false), ExplicitEmulatedTLS(false), EnableIPRA(false), EmitStackSizeSection(false), EnableMachineOutliner(false), SupportsDefaultOutlining(false), EmitAddrsig(false), - EmitCallSiteInfo(false), SupportsDebugEntryValues(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 @@ -336,9 +328,32 @@ namespace llvm { /// 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; diff --git a/llvm/lib/CodeGen/CommandFlags.cpp b/llvm/lib/CodeGen/CommandFlags.cpp index d5dc49a..d1540af 100644 --- a/llvm/lib/CodeGen/CommandFlags.cpp +++ b/llvm/lib/CodeGen/CommandFlags.cpp @@ -54,7 +54,7 @@ CGOPT(bool, EnableNoInfsFPMath) CGOPT(bool, EnableNoNaNsFPMath) CGOPT(bool, EnableNoSignedZerosFPMath) CGOPT(bool, EnableNoTrappingFPMath) -CGOPT(FPDenormal::DenormalMode, DenormalFPMath) +CGOPT(DenormalMode::DenormalModeKind, DenormalFPMath) CGOPT(bool, EnableHonorSignDependentRoundingFPMath) CGOPT(FloatABI::ABIType, FloatABIForCalls) CGOPT(FPOpFusion::FPOpFusionMode, FuseFPOps) @@ -212,17 +212,17 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() { cl::init(false)); CGBINDOPT(EnableNoTrappingFPMath); - static cl::opt DenormalFPMath( + static cl::opt DenormalFPMath( "denormal-fp-math", cl::desc( "Select which denormal numbers the code is permitted to require"), - cl::init(FPDenormal::IEEE), + cl::init(DenormalMode::IEEE), cl::values( - clEnumValN(FPDenormal::IEEE, "ieee", "IEEE 754 denormal numbers"), - clEnumValN(FPDenormal::PreserveSign, "preserve-sign", + clEnumValN(DenormalMode::IEEE, "ieee", "IEEE 754 denormal numbers"), + 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"))); CGBINDOPT(DenormalFPMath); @@ -425,7 +425,12 @@ TargetOptions codegen::InitTargetOptionsFromCodeGenFlags() { Options.NoNaNsFPMath = getEnableNoNaNsFPMath(); Options.NoSignedZerosFPMath = getEnableNoSignedZerosFPMath(); Options.NoTrappingFPMath = getEnableNoTrappingFPMath(); - Options.FPDenormalMode = getDenormalFPMath(); + + DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath(); + + // FIXME: Should have separate input and output flags + Options.setFPDenormalMode(DenormalMode(DenormKind, DenormKind)); + Options.HonorSignDependentRoundingFPMathOption = getEnableHonorSignDependentRoundingFPMath(); if (getFloatABIForCalls() != FloatABI::Default) @@ -563,6 +568,15 @@ void codegen::setFunctionAttributes(StringRef CPU, StringRef Features, HANDLE_BOOL_ATTR(EnableNoNaNsFPMathView, "no-nans-fp-math"); HANDLE_BOOL_ATTR(EnableNoSignedZerosFPMathView, "no-signed-zeros-fp-math"); + if (DenormalFPMathView->getNumOccurrences() > 0 && + !F.hasFnAttribute("denormal-fp-math")) { + DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath(); + + // FIXME: Command line flag should expose separate input/output modes. + NewAttrs.addAttribute("denormal-fp-math", + DenormalMode(DenormKind, DenormKind).str()); + } + if (TrapFuncNameView->getNumOccurrences() > 0) for (auto &B : F) for (auto &I : B) diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp index f6ccdf1..1342f2b 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -652,16 +652,13 @@ void ARMAsmPrinter::emitAttributes() { } // Set FP Denormals. - if (checkDenormalAttributeConsistency(*MMI->getModule(), - "denormal-fp-math", - DenormalMode::getPreserveSign()) || - TM.Options.FPDenormalMode == FPDenormal::PreserveSign) + if (checkDenormalAttributeConsistency(*MMI->getModule(), "denormal-fp-math", + DenormalMode::getPreserveSign())) ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, ARMBuildAttrs::PreserveFPSign); else if (checkDenormalAttributeConsistency(*MMI->getModule(), "denormal-fp-math", - DenormalMode::getPositiveZero()) || - TM.Options.FPDenormalMode == FPDenormal::PositiveZero) + DenormalMode::getPositiveZero())) ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, ARMBuildAttrs::PositiveZero); else if (!TM.Options.UnsafeFPMath) -- 2.7.4