So you left some debugging code in that I've fixed thusly: "Enclosing function uses fp intrinsics"
commit f4a7d5659df7cb56c1baa34a39e9fe2639472741 Author: Eric Christopher <echri...@gmail.com> Date: Tue Dec 10 15:02:29 2019 -0800 Remove debugging printf and reformat code. On Thu, Dec 5, 2019 at 3:48 AM Melanie Blower via cfe-commits < cfe-commits@lists.llvm.org> wrote: > > Author: Melanie Blower > Date: 2019-12-05T03:48:04-08:00 > New Revision: 7f9b5138470db1dc58f3bc05631284c653c9ed7a > > URL: > https://github.com/llvm/llvm-project/commit/7f9b5138470db1dc58f3bc05631284c653c9ed7a > DIFF: > https://github.com/llvm/llvm-project/commit/7f9b5138470db1dc58f3bc05631284c653c9ed7a.diff > > LOG: Reapply af57dbf12e54 "Add support for options > -frounding-math, ftrapping-math, -ffp-model=, and -ffp-exception-behavior=" > > Patch was reverted because > https://bugs.llvm.org/show_bug.cgi?id=44048 > The original patch is modified to set the strictfp IR attribute > explicitly in CodeGen instead of as a side effect of IRBuilder. > In the 2nd attempt to reapply there was a windows lit test fail, > the > tests were fixed to use wildcard matching. > > Differential Revision: https://reviews.llvm.org/D62731 > > Added: > clang/test/CodeGen/fpconstrained.c > clang/test/CodeGen/fpconstrained.cpp > clang/test/Driver/fp-model.c > > Modified: > clang/docs/UsersManual.rst > clang/include/clang/AST/Decl.h > clang/include/clang/AST/DeclBase.h > clang/include/clang/Basic/DiagnosticDriverKinds.td > clang/include/clang/Basic/DiagnosticGroups.td > clang/include/clang/Basic/LangOptions.def > clang/include/clang/Basic/LangOptions.h > clang/include/clang/Driver/Options.td > clang/lib/AST/Decl.cpp > clang/lib/CodeGen/CGCall.cpp > clang/lib/CodeGen/CodeGenFunction.cpp > clang/lib/CodeGen/CodeGenFunction.h > clang/lib/Driver/ToolChains/Clang.cpp > clang/lib/Frontend/CompilerInvocation.cpp > clang/lib/Sema/SemaExpr.cpp > clang/lib/Serialization/ASTReaderDecl.cpp > clang/lib/Serialization/ASTWriterDecl.cpp > clang/test/Driver/clang_f_opts.c > clang/test/Driver/fast-math.c > llvm/include/llvm/IR/IRBuilder.h > llvm/include/llvm/Target/TargetOptions.h > llvm/unittests/IR/IRBuilderTest.cpp > > Removed: > > > > > ################################################################################ > diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst > index 714681d7f4ce..62e2575c6b26 100644 > --- a/clang/docs/UsersManual.rst > +++ b/clang/docs/UsersManual.rst > @@ -1231,10 +1231,10 @@ are listed below. > > **-f[no-]trapping-math** > > - ``-fno-trapping-math`` allows optimizations that assume that > - floating point operations cannot generate traps such as divide-by-zero, > - overflow and underflow. Defaults to ``-ftrapping-math``. > - Currently this option has no effect. > + Control floating point exception behavior. ``-fno-trapping-math`` > allows optimizations that assume that floating point operations cannot > generate traps such as divide-by-zero, overflow and underflow. > + > +- The option ``-ftrapping-math`` behaves identically to > ``-ffp-exception-behavior=strict``. > +- The option ``-fno-trapping-math`` behaves identically to > ``-ffp-exception-behavior=ignore``. This is the default. > > .. option:: -ffp-contract=<value> > > @@ -1319,6 +1319,52 @@ are listed below. > > Defaults to ``-fno-finite-math``. > > +.. _opt_frounding-math: > + > +**-f[no-]rounding-math** > + > +Force floating-point operations to honor the dynamically-set rounding > mode by default. > + > +The result of a floating-point operation often cannot be exactly > represented in the result type and therefore must be rounded. IEEE 754 > describes > diff erent rounding modes that control how to perform this rounding, not > all of which are supported by all implementations. C provides interfaces > (``fesetround`` and ``fesetenv``) for dynamically controlling the rounding > mode, and while it also recommends certain conventions for changing the > rounding mode, these conventions are not typically enforced in the ABI. > Since the rounding mode changes the numerical result of operations, the > compiler must understand something about it in order to optimize floating > point operations. > + > +Note that floating-point operations performed as part of constant > initialization are formally performed prior to the start of the program and > are therefore not subject to the current rounding mode. This includes the > initialization of global variables and local ``static`` variables. > Floating-point operations in these contexts will be rounded using > ``FE_TONEAREST``. > + > +- The option ``-fno-rounding-math`` allows the compiler to assume that > the rounding mode is set to ``FE_TONEAREST``. This is the default. > +- The option ``-frounding-math`` forces the compiler to honor the > dynamically-set rounding mode. This prevents optimizations which might > affect results if the rounding mode changes or is > diff erent from the default; for example, it prevents floating-point > operations from being reordered across most calls and prevents > constant-folding when the result is not exactly representable. > + > +.. option:: -ffp-model=<value> > + > + Specify floating point behavior. ``-ffp-model`` is an umbrella > + option that encompasses functionality provided by other, single > + purpose, floating point options. Valid values are: ``precise``, > ``strict``, > + and ``fast``. > + Details: > + > + * ``precise`` Disables optimizations that are not value-safe on > floating-point data, although FP contraction (FMA) is enabled > (``-ffp-contract=fast``). This is the default behavior. > + * ``strict`` Enables ``-frounding-math`` and > ``-ffp-exception-behavior=strict``, and disables contractions (FMA). All > of the ``-ffast-math`` enablements are disabled. > + * ``fast`` Behaves identically to specifying both ``-ffast-math`` and > ``ffp-contract=fast`` > + > + Note: If your command line specifies multiple instances > + of the ``-ffp-model`` option, or if your command line option specifies > + ``-ffp-model`` and later on the command line selects a floating point > + option that has the effect of negating part of the ``ffp-model`` that > + has been selected, then the compiler will issue a diagnostic warning > + that the override has occurred. > + > +.. option:: -ffp-exception-behavior=<value> > + > + Specify the floating-point exception behavior. > + > + Valid values are: ``ignore``, ``maytrap``, and ``strict``. > + The default value is ``ignore``. Details: > + > + * ``ignore`` The compiler assumes that the exception status flags will > not be read and that floating point exceptions will be masked. > + * ``maytrap`` The compiler avoids transformations that may raise > exceptions that would not have been raised by the original code. Constant > folding performed by the compiler is exempt from this option. > + * ``strict`` The compiler ensures that all transformations strictly > preserve the floating point exception semantics of the original code. > + > + > + > + > .. _controlling-code-generation: > > Controlling Code Generation > > diff --git a/clang/include/clang/AST/Decl.h > b/clang/include/clang/AST/Decl.h > index c1544c9ded94..f4913540bab4 100644 > --- a/clang/include/clang/AST/Decl.h > +++ b/clang/include/clang/AST/Decl.h > @@ -2196,6 +2196,10 @@ class FunctionDecl : public DeclaratorDecl, > bool usesSEHTry() const { return FunctionDeclBits.UsesSEHTry; } > void setUsesSEHTry(bool UST) { FunctionDeclBits.UsesSEHTry = UST; } > > + /// Indicates the function uses Floating Point constrained intrinsics > + bool usesFPIntrin() const { return FunctionDeclBits.UsesFPIntrin; } > + void setUsesFPIntrin(bool Val) { FunctionDeclBits.UsesFPIntrin = Val; } > + > /// Whether this function has been deleted. > /// > /// A function that is "deleted" (via the C++0x "= delete" syntax) > > diff --git a/clang/include/clang/AST/DeclBase.h > b/clang/include/clang/AST/DeclBase.h > index adea10b33188..54cdb84b6f33 100644 > --- a/clang/include/clang/AST/DeclBase.h > +++ b/clang/include/clang/AST/DeclBase.h > @@ -1534,10 +1534,13 @@ class DeclContext { > > /// Store the ODRHash after first calculation. > uint64_t HasODRHash : 1; > + > + /// Indicates if the function uses Floating Point Constrained > Intrinsics > + uint64_t UsesFPIntrin : 1; > }; > > /// Number of non-inherited bits in FunctionDeclBitfields. > - enum { NumFunctionDeclBits = 25 }; > + enum { NumFunctionDeclBits = 26 }; > > /// Stores the bits used by CXXConstructorDecl. If modified > /// NumCXXConstructorDeclBits and the accessor > @@ -1554,7 +1557,7 @@ class DeclContext { > /// exactly 64 bits and thus the width of NumCtorInitializers > /// will need to be shrunk if some bit is added to > NumDeclContextBitfields, > /// NumFunctionDeclBitfields or CXXConstructorDeclBitfields. > - uint64_t NumCtorInitializers : 23; > + uint64_t NumCtorInitializers : 22; > uint64_t IsInheritingConstructor : 1; > > /// Whether this constructor has a trail-allocated explicit specifier. > > diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td > b/clang/include/clang/Basic/DiagnosticDriverKinds.td > index 39242c972ea2..67faa872e57c 100644 > --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td > +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td > @@ -441,6 +441,10 @@ def warn_drv_experimental_isel_incomplete_opt : > Warning< > "-fexperimental-isel support is incomplete for this architecture at the > current optimization level">, > InGroup<ExperimentalISel>; > > +def warn_drv_experimental_fp_control_incomplete_opt : Warning< > + "Support for floating point control option %0 is incomplete and > experimental">, > + InGroup<ExperimentalFloatControl>; > + > def warn_drv_moutline_unsupported_opt : Warning< > "The '%0' architecture does not support -moutline; flag ignored">, > InGroup<OptionIgnored>; > > diff --git a/clang/include/clang/Basic/DiagnosticGroups.td > b/clang/include/clang/Basic/DiagnosticGroups.td > index 478b217a19f6..dec293f45af7 100644 > --- a/clang/include/clang/Basic/DiagnosticGroups.td > +++ b/clang/include/clang/Basic/DiagnosticGroups.td > @@ -1109,6 +1109,9 @@ def SpirCompat : DiagGroup<"spir-compat">; > // Warning for the experimental-isel options. > def ExperimentalISel : DiagGroup<"experimental-isel">; > > +// Warning for the experimental float control options. > +def ExperimentalFloatControl : DiagGroup<"experimental-float-control">; > + > // A warning group specifically for warnings related to function > // multiversioning. > def FunctionMultiVersioning : DiagGroup<"function-multiversion">; > > diff --git a/clang/include/clang/Basic/LangOptions.def > b/clang/include/clang/Basic/LangOptions.def > index 68d6ee1dce42..05d96b6c6a13 100644 > --- a/clang/include/clang/Basic/LangOptions.def > +++ b/clang/include/clang/Basic/LangOptions.def > @@ -255,6 +255,8 @@ LANGOPT(SinglePrecisionConstants , 1, 0, "treating > double-precision floating poi > LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math") > /// FP_CONTRACT mode (on/off/fast). > ENUM_LANGOPT(DefaultFPContractMode, FPContractModeKind, 2, FPC_Off, "FP > contraction type") > +ENUM_LANGOPT(FPRoundingMode, FPRoundingModeKind, 3, FPR_ToNearest, "FP > Rounding Mode type") > +ENUM_LANGOPT(FPExceptionMode, FPExceptionModeKind, 2, FPE_Ignore, "FP > Exception Behavior Mode type") > LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment") > LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility") > LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference > counting") > > diff --git a/clang/include/clang/Basic/LangOptions.h > b/clang/include/clang/Basic/LangOptions.h > index 95628280a4a0..ae4a4b2b9e87 100644 > --- a/clang/include/clang/Basic/LangOptions.h > +++ b/clang/include/clang/Basic/LangOptions.h > @@ -190,6 +190,34 @@ class LangOptions : public LangOptionsBase { > FEA_On > }; > > + // Values of the following enumerations correspond to metadata arguments > + // specified for constrained floating-point intrinsics: > + // > http://llvm.org/docs/LangRef.html#constrained-floating-point-intrinsics. > + > + /// Possible rounding modes. > + enum FPRoundingModeKind { > + /// Rounding to nearest, corresponds to "round.tonearest". > + FPR_ToNearest, > + /// Rounding toward -Inf, corresponds to "round.downward". > + FPR_Downward, > + /// Rounding toward +Inf, corresponds to "round.upward". > + FPR_Upward, > + /// Rounding toward zero, corresponds to "round.towardzero". > + FPR_TowardZero, > + /// Is determined by runtime environment, corresponds to > "round.dynamic". > + FPR_Dynamic > + }; > + > + /// Possible floating point exception behavior. > + enum FPExceptionModeKind { > + /// Assume that floating-point exceptions are masked. > + FPE_Ignore, > + /// Transformations do not cause new exceptions but may hide some. > + FPE_MayTrap, > + /// Strictly preserve the floating-point exception semantics. > + FPE_Strict > + }; > + > enum class LaxVectorConversionKind { > /// Permit no implicit vector bitcasts. > None, > > diff --git a/clang/include/clang/Driver/Options.td > b/clang/include/clang/Driver/Options.td > index a64d0acb06fe..8965131b9001 100644 > --- a/clang/include/clang/Driver/Options.td > +++ b/clang/include/clang/Driver/Options.td > @@ -929,6 +929,10 @@ def : Flag<["-"], "fextended-identifiers">, > Group<clang_ignored_f_Group>; > def : Flag<["-"], "fno-extended-identifiers">, Group<f_Group>, > Flags<[Unsupported]>; > def fhosted : Flag<["-"], "fhosted">, Group<f_Group>; > def fdenormal_fp_math_EQ : Joined<["-"], "fdenormal-fp-math=">, > Group<f_Group>, Flags<[CC1Option]>; > +def ffp_model_EQ : Joined<["-"], "ffp-model=">, Group<f_Group>, > Flags<[DriverOption]>, > + HelpText<"Controls the semantics of floating-point calculations.">; > +def ffp_exception_behavior_EQ : Joined<["-"], "ffp-exception-behavior=">, > Group<f_Group>, Flags<[CC1Option]>, > + HelpText<"Specifies the exception behavior of floating-point > operations.">; > def ffast_math : Flag<["-"], "ffast-math">, Group<f_Group>, > Flags<[CC1Option]>, > HelpText<"Allow aggressive, lossy floating-point optimizations">; > def fno_fast_math : Flag<["-"], "fno-fast-math">, Group<f_Group>; > @@ -1154,6 +1158,8 @@ def fno_honor_infinities : Flag<["-"], > "fno-honor-infinities">, Group<f_Group>; > // This option was originally misspelt "infinites" [sic]. > def : Flag<["-"], "fhonor-infinites">, Alias<fhonor_infinities>; > def : Flag<["-"], "fno-honor-infinites">, Alias<fno_honor_infinities>; > +def frounding_math : Flag<["-"], "frounding-math">, Group<f_Group>, > Flags<[CC1Option]>; > +def fno_rounding_math : Flag<["-"], "fno-rounding-math">, Group<f_Group>, > Flags<[CC1Option]>; > def ftrapping_math : Flag<["-"], "ftrapping-math">, Group<f_Group>, > Flags<[CC1Option]>; > def fno_trapping_math : Flag<["-"], "fno-trapping-math">, Group<f_Group>, > Flags<[CC1Option]>; > def ffp_contract : Joined<["-"], "ffp-contract=">, Group<f_Group>, > @@ -3242,7 +3248,6 @@ defm profile_values : > BooleanFFlag<"profile-values">, Group<clang_ignored_gcc_op > defm regs_graph : BooleanFFlag<"regs-graph">, > Group<clang_ignored_f_Group>; > defm rename_registers : BooleanFFlag<"rename-registers">, > Group<clang_ignored_gcc_optimization_f_Group>; > defm ripa : BooleanFFlag<"ripa">, Group<clang_ignored_f_Group>; > -defm rounding_math : BooleanFFlag<"rounding-math">, > Group<clang_ignored_gcc_optimization_f_Group>; > defm schedule_insns : BooleanFFlag<"schedule-insns">, > Group<clang_ignored_gcc_optimization_f_Group>; > defm schedule_insns2 : BooleanFFlag<"schedule-insns2">, > Group<clang_ignored_gcc_optimization_f_Group>; > defm see : BooleanFFlag<"see">, Group<clang_ignored_f_Group>; > > diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp > index bfcf7926861f..0301110b7067 100644 > --- a/clang/lib/AST/Decl.cpp > +++ b/clang/lib/AST/Decl.cpp > @@ -2793,6 +2793,7 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, > DeclContext *DC, > FunctionDeclBits.ConstexprKind = ConstexprKind; > FunctionDeclBits.InstantiationIsPending = false; > FunctionDeclBits.UsesSEHTry = false; > + FunctionDeclBits.UsesFPIntrin = false; > FunctionDeclBits.HasSkippedBody = false; > FunctionDeclBits.WillHaveBody = false; > FunctionDeclBits.IsMultiVersion = false; > > diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp > index ca6b1d409c24..657c9260e6e6 100644 > --- a/clang/lib/CodeGen/CGCall.cpp > +++ b/clang/lib/CodeGen/CGCall.cpp > @@ -4336,6 +4336,13 @@ RValue CodeGenFunction::EmitCall(const > CGFunctionInfo &CallInfo, > Callee.getAbstractInfo(), Attrs, CallingConv, > /*AttrOnCallSite=*/true); > > + if (const FunctionDecl *FD = > dyn_cast_or_null<FunctionDecl>(CurFuncDecl)) > + if (FD->usesFPIntrin()) > + // All calls within a strictfp function are marked strictfp > + Attrs = > + Attrs.addAttribute(getLLVMContext(), > llvm::AttributeList::FunctionIndex, > + llvm::Attribute::StrictFP); > + > // Apply some call-site-specific attributes. > // TODO: work this into building the attribute set. > > @@ -4385,6 +4392,13 @@ RValue CodeGenFunction::EmitCall(const > CGFunctionInfo &CallInfo, > SmallVector<llvm::OperandBundleDef, 1> BundleList = > getBundlesForFunclet(CalleePtr); > > + if (const FunctionDecl *FD = > dyn_cast_or_null<FunctionDecl>(CurFuncDecl)) > + if (FD->usesFPIntrin()) > + // All calls within a strictfp function are marked strictfp > + Attrs = > + Attrs.addAttribute(getLLVMContext(), > llvm::AttributeList::FunctionIndex, > + llvm::Attribute::StrictFP); > + > // Emit the actual call/invoke instruction. > llvm::CallBase *CI; > if (!InvokeDest) { > > diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp > b/clang/lib/CodeGen/CodeGenFunction.cpp > index 7f3be896a7b9..fd3020835a4d 100644 > --- a/clang/lib/CodeGen/CodeGenFunction.cpp > +++ b/clang/lib/CodeGen/CodeGenFunction.cpp > @@ -33,6 +33,8 @@ > #include "clang/Frontend/FrontendDiagnostic.h" > #include "llvm/IR/DataLayout.h" > #include "llvm/IR/Dominators.h" > +#include "llvm/IR/FPEnv.h" > +#include "llvm/IR/IntrinsicInst.h" > #include "llvm/IR/Intrinsics.h" > #include "llvm/IR/MDBuilder.h" > #include "llvm/IR/Operator.h" > @@ -87,6 +89,7 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, > bool suppressNewContext) > FMF.setAllowReassoc(); > } > Builder.setFastMathFlags(FMF); > + SetFPModel(); > } > > CodeGenFunction::~CodeGenFunction() { > @@ -102,6 +105,51 @@ CodeGenFunction::~CodeGenFunction() { > CGM.getOpenMPRuntime().functionFinished(*this); > } > > +// Map the LangOption for rounding mode into > +// the corresponding enum in the IR. > +static llvm::fp::RoundingMode ToConstrainedRoundingMD( > + LangOptions::FPRoundingModeKind Kind) { > + > + switch (Kind) { > + case LangOptions::FPR_ToNearest: return llvm::fp::rmToNearest; > + case LangOptions::FPR_Downward: return llvm::fp::rmDownward; > + case LangOptions::FPR_Upward: return llvm::fp::rmUpward; > + case LangOptions::FPR_TowardZero: return llvm::fp::rmTowardZero; > + case LangOptions::FPR_Dynamic: return llvm::fp::rmDynamic; > + } > + llvm_unreachable("Unsupported FP RoundingMode"); > +} > + > +// Map the LangOption for exception behavior into > +// the corresponding enum in the IR. > +static llvm::fp::ExceptionBehavior ToConstrainedExceptMD( > + LangOptions::FPExceptionModeKind Kind) { > + > + switch (Kind) { > + case LangOptions::FPE_Ignore: return llvm::fp::ebIgnore; > + case LangOptions::FPE_MayTrap: return llvm::fp::ebMayTrap; > + case LangOptions::FPE_Strict: return llvm::fp::ebStrict; > + } > + llvm_unreachable("Unsupported FP Exception Behavior"); > +} > + > +void CodeGenFunction::SetFPModel() { > + auto fpRoundingMode = ToConstrainedRoundingMD( > + getLangOpts().getFPRoundingMode()); > + auto fpExceptionBehavior = ToConstrainedExceptMD( > + getLangOpts().getFPExceptionMode()); > + > + if (fpExceptionBehavior == llvm::fp::ebIgnore && > + fpRoundingMode == llvm::fp::rmToNearest) > + // Constrained intrinsics are not used. > + ; > + else { > + Builder.setIsFPConstrained(true); > + Builder.setDefaultConstrainedRounding(fpRoundingMode); > + Builder.setDefaultConstrainedExcept(fpExceptionBehavior); > + } > +} > + > CharUnits CodeGenFunction::getNaturalPointeeTypeAlignment(QualType T, > LValueBaseInfo > *BaseInfo, > TBAAAccessInfo > *TBAAInfo) { > @@ -823,6 +871,10 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, > QualType RetTy, > if (FD->isMain()) > Fn->addFnAttr(llvm::Attribute::NoRecurse); > > + if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) > + if (FD->usesFPIntrin()) > + Fn->addFnAttr(llvm::Attribute::StrictFP); > + > // If a custom alignment is used, force realigning to this alignment on > // any main function which certainly will need it. > if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) > > diff --git a/clang/lib/CodeGen/CodeGenFunction.h > b/clang/lib/CodeGen/CodeGenFunction.h > index 7a2627ccf58b..8f99b090b818 100644 > --- a/clang/lib/CodeGen/CodeGenFunction.h > +++ b/clang/lib/CodeGen/CodeGenFunction.h > @@ -4169,6 +4169,9 @@ class CodeGenFunction : public CodeGenTypeCache { > /// point operation, expressed as the maximum relative error in ulp. > void SetFPAccuracy(llvm::Value *Val, float Accuracy); > > + /// SetFPModel - Control floating point behavior via fp-model settings. > + void SetFPModel(); > + > private: > llvm::MDNode *getRangeForLoadFromType(QualType Ty); > void EmitReturnOfRValue(RValue RV, QualType Ty); > > diff --git a/clang/lib/Driver/ToolChains/Clang.cpp > b/clang/lib/Driver/ToolChains/Clang.cpp > index 03a6de812047..5f8c0cb8a2c1 100644 > --- a/clang/lib/Driver/ToolChains/Clang.cpp > +++ b/clang/lib/Driver/ToolChains/Clang.cpp > @@ -2302,9 +2302,18 @@ static void RenderFloatingPointOptions(const > ToolChain &TC, const Driver &D, > bool AssociativeMath = false; > bool ReciprocalMath = false; > bool SignedZeros = true; > - bool TrappingMath = true; > + bool TrappingMath = false; // Implemented via -ffp-exception-behavior > + bool TrappingMathPresent = false; // Is trapping-math in args, and not > + // overriden by > ffp-exception-behavior? > + bool RoundingFPMath = false; > + bool RoundingMathPresent = false; // Is rounding-math in args? > + // -ffp-model values: strict, fast, precise > + StringRef FPModel = ""; > + // -ffp-exception-behavior options: strict, maytrap, ignore > + StringRef FPExceptionBehavior = ""; > StringRef DenormalFPMath = ""; > StringRef FPContract = ""; > + bool StrictFPModel = false; > > if (const Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) > { > CmdArgs.push_back("-mlimit-float-precision"); > @@ -2312,7 +2321,73 @@ static void RenderFloatingPointOptions(const > ToolChain &TC, const Driver &D, > } > > for (const Arg *A : Args) { > - switch (A->getOption().getID()) { > + auto optID = A->getOption().getID(); > + bool PreciseFPModel = false; > + switch (optID) { > + default: > + break; > + case options::OPT_frounding_math: > + case options::OPT_ftrapping_math: > + case options::OPT_ffp_exception_behavior_EQ: > + D.Diag(clang::diag::warn_drv_experimental_fp_control_incomplete_opt) > + << A->getOption().getName(); > + break; > + case options::OPT_ffp_model_EQ: { > + D.Diag(clang::diag::warn_drv_experimental_fp_control_incomplete_opt) > + << A->getOption().getName(); > + // If -ffp-model= is seen, reset to fno-fast-math > + HonorINFs = true; > + HonorNaNs = true; > + // Turning *off* -ffast-math restores the toolchain default. > + MathErrno = TC.IsMathErrnoDefault(); > + AssociativeMath = false; > + ReciprocalMath = false; > + SignedZeros = true; > + // -fno_fast_math restores default denormal and fpcontract handling > + DenormalFPMath = ""; > + FPContract = ""; > + StringRef Val = A->getValue(); > + if (OFastEnabled && !Val.equals("fast")) { > + // Only -ffp-model=fast is compatible with OFast, ignore. > + D.Diag(clang::diag::warn_drv_overriding_flag_option) > + << Args.MakeArgString("-ffp-model=" + Val) > + << "-Ofast"; > + break; > + } > + StrictFPModel = false; > + PreciseFPModel = true; > + // ffp-model= is a Driver option, it is entirely rewritten into more > + // granular options before being passed into cc1. > + // Use the gcc option in the switch below. > + if (!FPModel.empty() && !FPModel.equals(Val)) { > + D.Diag(clang::diag::warn_drv_overriding_flag_option) > + << Args.MakeArgString("-ffp-model=" + FPModel) > + << Args.MakeArgString("-ffp-model=" + Val); > + FPContract = ""; > + } > + if (Val.equals("fast")) { > + optID = options::OPT_ffast_math; > + FPModel = Val; > + FPContract = "fast"; > + } else if (Val.equals("precise")) { > + optID = options::OPT_ffp_contract; > + FPModel = Val; > + FPContract = "fast"; > + PreciseFPModel = true; > + } else if (Val.equals("strict")) { > + StrictFPModel = true; > + optID = options::OPT_frounding_math; > + FPExceptionBehavior = "strict"; > + FPModel = Val; > + TrappingMath = true; > + } else > + D.Diag(diag::err_drv_unsupported_option_argument) > + << A->getOption().getName() << Val; > + break; > + } > + } > + > + switch (optID) { > // If this isn't an FP option skip the claim below > default: continue; > > @@ -2329,19 +2404,82 @@ static void RenderFloatingPointOptions(const > ToolChain &TC, const Driver &D, > case options::OPT_fno_reciprocal_math: ReciprocalMath = false; > break; > case options::OPT_fsigned_zeros: SignedZeros = true; > break; > case options::OPT_fno_signed_zeros: SignedZeros = false; > break; > - case options::OPT_ftrapping_math: TrappingMath = true; > break; > - case options::OPT_fno_trapping_math: TrappingMath = false; > break; > + case options::OPT_ftrapping_math: > + if (!TrappingMathPresent && !FPExceptionBehavior.empty() && > + !FPExceptionBehavior.equals("strict")) > + // Warn that previous value of option is overridden. > + D.Diag(clang::diag::warn_drv_overriding_flag_option) > + << Args.MakeArgString("-ffp-exception-behavior=" + > FPExceptionBehavior) > + << "-ftrapping-math"; > + TrappingMath = true; > + TrappingMathPresent = true; > + FPExceptionBehavior = "strict"; > + break; > + case options::OPT_fno_trapping_math: > + if (!TrappingMathPresent && !FPExceptionBehavior.empty() && > + !FPExceptionBehavior.equals("ignore")) > + // Warn that previous value of option is overridden. > + D.Diag(clang::diag::warn_drv_overriding_flag_option) > + << Args.MakeArgString("-ffp-exception-behavior=" + > FPExceptionBehavior) > + << "-fno-trapping-math"; > + TrappingMath = false; > + TrappingMathPresent = true; > + FPExceptionBehavior = "ignore"; > + break; > + > + case options::OPT_frounding_math: > + RoundingFPMath = true; > + RoundingMathPresent = true; > + break; > + > + case options::OPT_fno_rounding_math: > + RoundingFPMath = false; > + RoundingMathPresent = false; > + break; > > case options::OPT_fdenormal_fp_math_EQ: > DenormalFPMath = A->getValue(); > break; > > - // Validate and pass through -fp-contract option. > + // Validate and pass through -ffp-contract option. > case options::OPT_ffp_contract: { > StringRef Val = A->getValue(); > - if (Val == "fast" || Val == "on" || Val == "off") > + if (PreciseFPModel) { > + // -ffp-model=precise enables ffp-contract=fast as a side effect > + // the FPContract value has already been set to a string literal > + // and the Val string isn't a pertinent value. > + ; > + } else if (Val.equals("fast") || Val.equals("on") || > Val.equals("off")) > FPContract = Val; > else > + D.Diag(diag::err_drv_unsupported_option_argument) > + << A->getOption().getName() << Val; > + break; > + } > + > + // Validate and pass through -ffp-model option. > + case options::OPT_ffp_model_EQ: > + // This should only occur in the error case > + // since the optID has been replaced by a more granular > + // floating point option. > + break; > + > + // Validate and pass through -ffp-exception-behavior option. > + case options::OPT_ffp_exception_behavior_EQ: { > + StringRef Val = A->getValue(); > + if (!TrappingMathPresent && !FPExceptionBehavior.empty() && > + !FPExceptionBehavior.equals(Val)) > + // Warn that previous value of option is overridden. > + D.Diag(clang::diag::warn_drv_overriding_flag_option) > + << Args.MakeArgString("-ffp-exception-behavior=" + > FPExceptionBehavior) > + << Args.MakeArgString("-ffp-exception-behavior=" + Val); > + TrappingMath = TrappingMathPresent = false; > + if (Val.equals("ignore") || Val.equals("maytrap")) > + FPExceptionBehavior = Val; > + else if (Val.equals("strict")) { > + FPExceptionBehavior = Val; > + TrappingMath = TrappingMathPresent = true; > + } else > D.Diag(diag::err_drv_unsupported_option_argument) > << A->getOption().getName() << Val; > break; > @@ -2361,12 +2499,14 @@ static void RenderFloatingPointOptions(const > ToolChain &TC, const Driver &D, > ReciprocalMath = true; > SignedZeros = false; > TrappingMath = false; > + FPExceptionBehavior = ""; > break; > case options::OPT_fno_unsafe_math_optimizations: > AssociativeMath = false; > ReciprocalMath = false; > SignedZeros = true; > TrappingMath = true; > + FPExceptionBehavior = "strict"; > // -fno_unsafe_math_optimizations restores default denormal handling > DenormalFPMath = ""; > break; > @@ -2384,6 +2524,7 @@ static void RenderFloatingPointOptions(const > ToolChain &TC, const Driver &D, > ReciprocalMath = true; > SignedZeros = false; > TrappingMath = false; > + RoundingFPMath = false; > // If fast-math is set then set the fp-contract mode to fast. > FPContract = "fast"; > break; > @@ -2397,12 +2538,31 @@ static void RenderFloatingPointOptions(const > ToolChain &TC, const Driver &D, > AssociativeMath = false; > ReciprocalMath = false; > SignedZeros = true; > - TrappingMath = true; > + TrappingMath = false; > + RoundingFPMath = false; > // -fno_fast_math restores default denormal and fpcontract handling > DenormalFPMath = ""; > FPContract = ""; > break; > } > + if (StrictFPModel) { > + // If -ffp-model=strict has been specified on command line but > + // subsequent options conflict then emit warning diagnostic. > + if (HonorINFs && HonorNaNs && > + !AssociativeMath && !ReciprocalMath && > + SignedZeros && TrappingMath && RoundingFPMath && > + DenormalFPMath.empty() && FPContract.empty()) > + // OK: Current Arg doesn't conflict with -ffp-model=strict > + ; > + else { > + StrictFPModel = false; > + FPModel = ""; > + D.Diag(clang::diag::warn_drv_overriding_flag_option) > + << "-ffp-model=strict" << > + ((A->getNumValues() == 0) ? A->getSpelling() > + : Args.MakeArgString(A->getSpelling() + A->getValue())); > + } > + } > > // If we handled this option claim it > A->claim(); > @@ -2430,7 +2590,11 @@ static void RenderFloatingPointOptions(const > ToolChain &TC, const Driver &D, > if (ReciprocalMath) > CmdArgs.push_back("-freciprocal-math"); > > - if (!TrappingMath) > + if (TrappingMath) { > + // FP Exception Behavior is also set to strict > + assert(FPExceptionBehavior.equals("strict")); > + CmdArgs.push_back("-ftrapping-math"); > + } else if (TrappingMathPresent) > CmdArgs.push_back("-fno-trapping-math"); > > if (!DenormalFPMath.empty()) > @@ -2440,14 +2604,37 @@ static void RenderFloatingPointOptions(const > ToolChain &TC, const Driver &D, > if (!FPContract.empty()) > CmdArgs.push_back(Args.MakeArgString("-ffp-contract=" + FPContract)); > > + if (!RoundingFPMath) > + CmdArgs.push_back(Args.MakeArgString("-fno-rounding-math")); > + > + if (RoundingFPMath && RoundingMathPresent) > + CmdArgs.push_back(Args.MakeArgString("-frounding-math")); > + > + if (!FPExceptionBehavior.empty()) > + CmdArgs.push_back(Args.MakeArgString("-ffp-exception-behavior=" + > + FPExceptionBehavior)); > + > ParseMRecip(D, Args, CmdArgs); > > // -ffast-math enables the __FAST_MATH__ preprocessor macro, but check > for the > // individual features enabled by -ffast-math instead of the option > itself as > // that's consistent with gcc's behaviour. > if (!HonorINFs && !HonorNaNs && !MathErrno && AssociativeMath && > - ReciprocalMath && !SignedZeros && !TrappingMath) > + ReciprocalMath && !SignedZeros && !TrappingMath && !RoundingFPMath) > { > CmdArgs.push_back("-ffast-math"); > + if (FPModel.equals("fast")) { > + if (FPContract.equals("fast")) > + // All set, do nothing. > + ; > + else if (FPContract.empty()) > + // Enable -ffp-contract=fast > + CmdArgs.push_back(Args.MakeArgString("-ffp-contract=fast")); > + else > + D.Diag(clang::diag::warn_drv_overriding_flag_option) > + << "-ffp-model=fast" > + << Args.MakeArgString("-ffp-contract=" + FPContract); > + } > + } > > // Handle __FINITE_MATH_ONLY__ similarly. > if (!HonorINFs && !HonorNaNs) > > diff --git a/clang/lib/Frontend/CompilerInvocation.cpp > b/clang/lib/Frontend/CompilerInvocation.cpp > index 74831e78d8cb..198ae69b7655 100644 > --- a/clang/lib/Frontend/CompilerInvocation.cpp > +++ b/clang/lib/Frontend/CompilerInvocation.cpp > @@ -3145,6 +3145,34 @@ static void ParseLangArgs(LangOptions &Opts, > ArgList &Args, InputKind IK, > Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) > << Val; > } > > + LangOptions::FPRoundingModeKind FPRM = LangOptions::FPR_ToNearest; > + if (Args.hasArg(OPT_frounding_math)) { > + FPRM = LangOptions::FPR_Dynamic; > + } > + Opts.setFPRoundingMode(FPRM); > + > + if (Args.hasArg(OPT_ftrapping_math)) { > + Opts.setFPExceptionMode(LangOptions::FPE_Strict); > + } > + > + if (Args.hasArg(OPT_fno_trapping_math)) { > + Opts.setFPExceptionMode(LangOptions::FPE_Ignore); > + } > + > + LangOptions::FPExceptionModeKind FPEB = LangOptions::FPE_Ignore; > + if (Arg *A = Args.getLastArg(OPT_ffp_exception_behavior_EQ)) { > + StringRef Val = A->getValue(); > + if (Val.equals("ignore")) > + FPEB = LangOptions::FPE_Ignore; > + else if (Val.equals("maytrap")) > + FPEB = LangOptions::FPE_MayTrap; > + else if (Val.equals("strict")) > + FPEB = LangOptions::FPE_Strict; > + else > + Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) > << Val; > + } > + Opts.setFPExceptionMode(FPEB); > + > Opts.RetainCommentsFromSystemHeaders = > Args.hasArg(OPT_fretain_comments_from_system_headers); > > > diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp > index 7bbda127a540..c53a4b789bed 100644 > --- a/clang/lib/Sema/SemaExpr.cpp > +++ b/clang/lib/Sema/SemaExpr.cpp > @@ -13037,6 +13037,16 @@ ExprResult > Sema::CreateBuiltinBinOp(SourceLocation OpLoc, > if (ResultTy.isNull() || LHS.isInvalid() || RHS.isInvalid()) > return ExprError(); > > + if (ResultTy->isRealFloatingType() && > + (getLangOpts().getFPRoundingMode() != LangOptions::FPR_ToNearest || > + getLangOpts().getFPExceptionMode() != LangOptions::FPE_Ignore)) > + // Mark the current function as usng floating point constrained > intrinsics > + if (FunctionDecl *F = dyn_cast<FunctionDecl>(CurContext)) > +{ > + F->setUsesFPIntrin(true); > + printf("Enclosing function uses fp intrinsics\n"); > +} > + > // Some of the binary operations require promoting operands of half > vector to > // float vectors and truncating the result back to half vector. For > now, we do > // this only when HalfArgsAndReturn is set (that is, when the target is > arm or > > diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp > b/clang/lib/Serialization/ASTReaderDecl.cpp > index 3f7a1ed7fd5c..d989f46c4ab4 100644 > --- a/clang/lib/Serialization/ASTReaderDecl.cpp > +++ b/clang/lib/Serialization/ASTReaderDecl.cpp > @@ -886,6 +886,7 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl > *FD) { > > FD->ODRHash = Record.readInt(); > FD->setHasODRHash(true); > + FD->setUsesFPIntrin(Record.readInt()); > > switch ((FunctionDecl::TemplatedKind)Record.readInt()) { > case FunctionDecl::TK_NonTemplate: > > diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp > b/clang/lib/Serialization/ASTWriterDecl.cpp > index 51902a607ca1..38eb64e52e4a 100644 > --- a/clang/lib/Serialization/ASTWriterDecl.cpp > +++ b/clang/lib/Serialization/ASTWriterDecl.cpp > @@ -559,6 +559,7 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) > { > Record.AddSourceLocation(D->getEndLoc()); > > Record.push_back(D->getODRHash()); > + Record.push_back(D->usesFPIntrin()); > > Record.push_back(D->getTemplatedKind()); > switch (D->getTemplatedKind()) { > > diff --git a/clang/test/CodeGen/fpconstrained.c > b/clang/test/CodeGen/fpconstrained.c > new file mode 100644 > index 000000000000..0a890e2e702e > --- /dev/null > +++ b/clang/test/CodeGen/fpconstrained.c > @@ -0,0 +1,23 @@ > +// RUN: %clang_cc1 -ftrapping-math -frounding-math > -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s > -check-prefix=FPMODELSTRICT > +// RUN: %clang_cc1 -ffp-contract=fast -emit-llvm -o - %s | FileCheck %s > -check-prefix=PRECISE > +// RUN: %clang_cc1 -ffast-math -ffp-contract=fast -emit-llvm -o - %s | > FileCheck %s -check-prefix=FAST > +// RUN: %clang_cc1 -ffast-math -emit-llvm -o - %s | FileCheck %s > -check-prefix=FAST > +// RUN: %clang_cc1 -ffast-math -ffp-contract=fast > -ffp-exception-behavior=ignore -emit-llvm -o - %s | FileCheck %s > -check-prefix=FAST > +// RUN: %clang_cc1 -ffast-math -ffp-contract=fast > -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s > -check-prefix=EXCEPT > +// RUN: %clang_cc1 -ffast-math -ffp-contract=fast > -ffp-exception-behavior=maytrap -emit-llvm -o - %s | FileCheck %s > -check-prefix=MAYTRAP > +float f0, f1, f2; > + > +void foo() { > + // CHECK-LABEL: define {{.*}}void @foo() > + > + // MAYTRAP: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float > %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.maytrap") > + // EXCEPT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float > %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") > + // FPMODELSTRICT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, > float %{{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") > + // STRICTEXCEPT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, > float %{{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") > + // STRICTNOEXCEPT: llvm.experimental.constrained.fadd.f32(float > %{{.*}}, float %{{.*}}, metadata !"round.dynamic", metadata > !"fpexcept.ignore") > + // PRECISE: fadd contract float %{{.*}}, %{{.*}} > + // FAST: fadd fast > + f0 = f1 + f2; > + > + // CHECK: ret > +} > > diff --git a/clang/test/CodeGen/fpconstrained.cpp > b/clang/test/CodeGen/fpconstrained.cpp > new file mode 100644 > index 000000000000..7aa34c98a487 > --- /dev/null > +++ b/clang/test/CodeGen/fpconstrained.cpp > @@ -0,0 +1,47 @@ > +// RUN: %clang_cc1 -x c++ -ftrapping-math -fexceptions -fcxx-exceptions > -frounding-math -ffp-exception-behavior=strict -emit-llvm -o - %s | > FileCheck %s -check-prefix=FPMODELSTRICT > +// RUN: %clang_cc1 -x c++ -ffp-contract=fast -fexceptions > -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix=PRECISE > +// RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions > -ffp-contract=fast -emit-llvm -o - %s | FileCheck %s -check-prefix=FAST > +// RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions > -emit-llvm -o - %s | FileCheck %s -check-prefix=FAST > +// RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions > -ffp-contract=fast -ffp-exception-behavior=ignore -emit-llvm -o - %s | > FileCheck %s -check-prefix=FAST > +// RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions > -ffp-contract=fast -ffp-exception-behavior=strict -emit-llvm -o - %s | > FileCheck %s -check-prefix=EXCEPT > +// RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions > -ffp-contract=fast -ffp-exception-behavior=maytrap -emit-llvm -o - %s | > FileCheck %s -check-prefix=MAYTRAP > +float f0, f1, f2; > + > + template <class> > + class aaaa { > + public: > + ~aaaa(); > + void b(); > + }; > + > + template <class c> > + aaaa<c>::~aaaa() { try { > + b(); > + // CHECK-LABEL: define {{.*}}void @_ZN4aaaaIiED2Ev{{.*}} > + > + } catch (...) { > + // MAYTRAP: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float > %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.maytrap") > + // EXCEPT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float > %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") > + // FPMODELSTRICT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, > float %{{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") > + // STRICTEXCEPT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, > float %{{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") > + // STRICTNOEXCEPT: llvm.experimental.constrained.fadd.f32(float > %{{.*}}, float %{{.*}}, metadata !"round.dynamic", metadata > !"fpexcept.ignore") > + // PRECISE: fadd contract float %{{.*}}, %{{.*}} > + // FAST: fadd fast > + f0 = f1 + f2; > + > + // CHECK: ret void > + } > + } > + > + class d { > + public: > + d(const char *, int); > + aaaa<int> e; > + }; > + > +float foo() { > + d x("", 1); > + aaaa<int> a; > + return f0; > +} > + > > diff --git a/clang/test/Driver/clang_f_opts.c > b/clang/test/Driver/clang_f_opts.c > index 17feaab26ab7..fef9cbfb115e 100644 > --- a/clang/test/Driver/clang_f_opts.c > +++ b/clang/test/Driver/clang_f_opts.c > @@ -198,6 +198,22 @@ > // CHECK-EXTENDED-IDENTIFIERS-NOT: "-fextended-identifiers" > // CHECK-NO-EXTENDED-IDENTIFIERS: error: unsupported option > '-fno-extended-identifiers' > > +// RUN: %clang -### -S -frounding-math %s 2>&1 | FileCheck > -check-prefix=CHECK-ROUNDING-MATH %s > +// CHECK-ROUNDING-MATH: "-cc1" > +// CHECK-ROUNDING-MATH: "-frounding-math" > +// CHECK-ROUNDING-MATH-NOT: "-fno-rounding-math" > +// RUN: %clang -### -S %s 2>&1 | FileCheck > -check-prefix=CHECK-ROUNDING-MATH-NOT %s > +// RUN: %clang -### -S -ffp-model=imprecise %s 2>&1 | FileCheck > -check-prefix=CHECK-FPMODEL %s > +// CHECK-FPMODEL: unsupported argument 'imprecise' to option 'ffp-model=' > +// RUN: %clang -### -S -ffp-model=precise %s 2>&1 | FileCheck > -check-prefix=IGNORE %s > +// RUN: %clang -### -S -ffp-model=strict %s 2>&1 | FileCheck > -check-prefix=IGNORE %s > +// RUN: %clang -### -S -ffp-model=fast %s 2>&1 | FileCheck > -check-prefix=IGNORE %s > +// RUN: %clang -### -S -ffp-exception-behavior=trap %s 2>&1 | FileCheck > -check-prefix=CHECK-FPEB %s > +// CHECK-FPEB: unsupported argument 'trap' to option > 'ffp-exception-behavior=' > +// RUN: %clang -### -S -ffp-exception-behavior=maytrap %s 2>&1 | > FileCheck -check-prefix=IGNORE %s > +// RUN: %clang -### -S -ffp-exception-behavior=ignore %s 2>&1 | FileCheck > -check-prefix=IGNORE %s > +// RUN: %clang -### -S -ffp-exception-behavior=strict %s 2>&1 | FileCheck > -check-prefix=IGNORE %s > + > // RUN: %clang -### -S -fno-pascal-strings -mpascal-strings %s 2>&1 | > FileCheck -check-prefix=CHECK-M-PASCAL-STRINGS %s > // CHECK-M-PASCAL-STRINGS: "-fpascal-strings" > > @@ -320,7 +336,6 @@ > // RUN: -fprefetch-loop-arrays > \ > // RUN: -fprofile-correction > \ > // RUN: -fprofile-values > \ > -// RUN: -frounding-math > \ > // RUN: -fschedule-insns > \ > // RUN: -fsignaling-nans > \ > // RUN: -fstrength-reduce > \ > @@ -385,7 +400,6 @@ > // CHECK-WARNING-DAG: optimization flag '-fprefetch-loop-arrays' is not > supported > // CHECK-WARNING-DAG: optimization flag '-fprofile-correction' is not > supported > // CHECK-WARNING-DAG: optimization flag '-fprofile-values' is not > supported > -// CHECK-WARNING-DAG: optimization flag '-frounding-math' is not supported > // CHECK-WARNING-DAG: optimization flag '-fschedule-insns' is not > supported > // CHECK-WARNING-DAG: optimization flag '-fsignaling-nans' is not > supported > // CHECK-WARNING-DAG: optimization flag '-fstrength-reduce' is not > supported > > diff --git a/clang/test/Driver/fast-math.c b/clang/test/Driver/fast-math.c > index 916384216d8c..da47de260dc9 100644 > --- a/clang/test/Driver/fast-math.c > +++ b/clang/test/Driver/fast-math.c > @@ -170,11 +170,11 @@ > // RUN: %clang -### -fno-fast-math -ffast-math -c %s 2>&1 \ > // RUN: | FileCheck --check-prefix=CHECK-FAST-MATH %s > // RUN: %clang -### -funsafe-math-optimizations -ffinite-math-only \ > -// RUN: -fno-math-errno -ffp-contract=fast -c %s 2>&1 \ > +// RUN: -fno-math-errno -ffp-contract=fast -fno-rounding-math -c %s > 2>&1 \ > // RUN: | FileCheck --check-prefix=CHECK-FAST-MATH %s > // RUN: %clang -### -fno-honor-infinities -fno-honor-nans -fno-math-errno > \ > // RUN: -fassociative-math -freciprocal-math -fno-signed-zeros \ > -// RUN: -fno-trapping-math -ffp-contract=fast -c %s 2>&1 \ > +// RUN: -fno-trapping-math -ffp-contract=fast -fno-rounding-math -c > %s 2>&1 \ > // RUN: | FileCheck --check-prefix=CHECK-FAST-MATH %s > // CHECK-FAST-MATH: "-cc1" > // CHECK-FAST-MATH: "-ffast-math" > > diff --git a/clang/test/Driver/fp-model.c b/clang/test/Driver/fp-model.c > new file mode 100644 > index 000000000000..a3984acef62b > --- /dev/null > +++ b/clang/test/Driver/fp-model.c > @@ -0,0 +1,137 @@ > +// Test that incompatible combinations of -ffp-model= options > +// and other floating point options get a warning diagnostic. > +// > +// REQUIRES: clang-driver > + > +// RUN: %clang -### -ffp-model=fast -ffp-contract=off -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=WARN %s > +// WARN: warning: overriding '-ffp-model=fast' option with > '-ffp-contract=off' [-Woverriding-t-option] > + > +// RUN: %clang -### -ffp-model=fast -ffp-contract=on -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=WARN1 %s > +// WARN1: warning: overriding '-ffp-model=fast' option with > '-ffp-contract=on' [-Woverriding-t-option] > + > +// RUN: %clang -### -ffp-model=strict -fassociative-math -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=WARN2 %s > +// WARN2: warning: overriding '-ffp-model=strict' option with > '-fassociative-math' [-Woverriding-t-option] > + > +// RUN: %clang -### -ffp-model=strict -ffast-math -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=WARN3 %s > +// WARN3: warning: overriding '-ffp-model=strict' option with > '-ffast-math' [-Woverriding-t-option] > + > +// RUN: %clang -### -ffp-model=strict -ffinite-math-only -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=WARN4 %s > +// WARN4: warning: overriding '-ffp-model=strict' option with > '-ffinite-math-only' [-Woverriding-t-option] > + > +// RUN: %clang -### -ffp-model=strict -ffp-contract=fast -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=WARN5 %s > +// WARN5: warning: overriding '-ffp-model=strict' option with > '-ffp-contract=fast' [-Woverriding-t-option] > + > +// RUN: %clang -### -ffp-model=strict -ffp-contract=off -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=WARN6 %s > +// WARN6: warning: overriding '-ffp-model=strict' option with > '-ffp-contract=off' [-Woverriding-t-option] > + > +// RUN: %clang -### -ffp-model=strict -ffp-contract=on -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=WARN7 %s > +// WARN7: warning: overriding '-ffp-model=strict' option with > '-ffp-contract=on' [-Woverriding-t-option] > + > +// RUN: %clang -### -ffp-model=strict -fno-honor-infinities -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=WARN8 %s > +// WARN8: warning: overriding '-ffp-model=strict' option with > '-fno-honor-infinities' [-Woverriding-t-option] > + > +// RUN: %clang -### -ffp-model=strict -fno-honor-nans -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=WARN9 %s > +// WARN9: warning: overriding '-ffp-model=strict' option with > '-fno-honor-nans' [-Woverriding-t-option] > + > +// RUN: %clang -### -ffp-model=strict -fno-rounding-math -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=WARNa %s > +// WARNa: warning: overriding '-ffp-model=strict' option with > '-fno-rounding-math' [-Woverriding-t-option] > + > +// RUN: %clang -### -ffp-model=strict -fno-signed-zeros -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=WARNb %s > +// WARNb: warning: overriding '-ffp-model=strict' option with > '-fno-signed-zeros' [-Woverriding-t-option] > + > +// RUN: %clang -### -ffp-model=strict -fno-trapping-math -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=WARNc %s > +// WARNc: warning: overriding '-ffp-model=strict' option with > '-fno-trapping-math' [-Woverriding-t-option] > + > +// RUN: %clang -### -ffp-model=strict -freciprocal-math -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=WARNd %s > +// WARNd: warning: overriding '-ffp-model=strict' option with > '-freciprocal-math' [-Woverriding-t-option] > + > +// RUN: %clang -### -ffp-model=strict -funsafe-math-optimizations -c %s > 2>&1 \ > +// RUN: | FileCheck --check-prefix=WARNe %s > +// WARNe: warning: overriding '-ffp-model=strict' option with > '-funsafe-math-optimizations' [-Woverriding-t-option] > + > +// RUN: %clang -### -ffp-model=strict -Ofast -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=WARNf %s > +// WARNf: warning: overriding '-ffp-model=strict' option with '-Ofast' > [-Woverriding-t-option] > + > +// RUN: %clang -### -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=CHECK-NOROUND %s > +// CHECK-NOROUND: "-cc1" > +// CHECK-NOROUND: "-fno-rounding-math" > + > +// RUN: %clang -### -frounding-math -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=CHECK-ROUND --implicit-check-not > ffp-exception-behavior=strict %s > +// CHECK-ROUND: "-cc1" > +// CHECK-ROUND: "-frounding-math" > + > +// RUN: %clang -### -ftrapping-math -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=CHECK-TRAP %s > +// CHECK-TRAP: "-cc1" > +// CHECK-TRAP: "-ftrapping-math" > +// CHECK-TRAP: "-ffp-exception-behavior=strict" > + > +// RUN: %clang -### -nostdinc -ffp-model=fast -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=CHECK-FPM-FAST %s > +// CHECK-FPM-FAST: "-cc1" > +// CHECK-FPM-FAST: "-menable-no-infs" > +// CHECK-FPM-FAST: "-menable-no-nans" > +// CHECK-FPM-FAST: "-menable-unsafe-fp-math" > +// CHECK-FPM-FAST: "-fno-signed-zeros" > +// CHECK-FPM-FAST: "-mreassociate" > +// CHECK-FPM-FAST: "-freciprocal-math" > +// CHECK-FPM-FAST: "-ffp-contract=fast" > +// CHECK-FPM-FAST: "-fno-rounding-math" > +// CHECK-FPM-FAST: "-ffast-math" > +// CHECK-FPM-FAST: "-ffinite-math-only" > + > +// RUN: %clang -### -nostdinc -ffp-model=precise -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=CHECK-FPM-PRECISE %s > +// CHECK-FPM-PRECISE: "-cc1" > +// CHECK-FPM-PRECISE: "-ffp-contract=fast" > +// CHECK-FPM-PRECISE: "-fno-rounding-math" > + > +// RUN: %clang -### -nostdinc -ffp-model=strict -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=CHECK-FPM-STRICT %s > +// CHECK-FPM-STRICT: "-cc1" > +// CHECK-FPM-STRICT: "-ftrapping-math" > +// CHECK-FPM-STRICT: "-frounding-math" > +// CHECK-FPM-STRICT: "-ffp-exception-behavior=strict" > + > +// RUN: %clang -### -nostdinc -ftrapping-math > -ffp-exception-behavior=ignore -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=CHECK-TRAP-IGNORE %s > +// CHECK-TRAP-IGNORE: "-cc1" > +// CHECK-TRAP-IGNORE: "-fno-rounding-math" > +// CHECK-TRAP-IGNORE: "-ffp-exception-behavior=ignore" > + > + > +// RUN: %clang -### -nostdinc -ffp-exception-behavior=strict -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=CHECK-FEB-STRICT %s > +// CHECK-FEB-STRICT: "-cc1" > +// CHECK-FEB-STRICT: "-fno-rounding-math" > +// CHECK-FEB-STRICT: "-ffp-exception-behavior=strict" > + > +// RUN: %clang -### -nostdinc -ffp-exception-behavior=maytrap -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=CHECK-FEB-MAYTRAP %s > +// CHECK-FEB-MAYTRAP: "-cc1" > +// CHECK-FEB-MAYTRAP: "-fno-rounding-math" > +// CHECK-FEB-MAYTRAP: "-ffp-exception-behavior=maytrap" > + > +// RUN: %clang -### -nostdinc -ffp-exception-behavior=ignore -c %s 2>&1 \ > +// RUN: | FileCheck --check-prefix=CHECK-FEB-IGNORE %s > +// CHECK-FEB-IGNORE: "-cc1" > +// CHECK-FEB-IGNORE: "-fno-rounding-math" > +// CHECK-FEB-IGNORE: "-ffp-exception-behavior=ignore" > + > > diff --git a/llvm/include/llvm/IR/IRBuilder.h > b/llvm/include/llvm/IR/IRBuilder.h > index 2d9c72108d3d..24d39c2bc526 100644 > --- a/llvm/include/llvm/IR/IRBuilder.h > +++ b/llvm/include/llvm/IR/IRBuilder.h > @@ -265,7 +265,6 @@ class IRBuilderBase { > void setConstrainedFPCallAttr(CallInst *I) { > if (!I->hasFnAttr(Attribute::StrictFP)) > I->addAttribute(AttributeList::FunctionIndex, Attribute::StrictFP); > - setConstrainedFPFunctionAttr(); > } > > > > //===--------------------------------------------------------------------===// > > diff --git a/llvm/include/llvm/Target/TargetOptions.h > b/llvm/include/llvm/Target/TargetOptions.h > index c395e5bcecf1..d1db4eceabb8 100644 > --- a/llvm/include/llvm/Target/TargetOptions.h > +++ b/llvm/include/llvm/Target/TargetOptions.h > @@ -107,7 +107,7 @@ namespace llvm { > public: > TargetOptions() > : PrintMachineCode(false), UnsafeFPMath(false), > NoInfsFPMath(false), > - NoNaNsFPMath(false), NoTrappingFPMath(false), > + NoNaNsFPMath(false), NoTrappingFPMath(true), > NoSignedZerosFPMath(false), > HonorSignDependentRoundingFPMathOption(false), > NoZerosInBSS(false), > GuaranteedTailCallOpt(false), StackSymbolOrdering(true), > > diff --git a/llvm/unittests/IR/IRBuilderTest.cpp > b/llvm/unittests/IR/IRBuilderTest.cpp > index d7712fda1270..814da64c7852 100644 > --- a/llvm/unittests/IR/IRBuilderTest.cpp > +++ b/llvm/unittests/IR/IRBuilderTest.cpp > @@ -183,6 +183,8 @@ TEST_F(IRBuilderTest, ConstrainedFP) { > // See if we get constrained intrinsics instead of non-constrained > // instructions. > Builder.setIsFPConstrained(true); > + auto Parent = BB->getParent(); > + Parent->addFnAttr(Attribute::StrictFP); > > V = Builder.CreateFAdd(V, V); > ASSERT_TRUE(isa<IntrinsicInst>(V)); > @@ -233,7 +235,8 @@ TEST_F(IRBuilderTest, ConstrainedFP) { > AttributeSet CallAttrs = II->getAttributes().getFnAttributes(); > EXPECT_EQ(CallAttrs.hasAttribute(Attribute::StrictFP), true); > > - // Verify attributes on the containing function are created > automatically. > + // Verify attributes on the containing function are created when > requested. > + Builder.setConstrainedFPFunctionAttr(); > AttributeList Attrs = BB->getParent()->getAttributes(); > AttributeSet FnAttrs = Attrs.getFnAttributes(); > EXPECT_EQ(FnAttrs.hasAttribute(Attribute::StrictFP), true); > > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits