Index: clang/include/clang/Basic/CodeGenOptions.h =================================================================== --- clang/include/clang/Basic/CodeGenOptions.h +++ clang/include/clang/Basic/CodeGenOptions.h @@ -16,7 +16,7 @@ #include "clang/Basic/DebugInfoOptions.h" #include "clang/Basic/Sanitizers.h" #include "clang/Basic/XRayInstr.h" -#include "llvm/ADT/FloatingPointMode.h" +#include "llvm/IR/FPEnv.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/Regex.h" #include "llvm/Target/TargetOptions.h" @@ -164,10 +164,10 @@ std::string FloatABI; /// The floating-point denormal mode to use. - llvm::DenormalMode FPDenormalMode = llvm::DenormalMode::getIEEE(); + llvm::fp::DenormalMode FPDenormalMode = llvm::fp::DenormalMode::getIEEE(); /// The floating-point denormal mode to use, for float. - llvm::DenormalMode FP32DenormalMode = llvm::DenormalMode::getIEEE(); + llvm::fp::DenormalMode FP32DenormalMode = llvm::fp::DenormalMode::getIEEE(); /// The float precision limit to use, if non-empty. std::string LimitFloatPrecision; Index: clang/include/clang/Driver/ToolChain.h =================================================================== --- clang/include/clang/Driver/ToolChain.h +++ clang/include/clang/Driver/ToolChain.h @@ -18,10 +18,10 @@ #include "clang/Driver/Types.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/FloatingPointMode.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" +#include "llvm/IR/FPEnv.h" #include "llvm/MC/MCTargetOptions.h" #include "llvm/Option/Option.h" #include "llvm/Support/VersionTuple.h" @@ -635,11 +635,11 @@ /// Returns the output denormal handling type in the default floating point /// environment for the given \p FPType if given. Otherwise, the default /// assumed mode for any floating point type. - virtual llvm::DenormalMode getDefaultDenormalModeForType( + virtual llvm::fp::DenormalMode getDefaultDenormalModeForType( const llvm::opt::ArgList &DriverArgs, Action::OffloadKind DeviceOffloadKind, const llvm::fltSemantics *FPType = nullptr) const { - return llvm::DenormalMode::getIEEE(); + return llvm::fp::DenormalMode::getIEEE(); } }; Index: clang/lib/CodeGen/CGCall.cpp =================================================================== --- clang/lib/CodeGen/CGCall.cpp +++ clang/lib/CodeGen/CGCall.cpp @@ -1749,7 +1749,7 @@ if (CodeGenOpts.NullPointerIsValid) FuncAttrs.addAttribute("null-pointer-is-valid", "true"); - if (CodeGenOpts.FPDenormalMode != llvm::DenormalMode::getIEEE()) + if (CodeGenOpts.FPDenormalMode != llvm::fp::DenormalMode::getIEEE()) FuncAttrs.addAttribute("denormal-fp-math", CodeGenOpts.FPDenormalMode.str()); if (CodeGenOpts.FP32DenormalMode != CodeGenOpts.FPDenormalMode) { Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -594,7 +594,7 @@ // property.) getModule().addModuleFlag(llvm::Module::Override, "nvvm-reflect-ftz", CodeGenOpts.FP32DenormalMode.Output != - llvm::DenormalMode::IEEE); + llvm::fp::DenormalMode::IEEE); } // Emit OpenCL specific module metadata: OpenCL/SPIR version. Index: clang/lib/Driver/ToolChains/AMDGPU.h =================================================================== --- clang/lib/Driver/ToolChains/AMDGPU.h +++ clang/lib/Driver/ToolChains/AMDGPU.h @@ -73,7 +73,7 @@ /// for the subtarget. static bool getDefaultDenormsAreZeroForTarget(llvm::AMDGPU::GPUKind GPUKind); - llvm::DenormalMode getDefaultDenormalModeForType( + llvm::fp::DenormalMode getDefaultDenormalModeForType( const llvm::opt::ArgList &DriverArgs, Action::OffloadKind DeviceOffloadKind, const llvm::fltSemantics *FPType = nullptr) const override; Index: clang/lib/Driver/ToolChains/AMDGPU.cpp =================================================================== --- clang/lib/Driver/ToolChains/AMDGPU.cpp +++ clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -115,19 +115,19 @@ return !BothDenormAndFMAFast; } -llvm::DenormalMode AMDGPUToolChain::getDefaultDenormalModeForType( +llvm::fp::DenormalMode AMDGPUToolChain::getDefaultDenormalModeForType( const llvm::opt::ArgList &DriverArgs, Action::OffloadKind DeviceOffloadKind, const llvm::fltSemantics *FPType) const { // Denormals should always be enabled for f16 and f64. if (!FPType || FPType != &llvm::APFloat::IEEEsingle()) - return llvm::DenormalMode::getIEEE(); + return llvm::fp::DenormalMode::getIEEE(); if (DeviceOffloadKind == Action::OFK_Cuda) { if (FPType && FPType == &llvm::APFloat::IEEEsingle() && DriverArgs.hasFlag(options::OPT_fcuda_flush_denormals_to_zero, options::OPT_fno_cuda_flush_denormals_to_zero, false)) - return llvm::DenormalMode::getPreserveSign(); + return llvm::fp::DenormalMode::getPreserveSign(); } const StringRef GpuArch = DriverArgs.getLastArgValue(options::OPT_mcpu_EQ); @@ -138,8 +138,8 @@ bool DAZ = DriverArgs.hasArg(options::OPT_cl_denorms_are_zero) || getDefaultDenormsAreZeroForTarget(Kind); // Outputs are flushed to zero, preserving sign - return DAZ ? llvm::DenormalMode::getPreserveSign() : - llvm::DenormalMode::getIEEE(); + return DAZ ? llvm::fp::DenormalMode::getPreserveSign() + : llvm::fp::DenormalMode::getIEEE(); } void AMDGPUToolChain::addClangTargetOptions( Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -2533,14 +2533,14 @@ StringRef FPModel = ""; // -ffp-exception-behavior options: strict, maytrap, ignore StringRef FPExceptionBehavior = ""; - const llvm::DenormalMode DefaultDenormalFPMath = + const llvm::fp::DenormalMode DefaultDenormalFPMath = TC.getDefaultDenormalModeForType(Args, DeviceOffloadKind); - const llvm::DenormalMode DefaultDenormalFP32Math = + const llvm::fp::DenormalMode DefaultDenormalFP32Math = TC.getDefaultDenormalModeForType(Args, DeviceOffloadKind, &llvm::APFloat::IEEEsingle()); - llvm::DenormalMode DenormalFPMath = DefaultDenormalFPMath; - llvm::DenormalMode DenormalFP32Math = DefaultDenormalFP32Math; + llvm::fp::DenormalMode DenormalFPMath = DefaultDenormalFPMath; + llvm::fp::DenormalMode DenormalFP32Math = DefaultDenormalFP32Math; StringRef FPContract = ""; bool StrictFPModel = false; @@ -2567,11 +2567,11 @@ SignedZeros = true; // -fno_fast_math restores default denormal and fpcontract handling FPContract = ""; - DenormalFPMath = llvm::DenormalMode::getIEEE(); + DenormalFPMath = llvm::fp::DenormalMode::getIEEE(); // FIXME: The target may have picked a non-IEEE default mode here based on // -cl-denorms-are-zero. Should the target consider -fp-model interaction? - DenormalFP32Math = llvm::DenormalMode::getIEEE(); + DenormalFP32Math = llvm::fp::DenormalMode::getIEEE(); StringRef Val = A->getValue(); if (OFastEnabled && !Val.equals("fast")) { @@ -2749,8 +2749,8 @@ FPExceptionBehavior = "strict"; // The target may have opted to flush by default, so force IEEE. - DenormalFPMath = llvm::DenormalMode::getIEEE(); - DenormalFP32Math = llvm::DenormalMode::getIEEE(); + DenormalFPMath = llvm::fp::DenormalMode::getIEEE(); + DenormalFP32Math = llvm::fp::DenormalMode::getIEEE(); break; case options::OPT_Ofast: @@ -2784,7 +2784,7 @@ RoundingFPMath = false; // -fno_fast_math restores default denormal and fpcontract handling DenormalFPMath = DefaultDenormalFPMath; - DenormalFP32Math = llvm::DenormalMode::getIEEE(); + DenormalFP32Math = llvm::fp::DenormalMode::getIEEE(); FPContract = ""; break; } @@ -2795,8 +2795,8 @@ !AssociativeMath && !ReciprocalMath && SignedZeros && TrappingMath && RoundingFPMath && (FPContract.equals("off") || FPContract.empty()) && - DenormalFPMath == llvm::DenormalMode::getIEEE() && - DenormalFP32Math == llvm::DenormalMode::getIEEE()) + DenormalFPMath == llvm::fp::DenormalMode::getIEEE() && + DenormalFP32Math == llvm::fp::DenormalMode::getIEEE()) // OK: Current Arg doesn't conflict with -ffp-model=strict ; else { @@ -2843,7 +2843,7 @@ CmdArgs.push_back("-fno-trapping-math"); // The default is IEEE. - if (DenormalFPMath != llvm::DenormalMode::getIEEE()) { + if (DenormalFPMath != llvm::fp::DenormalMode::getIEEE()) { llvm::SmallString<64> DenormFlag; llvm::raw_svector_ostream ArgStr(DenormFlag); ArgStr << "-fdenormal-fp-math=" << DenormalFPMath; Index: clang/lib/Driver/ToolChains/Cuda.h =================================================================== --- clang/lib/Driver/ToolChains/Cuda.h +++ clang/lib/Driver/ToolChains/Cuda.h @@ -155,7 +155,7 @@ llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadKind) const override; - llvm::DenormalMode getDefaultDenormalModeForType( + llvm::fp::DenormalMode getDefaultDenormalModeForType( const llvm::opt::ArgList &DriverArgs, Action::OffloadKind DeviceOffloadKind, const llvm::fltSemantics *FPType = nullptr) const override; Index: clang/lib/Driver/ToolChains/Cuda.cpp =================================================================== --- clang/lib/Driver/ToolChains/Cuda.cpp +++ clang/lib/Driver/ToolChains/Cuda.cpp @@ -710,7 +710,7 @@ } } -llvm::DenormalMode CudaToolChain::getDefaultDenormalModeForType( +llvm::fp::DenormalMode CudaToolChain::getDefaultDenormalModeForType( const llvm::opt::ArgList &DriverArgs, Action::OffloadKind DeviceOffloadKind, const llvm::fltSemantics *FPType) const { if (DeviceOffloadKind == Action::OFK_Cuda) { @@ -718,11 +718,11 @@ DriverArgs.hasFlag(options::OPT_fcuda_flush_denormals_to_zero, options::OPT_fno_cuda_flush_denormals_to_zero, false)) - return llvm::DenormalMode::getPreserveSign(); + return llvm::fp::DenormalMode::getPreserveSign(); } assert(DeviceOffloadKind != Action::OFK_Host); - return llvm::DenormalMode::getIEEE(); + return llvm::fp::DenormalMode::getIEEE(); } bool CudaToolChain::supportsDebugInfoOption(const llvm::opt::Arg *A) const { Index: clang/lib/Driver/ToolChains/Linux.h =================================================================== --- clang/lib/Driver/ToolChains/Linux.h +++ clang/lib/Driver/ToolChains/Linux.h @@ -48,7 +48,7 @@ std::vector ExtraOpts; - llvm::DenormalMode getDefaultDenormalModeForType( + llvm::fp::DenormalMode getDefaultDenormalModeForType( const llvm::opt::ArgList &DriverArgs, Action::OffloadKind DeviceOffloadKind, const llvm::fltSemantics *FPType = nullptr) const override; Index: clang/lib/Driver/ToolChains/Linux.cpp =================================================================== --- clang/lib/Driver/ToolChains/Linux.cpp +++ clang/lib/Driver/ToolChains/Linux.cpp @@ -989,7 +989,7 @@ ToolChain::addProfileRTLibs(Args, CmdArgs); } -llvm::DenormalMode Linux::getDefaultDenormalModeForType( +llvm::fp::DenormalMode Linux::getDefaultDenormalModeForType( const llvm::opt::ArgList &DriverArgs, Action::OffloadKind DeviceOffloadKind, const llvm::fltSemantics *FPType) const { @@ -1000,11 +1000,11 @@ // 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(); + return llvm::fp::DenormalMode::getPreserveSign(); + return llvm::fp::DenormalMode::getIEEE(); } default: - return llvm::DenormalMode::getIEEE(); + return llvm::fp::DenormalMode::getIEEE(); } } Index: clang/lib/Driver/ToolChains/PS4CPU.h =================================================================== --- clang/lib/Driver/ToolChains/PS4CPU.h +++ clang/lib/Driver/ToolChains/PS4CPU.h @@ -93,12 +93,12 @@ llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadingKind) const override; - llvm::DenormalMode getDefaultDenormalModeForType( + llvm::fp::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(); + return llvm::fp::DenormalMode::getPreserveSign(); } protected: Index: llvm/include/llvm/ADT/FloatingPointMode.h =================================================================== --- llvm/include/llvm/ADT/FloatingPointMode.h +++ /dev/null @@ -1,151 +0,0 @@ -//===- llvm/Support/FloatingPointMode.h -------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Utilities for dealing with flags related to floating point mode controls. -// -//===----------------------------------------------------------------------===/ - -#ifndef LLVM_FLOATINGPOINTMODE_H -#define LLVM_FLOATINGPOINTMODE_H - -#include "llvm/ADT/StringSwitch.h" -#include "llvm/Support/raw_ostream.h" - -namespace llvm { - -/// Represent ssubnormal handling kind for floating point instruction inputs and -/// outputs. -struct DenormalMode { - /// Represent handled modes for denormal (aka subnormal) modes in the floating - /// point environment. - enum DenormalModeKind : int8_t { - Invalid = -1, - - /// IEEE-754 denormal numbers preserved. - IEEE, - - /// The sign of a flushed-to-zero number is preserved in the sign of 0 - PreserveSign, - - /// Denormals are flushed to positive zero. - PositiveZero - }; - - /// Denormal flushing mode for floating point instruction results in the - /// default floating point environment. - DenormalModeKind Output = DenormalModeKind::Invalid; - - /// Denormal treatment kind for floating point instruction inputs in the - /// default floating-point environment. If this is not DenormalModeKind::IEEE, - /// floating-point instructions implicitly treat the input value as 0. - DenormalModeKind Input = DenormalModeKind::Invalid; - - constexpr DenormalMode() = default; - constexpr DenormalMode(DenormalModeKind Out, DenormalModeKind In) : - Output(Out), Input(In) {} - - - static constexpr DenormalMode getInvalid() { - return DenormalMode(DenormalModeKind::Invalid, DenormalModeKind::Invalid); - } - - static constexpr DenormalMode getIEEE() { - return DenormalMode(DenormalModeKind::IEEE, DenormalModeKind::IEEE); - } - - static constexpr DenormalMode getPreserveSign() { - return DenormalMode(DenormalModeKind::PreserveSign, - DenormalModeKind::PreserveSign); - } - - static constexpr DenormalMode getPositiveZero() { - return DenormalMode(DenormalModeKind::PositiveZero, - DenormalModeKind::PositiveZero); - } - - bool operator==(DenormalMode Other) const { - return Output == Other.Output && Input == Other.Input; - } - - bool operator!=(DenormalMode Other) const { - return !(*this == Other); - } - - bool isSimple() const { - return Input == Output; - } - - bool isValid() const { - return Output != DenormalModeKind::Invalid && - Input != DenormalModeKind::Invalid; - } - - inline void print(raw_ostream &OS) const; - - inline std::string str() const { - std::string storage; - raw_string_ostream OS(storage); - print(OS); - return OS.str(); - } -}; - -inline raw_ostream& operator<<(raw_ostream &OS, DenormalMode Mode) { - Mode.print(OS); - return OS; -} - -/// Parse the expected names from the denormal-fp-math attribute. -inline DenormalMode::DenormalModeKind -parseDenormalFPAttributeComponent(StringRef Str) { - // Assume ieee on unspecified attribute. - return StringSwitch(Str) - .Cases("", "ieee", DenormalMode::IEEE) - .Case("preserve-sign", DenormalMode::PreserveSign) - .Case("positive-zero", DenormalMode::PositiveZero) - .Default(DenormalMode::Invalid); -} - -/// Return the name used for the denormal handling mode used by the the -/// expected names from the denormal-fp-math attribute. -inline StringRef denormalModeKindName(DenormalMode::DenormalModeKind Mode) { - switch (Mode) { - case DenormalMode::IEEE: - return "ieee"; - case DenormalMode::PreserveSign: - return "preserve-sign"; - case DenormalMode::PositiveZero: - return "positive-zero"; - default: - return ""; - } -} - -/// Returns the denormal mode to use for inputs and outputs. -inline DenormalMode parseDenormalFPAttribute(StringRef Str) { - StringRef OutputStr, InputStr; - std::tie(OutputStr, InputStr) = Str.split(','); - - DenormalMode Mode; - Mode.Output = parseDenormalFPAttributeComponent(OutputStr); - - // Maintain compatability with old form of the attribute which only specified - // one component. - Mode.Input = InputStr.empty() ? Mode.Output : - parseDenormalFPAttributeComponent(InputStr); - - return Mode; -} - -void DenormalMode::print(raw_ostream &OS) const { - OS << denormalModeKindName(Output) << ',' << denormalModeKindName(Input); -} - -} - -#endif // LLVM_FLOATINGPOINTMODE_H Index: llvm/include/llvm/CodeGen/CommandFlags.h =================================================================== --- llvm/include/llvm/CodeGen/CommandFlags.h +++ llvm/include/llvm/CodeGen/CommandFlags.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ADT/FloatingPointMode.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/IR/FPEnv.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" @@ -63,8 +63,8 @@ bool getEnableNoTrappingFPMath(); -DenormalMode::DenormalModeKind getDenormalFPMath(); -DenormalMode::DenormalModeKind getDenormalFP32Math(); +fp::DenormalMode::DenormalModeKind getDenormalFPMath(); +fp::DenormalMode::DenormalModeKind getDenormalFP32Math(); bool getEnableHonorSignDependentRoundingFPMath(); Index: llvm/include/llvm/CodeGen/MachineFunction.h =================================================================== --- llvm/include/llvm/CodeGen/MachineFunction.h +++ llvm/include/llvm/CodeGen/MachineFunction.h @@ -20,7 +20,6 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/FloatingPointMode.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" @@ -31,6 +30,7 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineMemOperand.h" +#include "llvm/IR/FPEnv.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/ArrayRecycler.h" #include "llvm/Support/AtomicOrdering.h" @@ -637,7 +637,7 @@ /// Returns the denormal handling type for the default rounding mode of the /// function. - DenormalMode getDenormalMode(const fltSemantics &FPType) const; + fp::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 Index: llvm/include/llvm/CodeGen/SelectionDAG.h =================================================================== --- llvm/include/llvm/CodeGen/SelectionDAG.h +++ llvm/include/llvm/CodeGen/SelectionDAG.h @@ -1907,7 +1907,7 @@ /// Return the current function's default denormal handling kind for the given /// floating point type. - DenormalMode getDenormalMode(EVT VT) const { + fp::DenormalMode getDenormalMode(EVT VT) const { return MF->getDenormalMode(EVTToAPFloatSemantics(VT)); } Index: llvm/include/llvm/IR/FPEnv.h =================================================================== --- llvm/include/llvm/IR/FPEnv.h +++ llvm/include/llvm/IR/FPEnv.h @@ -17,8 +17,11 @@ #include "llvm/ADT/APFloat.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/StringRef.h" -#include +#include "llvm/Support/raw_ostream.h" + +#include namespace llvm { @@ -48,7 +51,84 @@ ebStrict ///< This corresponds to "fpexcept.strict". }; -} +/// Represent denormal/subnormal handling kind for floating point instruction +/// inputs and outputs. +struct DenormalMode { + /// Represent handled modes for denormal (aka subnormal) modes in the floating + /// point environment. + enum DenormalModeKind : int8_t { + Invalid = -1, + + /// IEEE-754 denormal numbers preserved. + IEEE, + + /// The sign of a flushed-to-zero number is preserved in the sign of 0 + PreserveSign, + + /// Denormals are flushed to positive zero. + PositiveZero + }; + + /// Denormal flushing mode for floating point instruction results in the + /// default floating point environment. + DenormalModeKind Output = DenormalModeKind::Invalid; + + /// Denormal treatment kind for floating point instruction inputs in the + /// default floating-point environment. If this is not DenormalModeKind::IEEE, + /// floating-point instructions implicitly treat the input value as 0. + DenormalModeKind Input = DenormalModeKind::Invalid; + + constexpr DenormalMode() = default; + constexpr DenormalMode(DenormalModeKind Out, DenormalModeKind In) : + Output(Out), Input(In) {} + + + static constexpr DenormalMode getInvalid() { + return DenormalMode(DenormalModeKind::Invalid, DenormalModeKind::Invalid); + } + + static constexpr DenormalMode getIEEE() { + return DenormalMode(DenormalModeKind::IEEE, DenormalModeKind::IEEE); + } + + static constexpr DenormalMode getPreserveSign() { + return DenormalMode(DenormalModeKind::PreserveSign, + DenormalModeKind::PreserveSign); + } + + static constexpr DenormalMode getPositiveZero() { + return DenormalMode(DenormalModeKind::PositiveZero, + DenormalModeKind::PositiveZero); + } + + bool operator==(DenormalMode Other) const { + return Output == Other.Output && Input == Other.Input; + } + + bool operator!=(DenormalMode Other) const { + return !(*this == Other); + } + + bool isSimple() const { + return Input == Output; + } + + bool isValid() const { + return Output != DenormalModeKind::Invalid && + Input != DenormalModeKind::Invalid; + } + + inline void print(raw_ostream &OS) const; + + inline std::string str() const { + std::string storage; + raw_string_ostream OS(storage); + print(OS); + return OS.str(); + } +}; + +} // namespace fp /// Returns a valid RoundingMode enumerator when given a string /// that is valid as input in constrained intrinsic rounding mode @@ -70,5 +150,56 @@ /// Converts rounding mode represented by fp::RoundingMode to the rounding mode /// index used by APFloat. For fp::rmDynamic it returns None. Optional getAPFloatRoundingMode(fp::RoundingMode); + +inline raw_ostream &operator<<(raw_ostream &OS, fp::DenormalMode Mode) { + Mode.print(OS); + return OS; +} + +/// Parse the expected names from the denormal-fp-math attribute. +inline fp::DenormalMode::DenormalModeKind +parseDenormalFPAttributeComponent(StringRef Str) { + // Assume ieee on unspecified attribute. + return StringSwitch(Str) + .Cases("", "ieee", fp::DenormalMode::IEEE) + .Case("preserve-sign", fp::DenormalMode::PreserveSign) + .Case("positive-zero", fp::DenormalMode::PositiveZero) + .Default(fp::DenormalMode::Invalid); +} + +/// Return the name used for the denormal handling mode used by the the +/// expected names from the denormal-fp-math attribute. +inline StringRef denormalModeKindName(fp::DenormalMode::DenormalModeKind Mode) { + switch (Mode) { + case fp::DenormalMode::IEEE: + return "ieee"; + case fp::DenormalMode::PreserveSign: + return "preserve-sign"; + case fp::DenormalMode::PositiveZero: + return "positive-zero"; + default: + return ""; + } +} + +/// Returns the denormal mode to use for inputs and outputs. +inline fp::DenormalMode parseDenormalFPAttribute(StringRef Str) { + StringRef OutputStr, InputStr; + std::tie(OutputStr, InputStr) = Str.split(','); + + fp::DenormalMode Mode; + Mode.Output = parseDenormalFPAttributeComponent(OutputStr); + + // Maintain compatability with old form of the attribute which only specified + // one component. + Mode.Input = InputStr.empty() ? Mode.Output : + parseDenormalFPAttributeComponent(InputStr); + + return Mode; +} + +void fp::DenormalMode::print(raw_ostream &OS) const { + OS << denormalModeKindName(Output) << ',' << denormalModeKindName(Input); +} } #endif Index: llvm/include/llvm/Target/TargetOptions.h =================================================================== --- llvm/include/llvm/Target/TargetOptions.h +++ llvm/include/llvm/Target/TargetOptions.h @@ -14,7 +14,7 @@ #ifndef LLVM_TARGET_TARGETOPTIONS_H #define LLVM_TARGET_TARGETOPTIONS_H -#include "llvm/ADT/FloatingPointMode.h" +#include "llvm/IR/FPEnv.h" #include "llvm/MC/MCTargetOptions.h" #include @@ -129,7 +129,7 @@ SupportsDefaultOutlining(false), EmitAddrsig(false), EmitCallSiteInfo(false), SupportsDebugEntryValues(false), EnableDebugEntryValues(false), ForceDwarfFrameSection(false), - FPDenormalMode(DenormalMode::IEEE, DenormalMode::IEEE) {} + FPDenormalMode(fp::DenormalMode::IEEE, fp::DenormalMode::IEEE) {} /// PrintMachineCode - This flag is enabled when the -print-machineinstrs /// option is specified on the command line, and should enable debugging @@ -332,30 +332,30 @@ private: /// Flushing mode to assume in default FP environment. - DenormalMode FPDenormalMode; + fp::DenormalMode FPDenormalMode; /// Flushing mode to assume in default FP environment, for float/vector of /// float. - DenormalMode FP32DenormalMode; + fp::DenormalMode FP32DenormalMode; public: - void setFPDenormalMode(DenormalMode Mode) { + void setFPDenormalMode(fp::DenormalMode Mode) { FPDenormalMode = Mode; } - void setFP32DenormalMode(DenormalMode Mode) { + void setFP32DenormalMode(fp::DenormalMode Mode) { FP32DenormalMode = Mode; } - DenormalMode getRawFPDenormalMode() const { + fp::DenormalMode getRawFPDenormalMode() const { return FPDenormalMode; } - DenormalMode getRawFP32DenormalMode() const { + fp::DenormalMode getRawFP32DenormalMode() const { return FP32DenormalMode; } - DenormalMode getDenormalMode(const fltSemantics &FPType) const; + fp::DenormalMode getDenormalMode(const fltSemantics &FPType) const; /// What exception model to use ExceptionHandling ExceptionModel = ExceptionHandling::None; Index: llvm/lib/CodeGen/CommandFlags.cpp =================================================================== --- llvm/lib/CodeGen/CommandFlags.cpp +++ llvm/lib/CodeGen/CommandFlags.cpp @@ -54,8 +54,8 @@ CGOPT(bool, EnableNoNaNsFPMath) CGOPT(bool, EnableNoSignedZerosFPMath) CGOPT(bool, EnableNoTrappingFPMath) -CGOPT(DenormalMode::DenormalModeKind, DenormalFPMath) -CGOPT(DenormalMode::DenormalModeKind, DenormalFP32Math) +CGOPT(fp::DenormalMode::DenormalModeKind, DenormalFPMath) +CGOPT(fp::DenormalMode::DenormalModeKind, DenormalFP32Math) CGOPT(bool, EnableHonorSignDependentRoundingFPMath) CGOPT(FloatABI::ABIType, FloatABIForCalls) CGOPT(FPOpFusion::FPOpFusionMode, FuseFPOps) @@ -213,28 +213,27 @@ cl::init(false)); CGBINDOPT(EnableNoTrappingFPMath); - static const auto DenormFlagEnumOptions = - cl::values(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(DenormalMode::PositiveZero, "positive-zero", - "denormals are flushed to positive zero")); + static const auto DenormFlagEnumOptions = cl::values( + clEnumValN(fp::DenormalMode::IEEE, "ieee", "IEEE 754 denormal numbers"), + clEnumValN(fp::DenormalMode::PreserveSign, "preserve-sign", + "the sign of a flushed-to-zero number is preserved " + "in the sign of 0"), + clEnumValN(fp::DenormalMode::PositiveZero, "positive-zero", + "denormals are flushed to positive zero")); // 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(DenormalMode::IEEE), - DenormFlagEnumOptions); + static cl::opt DenormalFPMath( + "denormal-fp-math", + cl::desc( + "Select which denormal numbers the code is permitted to require"), + cl::init(fp::DenormalMode::IEEE), DenormFlagEnumOptions); CGBINDOPT(DenormalFPMath); - static cl::opt DenormalFP32Math( - "denormal-fp-math-f32", - cl::desc("Select which denormal numbers the code is permitted to require for float"), - cl::init(DenormalMode::Invalid), - DenormFlagEnumOptions); + static cl::opt DenormalFP32Math( + "denormal-fp-math-f32", + cl::desc("Select which denormal numbers the code is permitted to require " + "for float"), + cl::init(fp::DenormalMode::Invalid), DenormFlagEnumOptions); CGBINDOPT(DenormalFP32Math); static cl::opt EnableHonorSignDependentRoundingFPMath( @@ -437,10 +436,10 @@ Options.NoSignedZerosFPMath = getEnableNoSignedZerosFPMath(); Options.NoTrappingFPMath = getEnableNoTrappingFPMath(); - DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath(); + fp::DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath(); // FIXME: Should have separate input and output flags - Options.setFPDenormalMode(DenormalMode(DenormKind, DenormKind)); + Options.setFPDenormalMode(fp::DenormalMode(DenormKind, DenormKind)); Options.HonorSignDependentRoundingFPMathOption = getEnableHonorSignDependentRoundingFPMath(); @@ -581,21 +580,20 @@ if (DenormalFPMathView->getNumOccurrences() > 0 && !F.hasFnAttribute("denormal-fp-math")) { - DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath(); + fp::DenormalMode::DenormalModeKind DenormKind = getDenormalFPMath(); // FIXME: Command line flag should expose separate input/output modes. NewAttrs.addAttribute("denormal-fp-math", - DenormalMode(DenormKind, DenormKind).str()); + fp::DenormalMode(DenormKind, DenormKind).str()); } if (DenormalFP32MathView->getNumOccurrences() > 0 && !F.hasFnAttribute("denormal-fp-math-f32")) { // FIXME: Command line flag should expose separate input/output modes. - DenormalMode::DenormalModeKind DenormKind = getDenormalFP32Math(); + fp::DenormalMode::DenormalModeKind DenormKind = getDenormalFP32Math(); - NewAttrs.addAttribute( - "denormal-fp-math-f32", - DenormalMode(DenormKind, DenormKind).str()); + NewAttrs.addAttribute("denormal-fp-math-f32", + fp::DenormalMode(DenormKind, DenormKind).str()); } if (TrapFuncNameView->getNumOccurrences() > 0) Index: llvm/lib/CodeGen/MachineFunction.cpp =================================================================== --- llvm/lib/CodeGen/MachineFunction.cpp +++ llvm/lib/CodeGen/MachineFunction.cpp @@ -272,7 +272,8 @@ return JumpTableInfo; } -DenormalMode MachineFunction::getDenormalMode(const fltSemantics &FPType) const { +fp::DenormalMode +MachineFunction::getDenormalMode(const fltSemantics &FPType) const { if (&FPType == &APFloat::IEEEsingle()) { Attribute Attr = F.getFnAttribute("denormal-fp-math-f32"); StringRef Val = Attr.getValueAsString(); Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -21229,8 +21229,8 @@ SDLoc DL(Op); EVT CCVT = getSetCCResultType(VT); ISD::NodeType SelOpcode = VT.isVector() ? ISD::VSELECT : ISD::SELECT; - DenormalMode DenormMode = DAG.getDenormalMode(VT); - if (DenormMode.Input == DenormalMode::IEEE) { + fp::DenormalMode DenormMode = DAG.getDenormalMode(VT); + if (DenormMode.Input == fp::DenormalMode::IEEE) { // This is specifically a check for the handling of denormal inputs, // not the result. Index: llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp =================================================================== --- llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp +++ llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp @@ -15,7 +15,6 @@ #include "AMDGPU.h" #include "AMDGPUSubtarget.h" #include "AMDGPUTargetMachine.h" -#include "llvm/ADT/FloatingPointMode.h" #include "llvm/ADT/StringRef.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/ConstantFolding.h" @@ -28,6 +27,7 @@ #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/FPEnv.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/InstVisitor.h" Index: llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp =================================================================== --- llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp +++ llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp @@ -1347,22 +1347,22 @@ StringRef DenormF32Attr = F.getFnAttribute("denormal-fp-math-f32").getValueAsString(); if (!DenormF32Attr.empty()) { - DenormalMode DenormMode = parseDenormalFPAttribute(DenormF32Attr); - FP32InputDenormals = DenormMode.Input == DenormalMode::IEEE; - FP32OutputDenormals = DenormMode.Output == DenormalMode::IEEE; + fp::DenormalMode DenormMode = parseDenormalFPAttribute(DenormF32Attr); + FP32InputDenormals = DenormMode.Input == fp::DenormalMode::IEEE; + FP32OutputDenormals = DenormMode.Output == fp::DenormalMode::IEEE; } StringRef DenormAttr = F.getFnAttribute("denormal-fp-math").getValueAsString(); if (!DenormAttr.empty()) { - DenormalMode DenormMode = parseDenormalFPAttribute(DenormAttr); + fp::DenormalMode DenormMode = parseDenormalFPAttribute(DenormAttr); if (DenormF32Attr.empty()) { - FP32InputDenormals = DenormMode.Input == DenormalMode::IEEE; - FP32OutputDenormals = DenormMode.Output == DenormalMode::IEEE; + FP32InputDenormals = DenormMode.Input == fp::DenormalMode::IEEE; + FP32OutputDenormals = DenormMode.Output == fp::DenormalMode::IEEE; } - FP64FP16InputDenormals = DenormMode.Input == DenormalMode::IEEE; - FP64FP16OutputDenormals = DenormMode.Output == DenormalMode::IEEE; + FP64FP16InputDenormals = DenormMode.Input == fp::DenormalMode::IEEE; + FP64FP16OutputDenormals = DenormMode.Output == fp::DenormalMode::IEEE; } } Index: llvm/lib/Target/ARM/ARMAsmPrinter.cpp =================================================================== --- llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -586,9 +586,8 @@ } // Returns true if all functions have the same denormal mode. // It also returns true when the module has no functions. -static bool checkDenormalAttributeConsistency(const Module &M, - StringRef Attr, - DenormalMode Value) { +static bool checkDenormalAttributeConsistency(const Module &M, StringRef Attr, + fp::DenormalMode Value) { return !any_of(M, [&](const Function &F) { StringRef AttrVal = F.getFnAttribute(Attr).getValueAsString(); return parseDenormalFPAttribute(AttrVal) != Value; @@ -653,12 +652,12 @@ // Set FP Denormals. if (checkDenormalAttributeConsistency(*MMI->getModule(), "denormal-fp-math", - DenormalMode::getPreserveSign())) + fp::DenormalMode::getPreserveSign())) ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, ARMBuildAttrs::PreserveFPSign); - else if (checkDenormalAttributeConsistency(*MMI->getModule(), - "denormal-fp-math", - DenormalMode::getPositiveZero())) + else if (checkDenormalAttributeConsistency( + *MMI->getModule(), "denormal-fp-math", + fp::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 @@ -113,7 +113,7 @@ bool NVPTXTargetLowering::useF32FTZ(const MachineFunction &MF) const { return MF.getDenormalMode(APFloat::IEEEsingle()).Output == - DenormalMode::PreserveSign; + fp::DenormalMode::PreserveSign; } static bool IsPTXVectorType(MVT VT) { Index: llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -15,7 +15,6 @@ #include "llvm/ADT/APInt.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/FloatingPointMode.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" @@ -34,6 +33,7 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/FPEnv.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/InstrTypes.h" @@ -1788,8 +1788,8 @@ StringRef Attr = II->getFunction() ->getFnAttribute("denormal-fp-math-f32") .getValueAsString(); - DenormalMode Mode = parseDenormalFPAttribute(Attr); - bool FtzEnabled = Mode.Output != DenormalMode::IEEE; + fp::DenormalMode Mode = parseDenormalFPAttribute(Attr); + bool FtzEnabled = Mode.Output != fp::DenormalMode::IEEE; if (FtzEnabled != (Action.FtzRequirement == FTZ_MustBeOn)) return nullptr; Index: llvm/unittests/ADT/CMakeLists.txt =================================================================== --- llvm/unittests/ADT/CMakeLists.txt +++ llvm/unittests/ADT/CMakeLists.txt @@ -22,7 +22,6 @@ EnumeratedArrayTest.cpp EquivalenceClassesTest.cpp FallibleIteratorTest.cpp - FloatingPointMode.cpp FoldingSet.cpp FunctionExtrasTest.cpp FunctionRefTest.cpp Index: llvm/unittests/IR/CMakeLists.txt =================================================================== --- llvm/unittests/IR/CMakeLists.txt +++ llvm/unittests/IR/CMakeLists.txt @@ -19,6 +19,7 @@ DebugTypeODRUniquingTest.cpp DominatorTreeTest.cpp DominatorTreeBatchUpdatesTest.cpp + FPEnv.cpp FunctionTest.cpp PassBuilderCallbacksTest.cpp IRBuilderTest.cpp Index: llvm/unittests/IR/FPEnv.cpp =================================================================== --- llvm/unittests/IR/FPEnv.cpp +++ llvm/unittests/IR/FPEnv.cpp @@ -1,4 +1,4 @@ -//===- llvm/unittest/ADT/FloatingPointMode.cpp ----------------------------===// +//===- llvm/unittest/IR/FPEnv.cpp ----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,14 +6,15 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ADT/FloatingPointMode.h" +#include "llvm/IR/FPEnv.h" #include "gtest/gtest.h" using namespace llvm; namespace { +using namespace fp; -TEST(FloatingPointModeTest, ParseDenormalFPAttributeComponent) { +TEST(FPEnvTest, ParseDenormalFPAttributeComponent) { EXPECT_EQ(DenormalMode::IEEE, parseDenormalFPAttributeComponent("ieee")); EXPECT_EQ(DenormalMode::IEEE, parseDenormalFPAttributeComponent("")); EXPECT_EQ(DenormalMode::PreserveSign, @@ -23,14 +24,14 @@ EXPECT_EQ(DenormalMode::Invalid, parseDenormalFPAttributeComponent("foo")); } -TEST(FloatingPointModeTest, DenormalAttributeName) { +TEST(FPEnvTest, DenormalAttributeName) { EXPECT_EQ("ieee", denormalModeKindName(DenormalMode::IEEE)); EXPECT_EQ("preserve-sign", denormalModeKindName(DenormalMode::PreserveSign)); EXPECT_EQ("positive-zero", denormalModeKindName(DenormalMode::PositiveZero)); EXPECT_EQ("", denormalModeKindName(DenormalMode::Invalid)); } -TEST(FloatingPointModeTest, ParseDenormalFPAttribute) { +TEST(FPEnvTest, ParseDenormalFPAttribute) { EXPECT_EQ(DenormalMode(DenormalMode::IEEE, DenormalMode::IEEE), parseDenormalFPAttribute("ieee")); EXPECT_EQ(DenormalMode(DenormalMode::IEEE, DenormalMode::IEEE), @@ -74,7 +75,7 @@ parseDenormalFPAttribute("foo,bar")); } -TEST(FloatingPointModeTest, RenderDenormalFPAttribute) { +TEST(FPEnvTest, RenderDenormalFPAttribute) { EXPECT_EQ(DenormalMode(DenormalMode::Invalid, DenormalMode::Invalid), parseDenormalFPAttribute("foo")); @@ -104,7 +105,7 @@ DenormalMode(DenormalMode::PreserveSign, DenormalMode::PositiveZero).str()); } -TEST(FloatingPointModeTest, DenormalModeIsSimple) { +TEST(FPEnvTest, DenormalModeIsSimple) { EXPECT_TRUE(DenormalMode(DenormalMode::IEEE, DenormalMode::IEEE).isSimple()); EXPECT_FALSE(DenormalMode(DenormalMode::IEEE, DenormalMode::Invalid).isSimple()); @@ -112,7 +113,7 @@ DenormalMode::PositiveZero).isSimple()); } -TEST(FloatingPointModeTest, DenormalModeIsValid) { +TEST(FPEnvTest, DenormalModeIsValid) { EXPECT_TRUE(DenormalMode(DenormalMode::IEEE, DenormalMode::IEEE).isValid()); EXPECT_FALSE(DenormalMode(DenormalMode::IEEE, DenormalMode::Invalid).isValid()); EXPECT_FALSE(DenormalMode(DenormalMode::Invalid, DenormalMode::IEEE).isValid()); @@ -120,7 +121,7 @@ DenormalMode::Invalid).isValid()); } -TEST(FloatingPointModeTest, DenormalModeConstructor) { +TEST(FPEnvTest, DenormalModeConstructor) { EXPECT_EQ(DenormalMode(DenormalMode::Invalid, DenormalMode::Invalid), DenormalMode::getInvalid()); EXPECT_EQ(DenormalMode(DenormalMode::IEEE, DenormalMode::IEEE), Index: llvm/utils/gn/secondary/llvm/unittests/ADT/BUILD.gn =================================================================== --- llvm/utils/gn/secondary/llvm/unittests/ADT/BUILD.gn +++ llvm/utils/gn/secondary/llvm/unittests/ADT/BUILD.gn @@ -29,7 +29,6 @@ "EnumeratedArrayTest.cpp", "EquivalenceClassesTest.cpp", "FallibleIteratorTest.cpp", - "FloatingPointMode.cpp", "FoldingSet.cpp", "FunctionExtrasTest.cpp", "FunctionRefTest.cpp", Index: llvm/utils/gn/secondary/llvm/unittests/IR/BUILD.gn =================================================================== --- llvm/utils/gn/secondary/llvm/unittests/IR/BUILD.gn +++ llvm/utils/gn/secondary/llvm/unittests/IR/BUILD.gn @@ -22,6 +22,7 @@ "DebugTypeODRUniquingTest.cpp", "DominatorTreeBatchUpdatesTest.cpp", "DominatorTreeTest.cpp", + "FPEnv.cpp", "FunctionTest.cpp", "IRBuilderTest.cpp", "InstructionsTest.cpp",