[clang] 4bafe65 - Add support for floating-point option `ffp-eval-method` and for
Aaron Ballman via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 15 15:26:07 PST 2022
https://reviews.llvm.org/D109239
On Tue, Feb 15, 2022, 5:26 PM Roman Lebedev via cfe-commits <
cfe-commits at lists.llvm.org> wrote:
> Where was this reviewed?
>
> On Wed, Feb 16, 2022 at 12:59 AM Zahira Ammarguellat via cfe-commits
> <cfe-commits at lists.llvm.org> wrote:
> >
> >
> > Author: Zahira Ammarguellat
> > Date: 2022-02-15T13:59:27-08:00
> > New Revision: 4bafe65c2b2f1ce745894a509a6d80c87fb1c335
> >
> > URL:
> https://github.com/llvm/llvm-project/commit/4bafe65c2b2f1ce745894a509a6d80c87fb1c335
> > DIFF:
> https://github.com/llvm/llvm-project/commit/4bafe65c2b2f1ce745894a509a6d80c87fb1c335.diff
> >
> > LOG: Add support for floating-point option `ffp-eval-method` and for
> > `pragma clang fp eval_method`.
> >
> > Added:
> > clang/test/CodeGen/X86/32bit-behavior-no-eval.c
> > clang/test/CodeGen/X86/32bit-behavior.c
> > clang/test/CodeGen/X86/fp-eval-method.c
> > clang/test/CodeGen/flt_eval_macro.cpp
> > clang/test/Preprocessor/flt_eval_macro.cpp
> > clang/test/Sema/fp-eval-pragma.cpp
> > clang/test/Sema/x86-eval-method.c
> > clang/test/Sema/x86_64-eval-method.c
> >
> > Modified:
> > clang/docs/LanguageExtensions.rst
> > clang/docs/UsersManual.rst
> > clang/include/clang/Basic/DiagnosticCommonKinds.td
> > clang/include/clang/Basic/DiagnosticLexKinds.td
> > clang/include/clang/Basic/FPOptions.def
> > clang/include/clang/Basic/LangOptions.def
> > clang/include/clang/Basic/LangOptions.h
> > clang/include/clang/Basic/TargetInfo.h
> > clang/include/clang/Driver/Options.td
> > clang/include/clang/Lex/Preprocessor.h
> > clang/include/clang/Parse/Parser.h
> > clang/include/clang/Sema/Sema.h
> > clang/lib/Basic/Targets/OSTargets.h
> > clang/lib/Basic/Targets/X86.h
> > clang/lib/Driver/ToolChains/Clang.cpp
> > clang/lib/Frontend/InitPreprocessor.cpp
> > clang/lib/Lex/PPMacroExpansion.cpp
> > clang/lib/Parse/ParsePragma.cpp
> > clang/lib/Parse/ParseStmt.cpp
> > clang/lib/Sema/Sema.cpp
> > clang/lib/Sema/SemaAttr.cpp
> > clang/lib/Sema/SemaExpr.cpp
> > clang/test/CodeGen/fp-floatcontrol-pragma.cpp
> > clang/test/Preprocessor/init-aarch64.c
> > clang/test/Preprocessor/init-arm.c
> > clang/test/Preprocessor/init-mips.c
> > clang/test/Preprocessor/init-ppc.c
> > clang/test/Preprocessor/init-ppc64.c
> > clang/test/Preprocessor/init-s390x.c
> > clang/test/Preprocessor/init-v7k-compat.c
> > clang/test/Preprocessor/init-x86.c
> > clang/test/Preprocessor/init.c
> >
> > Removed:
> >
> >
> >
> >
> ################################################################################
> > diff --git a/clang/docs/LanguageExtensions.rst
> b/clang/docs/LanguageExtensions.rst
> > index f45d88092eb4a..5249d3f3f7930 100644
> > --- a/clang/docs/LanguageExtensions.rst
> > +++ b/clang/docs/LanguageExtensions.rst
> > @@ -3907,6 +3907,38 @@ A ``#pragma clang fp`` pragma may contain any
> number of options:
> > ...
> > }
> >
> > +``#pragma clang fp eval_method`` allows floating-point behavior to be
> specified
> > +for a section of the source code. This pragma can appear at file or
> namespace
> > +scope, or at the start of a compound statement (excluding comments).
> > +The pragma is active within the scope of the compound statement.
> > +
> > +When ``pragma clang fp eval_method(source)`` is enabled, the section of
> code
> > +governed by the pragma behaves as though the command-line option
> > +``-ffp-eval-method=source`` is enabled. Rounds intermediate results to
> > +source-defined precision.
> > +
> > +When ``pragma clang fp eval_method(double)`` is enabled, the section of
> code
> > +governed by the pragma behaves as though the command-line option
> > +``-ffp-eval-method=double`` is enabled. Rounds intermediate results to
> > +``double`` precision.
> > +
> > +When ``pragma clang fp eval_method(extended)`` is enabled, the section
> of code
> > +governed by the pragma behaves as though the command-line option
> > +``-ffp-eval-method=extended`` is enabled. Rounds intermediate results to
> > +target-dependent ``long double`` precision. In Win32 programming, for
> instance,
> > +the long double data type maps to the double, 64-bit precision data
> type.
> > +
> > +The full syntax this pragma supports is
> > +``#pragma clang fp eval_method(source|double|extended)``.
> > +
> > +.. code-block:: c++
> > +
> > + for(...) {
> > + // The compiler will use long double as the floating-point
> evaluation
> > + // method.
> > + #pragma clang fp eval_method(extended)
> > + a = b[i] * c[i] + e;
> > + }
> >
> > The ``#pragma float_control`` pragma allows precise floating-point
> > semantics and floating-point exception behavior to be specified
> >
> > diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
> > index 1df96296cb8ac..70fee29ab2a84 100644
> > --- a/clang/docs/UsersManual.rst
> > +++ b/clang/docs/UsersManual.rst
> > @@ -1566,6 +1566,22 @@ Note that floating-point operations performed as
> part of constant initialization
> > * ``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.
> >
> > +.. option:: -ffp-eval-method=<value>
> > +
> > + Specify the floating-point evaluation method for intermediate
> results within
> > + a single expression of the code.
> > +
> > + Valid values are: ``source``, ``double``, and ``extended``.
> > + For 64-bit targets, the default value is ``source``. For 32-bit x86
> targets
> > + however, in the case of NETBSD 6.99.26 and under, the default value
> is
> > + ``double``; in the case of NETBSD greater than 6.99.26, with NoSSE,
> the
> > + default value is ``extended``, with SSE the default value is
> ``source``.
> > + Details:
> > +
> > + * ``source`` The compiler uses the floating-point type declared in
> the source program as the evaluation method.
> > + * ``double`` The compiler uses ``double`` as the floating-point
> evaluation method for all float expressions of type that is narrower than
> ``double``.
> > + * ``extended`` The compiler uses ``long double`` as the
> floating-point evaluation method for all float expressions of type that is
> narrower than ``long double``.
> > +
> > .. option:: -f[no-]protect-parens:
> >
> > This option pertains to floating-point types, complex types with
> > @@ -1587,6 +1603,17 @@ Note that floating-point operations performed as
> part of constant initialization
> > has no effect because the optimizer is prohibited from making unsafe
> > transformations.
> >
> > +.. _FLT_EVAL_METHOD:
> > +
> > +A note about ``__FLT_EVAL_METHOD__``
> > +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > +The macro ``__FLT_EVAL_METHOD__`` will expand to either the value set
> from the
> > +command line option ``ffp-eval-method`` or to the value from the target
> info
> > +setting. The ``__FLT_EVAL_METHOD__`` macro cannot expand to the correct
> > +evaluation method in the presence of a ``#pragma`` which alters the
> evaluation
> > +method. An error is issued if ``__FLT_EVAL_METHOD__`` is expanded
> inside a scope
> > +modified by ``#pragma clang fp eval_method``.
> > +
> > .. _fp-constant-eval:
> >
> > A note about Floating Point Constant Evaluation
> >
> > diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td
> b/clang/include/clang/Basic/DiagnosticCommonKinds.td
> > index 421527827a4bd..bbf26d637265e 100644
> > --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
> > +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
> > @@ -318,6 +318,11 @@ def err_opt_not_valid_on_target : Error<
> > def err_invalid_feature_combination : Error<
> > "invalid feature combination: %0">;
> >
> > +// Eval method
> > +def warn_no_support_for_eval_method_source_on_m32 : Warning<
> > + "Setting FPEvalMethod to source on a 32bit target, with no SSE is"
> > + " not supported.">;
> > +
> > // Source manager
> > def err_cannot_open_file : Error<"cannot open file '%0': %1">,
> DefaultFatal;
> > def err_file_modified : Error<
> >
> > diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td
> b/clang/include/clang/Basic/DiagnosticLexKinds.td
> > index a4436208799f9..0f424b02c812a 100644
> > --- a/clang/include/clang/Basic/DiagnosticLexKinds.td
> > +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
> > @@ -321,6 +321,10 @@ def err_pragma_include_instead_system_reserved :
> Error<
> > "header '%0' is an implementation detail; #include
> %select{'%2'|either '%2' "
> > "or '%3'|one of %2}1 instead">;
> >
> > +def err_illegal_use_of_flt_eval_macro : Error<
> > + "'__FLT_EVAL_METHOD__' cannot be expanded inside a scope containing "
> > + "'#pragma clang fp eval_method'">;
> > +
> > def pp_poisoning_existing_macro : Warning<"poisoning existing macro">;
> > def pp_out_of_date_dependency : Warning<
> > "current file is older than dependency %0">;
> >
> > diff --git a/clang/include/clang/Basic/FPOptions.def
> b/clang/include/clang/Basic/FPOptions.def
> > index a93fa475cd5f6..224c1827144f5 100644
> > --- a/clang/include/clang/Basic/FPOptions.def
> > +++ b/clang/include/clang/Basic/FPOptions.def
> > @@ -23,4 +23,5 @@ OPTION(NoHonorInfs, bool, 1, NoHonorNaNs)
> > OPTION(NoSignedZero, bool, 1, NoHonorInfs)
> > OPTION(AllowReciprocal, bool, 1, NoSignedZero)
> > OPTION(AllowApproxFunc, bool, 1, AllowReciprocal)
> > +OPTION(FPEvalMethod, LangOptions::FPEvalMethodKind, 2, AllowApproxFunc)
> > #undef OPTION
> >
> > diff --git a/clang/include/clang/Basic/LangOptions.def
> b/clang/include/clang/Basic/LangOptions.def
> > index 4651f4fff6aa0..89b11fdea89b2 100644
> > --- a/clang/include/clang/Basic/LangOptions.def
> > +++ b/clang/include/clang/Basic/LangOptions.def
> > @@ -301,6 +301,7 @@ BENIGN_ENUM_LANGOPT(DefaultFPContractMode,
> FPModeKind, 2, FPM_Off, "FP contracti
> > COMPATIBLE_LANGOPT(ExpStrictFP, 1, false, "Enable experimental strict
> floating point")
> > BENIGN_ENUM_LANGOPT(FPRoundingMode, RoundingMode, 3,
> RoundingMode::NearestTiesToEven, "FP Rounding Mode type")
> > BENIGN_ENUM_LANGOPT(FPExceptionMode, FPExceptionModeKind, 2,
> FPE_Ignore, "FP Exception Behavior Mode type")
> > +BENIGN_ENUM_LANGOPT(FPEvalMethod, FPEvalMethodKind, 2,
> FEM_UnsetOnCommandLine, "FP type used for floating point arithmetic")
> > 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 50c7f038fc6be..2e334e375950e 100644
> > --- a/clang/include/clang/Basic/LangOptions.h
> > +++ b/clang/include/clang/Basic/LangOptions.h
> > @@ -235,6 +235,24 @@ class LangOptions : public LangOptionsBase {
> > FPE_Strict
> > };
> >
> > + /// Possible float expression evaluation method choices.
> > + enum FPEvalMethodKind {
> > + /// The evaluation method cannot be determined or is inconsistent
> for this
> > + /// target.
> > + FEM_Indeterminable = -1,
> > + /// Use the declared type for fp arithmetic.
> > + FEM_Source = 0,
> > + /// Use the type double for fp arithmetic.
> > + FEM_Double = 1,
> > + /// Use extended type for fp arithmetic.
> > + FEM_Extended = 2,
> > + /// Used only for FE option processing; this is only used to
> indicate that
> > + /// the user did not specify an explicit evaluation method on the
> command
> > + /// line and so the target should be queried for its default
> evaluation
> > + /// method instead.
> > + FEM_UnsetOnCommandLine = 3
> > + };
> > +
> > /// Possible exception handling behavior.
> > enum class ExceptionHandlingKind { None, SjLj, WinEH, DwarfCFI, Wasm
> };
> >
> >
> > diff --git a/clang/include/clang/Basic/TargetInfo.h
> b/clang/include/clang/Basic/TargetInfo.h
> > index 22918f7e12e84..8e18ded7d3765 100644
> > --- a/clang/include/clang/Basic/TargetInfo.h
> > +++ b/clang/include/clang/Basic/TargetInfo.h
> > @@ -726,7 +726,11 @@ class TargetInfo : public virtual
> TransferrableTargetInfo,
> > }
> >
> > /// Return the value for the C99 FLT_EVAL_METHOD macro.
> > - virtual unsigned getFloatEvalMethod() const { return 0; }
> > + virtual LangOptions::FPEvalMethodKind getFPEvalMethod() const {
> > + return LangOptions::FPEvalMethodKind::FEM_Source;
> > + }
> > +
> > + virtual bool supportSourceEvalMethod() const { return true; }
> >
> > // getLargeArrayMinWidth/Align - Return the minimum array size that is
> > // 'large' and its alignment.
> >
> > diff --git a/clang/include/clang/Driver/Options.td
> b/clang/include/clang/Driver/Options.td
> > index b81973155cae6..f1e8b967c78e5 100644
> > --- a/clang/include/clang/Driver/Options.td
> > +++ b/clang/include/clang/Driver/Options.td
> > @@ -1495,6 +1495,11 @@ 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_eval_method_EQ : Joined<["-"], "ffp-eval-method=">,
> Group<f_Group>, Flags<[CC1Option]>,
> > + HelpText<"Specifies the evaluation method to use for floating-point
> arithmetic.">,
> > + Values<"source,double,extended">,
> NormalizedValuesScope<"LangOptions">,
> > + NormalizedValues<["FEM_Source", "FEM_Double", "FEM_Extended"]>,
> > + MarshallingInfoEnum<LangOpts<"FPEvalMethod">,
> "FEM_UnsetOnCommandLine">;
> > def ffp_model_EQ : Joined<["-"], "ffp-model=">, Group<f_Group>,
> Flags<[NoXarchOption]>,
> > HelpText<"Controls the semantics of floating-point calculations.">;
> > def ffp_exception_behavior_EQ : Joined<["-"],
> "ffp-exception-behavior=">, Group<f_Group>, Flags<[CC1Option]>,
> >
> > diff --git a/clang/include/clang/Lex/Preprocessor.h
> b/clang/include/clang/Lex/Preprocessor.h
> > index 2802329a60220..f2c84e43ddca3 100644
> > --- a/clang/include/clang/Lex/Preprocessor.h
> > +++ b/clang/include/clang/Lex/Preprocessor.h
> > @@ -179,12 +179,27 @@ class Preprocessor {
> > IdentifierInfo *Ident__is_target_vendor; // __is_target_vendor
> > IdentifierInfo *Ident__is_target_os; // __is_target_os
> > IdentifierInfo *Ident__is_target_environment; //
> __is_target_environment
> > + IdentifierInfo *Ident__FLT_EVAL_METHOD__; // __FLT_EVAL_METHOD
> >
> > // Weak, only valid (and set) while InMacroArgs is true.
> > Token* ArgMacro;
> >
> > SourceLocation DATELoc, TIMELoc;
> >
> > + // FEM_UnsetOnCommandLine means that an explicit evaluation method was
> > + // not specified on the command line. The target is queried to set the
> > + // default evaluation method.
> > + LangOptions::FPEvalMethodKind CurrentFPEvalMethod =
> > + LangOptions::FPEvalMethodKind::FEM_UnsetOnCommandLine;
> > +
> > + // The most recent pragma location where the floating point evaluation
> > + // method was modified. This is used to determine whether the
> > + // 'pragma clang fp eval_method' was used whithin the current scope.
> > + SourceLocation LastFPEvalPragmaLocation;
> > +
> > + LangOptions::FPEvalMethodKind TUFPEvalMethod =
> > + LangOptions::FPEvalMethodKind::FEM_UnsetOnCommandLine;
> > +
> > // Next __COUNTER__ value, starts at 0.
> > unsigned CounterValue = 0;
> >
> > @@ -2048,6 +2063,32 @@ class Preprocessor {
> > unsigned getCounterValue() const { return CounterValue; }
> > void setCounterValue(unsigned V) { CounterValue = V; }
> >
> > + LangOptions::FPEvalMethodKind getCurrentFPEvalMethod() const {
> > + assert(CurrentFPEvalMethod != LangOptions::FEM_UnsetOnCommandLine &&
> > + "FPEvalMethod should be set either from command line or from
> the "
> > + "target info");
> > + return CurrentFPEvalMethod;
> > + }
> > +
> > + LangOptions::FPEvalMethodKind getTUFPEvalMethod() const {
> > + return TUFPEvalMethod;
> > + }
> > +
> > + SourceLocation getLastFPEvalPragmaLocation() const {
> > + return LastFPEvalPragmaLocation;
> > + }
> > +
> > + void setCurrentFPEvalMethod(SourceLocation PragmaLoc,
> > + LangOptions::FPEvalMethodKind Val) {
> > + assert(Val != LangOptions::FEM_UnsetOnCommandLine &&
> > + "FPEvalMethod should never be set to
> FEM_UnsetOnCommandLine");
> > + // This is the location of the '#pragma float_control" where the
> > + // execution state is modifed.
> > + LastFPEvalPragmaLocation = PragmaLoc;
> > + CurrentFPEvalMethod = Val;
> > + TUFPEvalMethod = Val;
> > + }
> > +
> > /// Retrieves the module that we're currently building, if any.
> > Module *getCurrentModule();
> >
> >
> > diff --git a/clang/include/clang/Parse/Parser.h
> b/clang/include/clang/Parse/Parser.h
> > index 981800a7e2356..d2e588992238d 100644
> > --- a/clang/include/clang/Parse/Parser.h
> > +++ b/clang/include/clang/Parse/Parser.h
> > @@ -184,6 +184,7 @@ class Parser : public CodeCompletionHandler {
> > std::unique_ptr<PragmaHandler> PCSectionHandler;
> > std::unique_ptr<PragmaHandler> MSCommentHandler;
> > std::unique_ptr<PragmaHandler> MSDetectMismatchHandler;
> > + std::unique_ptr<PragmaHandler> FPEvalMethodHandler;
> > std::unique_ptr<PragmaHandler> FloatControlHandler;
> > std::unique_ptr<PragmaHandler> MSPointersToMembers;
> > std::unique_ptr<PragmaHandler> MSVtorDisp;
> >
> > diff --git a/clang/include/clang/Sema/Sema.h
> b/clang/include/clang/Sema/Sema.h
> > index c1e846c55dee7..60ee577fca06a 100644
> > --- a/clang/include/clang/Sema/Sema.h
> > +++ b/clang/include/clang/Sema/Sema.h
> > @@ -1541,19 +1541,16 @@ class Sema final {
> > /// statements.
> > class FPFeaturesStateRAII {
> > public:
> > - FPFeaturesStateRAII(Sema &S) : S(S),
> OldFPFeaturesState(S.CurFPFeatures) {
> > - OldOverrides = S.FpPragmaStack.CurrentValue;
> > - }
> > - ~FPFeaturesStateRAII() {
> > - S.CurFPFeatures = OldFPFeaturesState;
> > - S.FpPragmaStack.CurrentValue = OldOverrides;
> > - }
> > + FPFeaturesStateRAII(Sema &S);
> > + ~FPFeaturesStateRAII();
> > FPOptionsOverride getOverrides() { return OldOverrides; }
> >
> > private:
> > Sema& S;
> > FPOptions OldFPFeaturesState;
> > FPOptionsOverride OldOverrides;
> > + LangOptions::FPEvalMethodKind OldEvalMethod;
> > + SourceLocation OldFPPragmaLocation;
> > };
> >
> > void addImplicitTypedef(StringRef Name, QualType T);
> > @@ -10131,6 +10128,9 @@ class Sema final {
> > !CurFPFeatures.getAllowApproxFunc();
> > }
> >
> > + void ActOnPragmaFPEvalMethod(SourceLocation Loc,
> > + LangOptions::FPEvalMethodKind Value);
> > +
> > /// ActOnPragmaFloatControl - Call on well-formed \#pragma
> float_control
> > void ActOnPragmaFloatControl(SourceLocation Loc, PragmaMsStackAction
> Action,
> > PragmaFloatControlKind Value);
> >
> > diff --git a/clang/lib/Basic/Targets/OSTargets.h
> b/clang/lib/Basic/Targets/OSTargets.h
> > index 3c1830d5f8e89..f61652d285a89 100644
> > --- a/clang/lib/Basic/Targets/OSTargets.h
> > +++ b/clang/lib/Basic/Targets/OSTargets.h
> > @@ -749,7 +749,9 @@ class AIXTargetInfo : public OSTargetInfo<Target> {
> > }
> >
> > // AIX sets FLT_EVAL_METHOD to be 1.
> > - unsigned getFloatEvalMethod() const override { return 1; }
> > + LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
> > + return LangOptions::FPEvalMethodKind::FEM_Double;
> > + }
> >
> > bool defaultsToAIXPowerAlignment() const override { return true; }
> > };
> >
> > diff --git a/clang/lib/Basic/Targets/X86.h
> b/clang/lib/Basic/Targets/X86.h
> > index d1b66432e38b4..e0bb3c344c5b6 100644
> > --- a/clang/lib/Basic/Targets/X86.h
> > +++ b/clang/lib/Basic/Targets/X86.h
> > @@ -168,11 +168,15 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo :
> public TargetInfo {
> > return LongDoubleFormat == &llvm::APFloat::IEEEquad() ? "g" : "e";
> > }
> >
> > - unsigned getFloatEvalMethod() const override {
> > + LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
> > // X87 evaluates with 80 bits "long double" precision.
> > - return SSELevel == NoSSE ? 2 : 0;
> > + return SSELevel == NoSSE ?
> LangOptions::FPEvalMethodKind::FEM_Extended
> > + :
> LangOptions::FPEvalMethodKind::FEM_Source;
> > }
> >
> > + // EvalMethod `source` is not supported for targets with `NoSSE`
> feature.
> > + bool supportSourceEvalMethod() const override { return SSELevel >
> NoSSE; }
> > +
> > ArrayRef<const char *> getGCCRegNames() const override;
> >
> > ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
> > @@ -471,13 +475,13 @@ class LLVM_LIBRARY_VISIBILITY NetBSDI386TargetInfo
> > NetBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions
> &Opts)
> > : NetBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {}
> >
> > - unsigned getFloatEvalMethod() const override {
> > + LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
> > VersionTuple OsVersion = getTriple().getOSVersion();
> > // New NetBSD uses the default rounding mode.
> > if (OsVersion >= VersionTuple(6, 99, 26) || OsVersion.getMajor() ==
> 0)
> > - return X86_32TargetInfo::getFloatEvalMethod();
> > + return X86_32TargetInfo::getFPEvalMethod();
> > // NetBSD before 6.99.26 defaults to "double" rounding.
> > - return 1;
> > + return LangOptions::FPEvalMethodKind::FEM_Double;
> > }
> > };
> >
> >
> > diff --git a/clang/lib/Driver/ToolChains/Clang.cpp
> b/clang/lib/Driver/ToolChains/Clang.cpp
> > index 945f626977799..ee32e5849ff84 100644
> > --- a/clang/lib/Driver/ToolChains/Clang.cpp
> > +++ b/clang/lib/Driver/ToolChains/Clang.cpp
> > @@ -2719,6 +2719,8 @@ static void RenderFloatingPointOptions(const
> ToolChain &TC, const Driver &D,
> > StringRef FPModel = "";
> > // -ffp-exception-behavior options: strict, maytrap, ignore
> > StringRef FPExceptionBehavior = "";
> > + // -ffp-eval-method options: double, extended, source
> > + StringRef FPEvalMethod = "";
> > const llvm::DenormalMode DefaultDenormalFPMath =
> > TC.getDefaultDenormalModeForType(Args, JA);
> > const llvm::DenormalMode DefaultDenormalFP32Math =
> > @@ -2914,6 +2916,18 @@ static void RenderFloatingPointOptions(const
> ToolChain &TC, const Driver &D,
> > break;
> > }
> >
> > + // Validate and pass through -ffp-eval-method option.
> > + case options::OPT_ffp_eval_method_EQ: {
> > + StringRef Val = A->getValue();
> > + if (Val.equals("double") || Val.equals("extended") ||
> > + Val.equals("source"))
> > + FPEvalMethod = Val;
> > + else
> > + D.Diag(diag::err_drv_unsupported_option_argument)
> > + << A->getOption().getName() << Val;
> > + break;
> > + }
> > +
> > case options::OPT_ffinite_math_only:
> > HonorINFs = false;
> > HonorNaNs = false;
> > @@ -3069,6 +3083,9 @@ static void RenderFloatingPointOptions(const
> ToolChain &TC, const Driver &D,
> > CmdArgs.push_back(Args.MakeArgString("-ffp-exception-behavior=" +
> > FPExceptionBehavior));
> >
> > + if (!FPEvalMethod.empty())
> > + CmdArgs.push_back(Args.MakeArgString("-ffp-eval-method=" +
> FPEvalMethod));
> > +
> > ParseMRecip(D, Args, CmdArgs);
> >
> > // -ffast-math enables the __FAST_MATH__ preprocessor macro, but
> check for the
> >
> > diff --git a/clang/lib/Frontend/InitPreprocessor.cpp
> b/clang/lib/Frontend/InitPreprocessor.cpp
> > index bf8a0b2abe22e..ff507e2c00aaa 100644
> > --- a/clang/lib/Frontend/InitPreprocessor.cpp
> > +++ b/clang/lib/Frontend/InitPreprocessor.cpp
> > @@ -1136,7 +1136,6 @@ static void InitializePredefinedMacros(const
> TargetInfo &TI,
> > }
> >
> > // Macros to control C99 numerics and <float.h>
> > - Builder.defineMacro("__FLT_EVAL_METHOD__",
> Twine(TI.getFloatEvalMethod()));
> > Builder.defineMacro("__FLT_RADIX__", "2");
> > Builder.defineMacro("__DECIMAL_DIG__", "__LDBL_DECIMAL_DIG__");
> >
> >
> > diff --git a/clang/lib/Lex/PPMacroExpansion.cpp
> b/clang/lib/Lex/PPMacroExpansion.cpp
> > index a29ff215d7ea0..82fc57c8f2e88 100644
> > --- a/clang/lib/Lex/PPMacroExpansion.cpp
> > +++ b/clang/lib/Lex/PPMacroExpansion.cpp
> > @@ -342,6 +342,7 @@ void Preprocessor::RegisterBuiltinMacros() {
> > Ident__TIME__ = RegisterBuiltinMacro(*this, "__TIME__");
> > Ident__COUNTER__ = RegisterBuiltinMacro(*this, "__COUNTER__");
> > Ident_Pragma = RegisterBuiltinMacro(*this, "_Pragma");
> > + Ident__FLT_EVAL_METHOD__ = RegisterBuiltinMacro(*this,
> "__FLT_EVAL_METHOD__");
> >
> > // C++ Standing Document Extensions.
> > if (getLangOpts().CPlusPlus)
> > @@ -1574,6 +1575,17 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok)
> {
> > // Surround the string with " and strip the trailing newline.
> > OS << '"' << StringRef(Result).drop_back() << '"';
> > Tok.setKind(tok::string_literal);
> > + } else if (II == Ident__FLT_EVAL_METHOD__) {
> > + // __FLT_EVAL_METHOD__ is set to the default value.
> > + OS << getTUFPEvalMethod();
> > + // __FLT_EVAL_METHOD__ expands to a simple numeric value.
> > + Tok.setKind(tok::numeric_constant);
> > + if (getLastFPEvalPragmaLocation().isValid()) {
> > + // The program is ill-formed. The value of __FLT_EVAL_METHOD__ is
> altered
> > + // by the pragma.
> > + Diag(Tok, diag::err_illegal_use_of_flt_eval_macro);
> > + Diag(getLastFPEvalPragmaLocation(),
> diag::note_pragma_entered_here);
> > + }
> > } else if (II == Ident__COUNTER__) {
> > // __COUNTER__ expands to a simple numeric value.
> > OS << CounterValue++;
> >
> > diff --git a/clang/lib/Parse/ParsePragma.cpp
> b/clang/lib/Parse/ParsePragma.cpp
> > index 27e8501278626..5c6aa0e47635b 100644
> > --- a/clang/lib/Parse/ParsePragma.cpp
> > +++ b/clang/lib/Parse/ParsePragma.cpp
> > @@ -3028,12 +3028,13 @@ void
> PragmaOptimizeHandler::HandlePragma(Preprocessor &PP,
> > namespace {
> > /// Used as the annotation value for tok::annot_pragma_fp.
> > struct TokFPAnnotValue {
> > - enum FlagKinds { Contract, Reassociate, Exceptions };
> > + enum FlagKinds { Contract, Reassociate, Exceptions, EvalMethod };
> > enum FlagValues { On, Off, Fast };
> >
> > llvm::Optional<LangOptions::FPModeKind> ContractValue;
> > llvm::Optional<LangOptions::FPModeKind> ReassociateValue;
> > llvm::Optional<LangOptions::FPExceptionModeKind> ExceptionsValue;
> > + llvm::Optional<LangOptions::FPEvalMethodKind> EvalMethodValue;
> > };
> > } // end anonymous namespace
> >
> > @@ -3060,6 +3061,7 @@ void PragmaFPHandler::HandlePragma(Preprocessor
> &PP,
> > .Case("contract", TokFPAnnotValue::Contract)
> > .Case("reassociate", TokFPAnnotValue::Reassociate)
> > .Case("exceptions", TokFPAnnotValue::Exceptions)
> > + .Case("eval_method", TokFPAnnotValue::EvalMethod)
> > .Default(None);
> > if (!FlagKind) {
> > PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
> > @@ -3074,8 +3076,11 @@ void PragmaFPHandler::HandlePragma(Preprocessor
> &PP,
> > return;
> > }
> > PP.Lex(Tok);
> > + bool isEvalMethodDouble =
> > + Tok.is(tok::kw_double) && FlagKind ==
> TokFPAnnotValue::EvalMethod;
> >
> > - if (Tok.isNot(tok::identifier)) {
> > + // Don't diagnose if we have an eval_metod pragma with "double"
> kind.
> > + if (Tok.isNot(tok::identifier) && !isEvalMethodDouble) {
> > PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
> > << PP.getSpelling(Tok) << OptionInfo->getName()
> > << static_cast<int>(*FlagKind);
> > @@ -3121,6 +3126,19 @@ void PragmaFPHandler::HandlePragma(Preprocessor
> &PP,
> > << PP.getSpelling(Tok) << OptionInfo->getName() <<
> *FlagKind;
> > return;
> > }
> > + } else if (FlagKind == TokFPAnnotValue::EvalMethod) {
> > + AnnotValue->EvalMethodValue =
> > +
> llvm::StringSwitch<llvm::Optional<LangOptions::FPEvalMethodKind>>(
> > + II->getName())
> > + .Case("source", LangOptions::FPEvalMethodKind::FEM_Source)
> > + .Case("double", LangOptions::FPEvalMethodKind::FEM_Double)
> > + .Case("extended",
> LangOptions::FPEvalMethodKind::FEM_Extended)
> > + .Default(llvm::None);
> > + if (!AnnotValue->EvalMethodValue) {
> > + PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
> > + << PP.getSpelling(Tok) << OptionInfo->getName() <<
> *FlagKind;
> > + return;
> > + }
> > }
> > PP.Lex(Tok);
> >
> > @@ -3223,6 +3241,9 @@ void Parser::HandlePragmaFP() {
> > if (AnnotValue->ExceptionsValue)
> > Actions.ActOnPragmaFPExceptions(Tok.getLocation(),
> > *AnnotValue->ExceptionsValue);
> > + if (AnnotValue->EvalMethodValue)
> > + Actions.ActOnPragmaFPEvalMethod(Tok.getLocation(),
> > + *AnnotValue->EvalMethodValue);
> > ConsumeAnnotationToken();
> > }
> >
> >
> > diff --git a/clang/lib/Parse/ParseStmt.cpp
> b/clang/lib/Parse/ParseStmt.cpp
> > index ee07775b6346f..cadedf6d98dbd 100644
> > --- a/clang/lib/Parse/ParseStmt.cpp
> > +++ b/clang/lib/Parse/ParseStmt.cpp
> > @@ -1153,6 +1153,16 @@ StmtResult
> Parser::ParseCompoundStatementBody(bool isStmtExpr) {
> > if (R.isUsable())
> > Stmts.push_back(R.get());
> > }
> > + // Warn the user that using option `-ffp-eval-method=source` on a
> > + // 32-bit target and feature `sse` disabled, or using
> > + // `pragma clang fp eval_method=source` and feature `sse` disabled,
> is not
> > + // supported.
> > + if (!PP.getTargetInfo().supportSourceEvalMethod() &&
> > + (PP.getLastFPEvalPragmaLocation().isValid() ||
> > + PP.getCurrentFPEvalMethod() ==
> > + LangOptions::FPEvalMethodKind::FEM_Source))
> > + Diag(Tok.getLocation(),
> > + diag::warn_no_support_for_eval_method_source_on_m32);
> >
> > SourceLocation CloseLoc = Tok.getLocation();
> >
> >
> > diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
> > index 7b57c8da4e9cc..db3eda622639f 100644
> > --- a/clang/lib/Sema/Sema.cpp
> > +++ b/clang/lib/Sema/Sema.cpp
> > @@ -242,6 +242,15 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt,
> ASTConsumer &consumer,
> > SemaPPCallbackHandler = Callbacks.get();
> > PP.addPPCallbacks(std::move(Callbacks));
> > SemaPPCallbackHandler->set(*this);
> > + if (getLangOpts().getFPEvalMethod() ==
> LangOptions::FEM_UnsetOnCommandLine)
> > + // Use setting from TargetInfo.
> > + PP.setCurrentFPEvalMethod(SourceLocation(),
> > + ctxt.getTargetInfo().getFPEvalMethod());
> > + else
> > + // Set initial value of __FLT_EVAL_METHOD__ from the command line.
> > + PP.setCurrentFPEvalMethod(SourceLocation(),
> > + getLangOpts().getFPEvalMethod());
> > + CurFPFeatures.setFPEvalMethod(PP.getCurrentFPEvalMethod());
> > }
> >
> > // Anchor Sema's type info to this TU.
> > @@ -2630,3 +2639,15 @@ const llvm::MapVector<FieldDecl *,
> Sema::DeleteLocs> &
> > Sema::getMismatchingDeleteExpressions() const {
> > return DeleteExprs;
> > }
> > +
> > +Sema::FPFeaturesStateRAII::FPFeaturesStateRAII(Sema &S)
> > + : S(S), OldFPFeaturesState(S.CurFPFeatures),
> > + OldOverrides(S.FpPragmaStack.CurrentValue),
> > + OldEvalMethod(S.PP.getCurrentFPEvalMethod()),
> > + OldFPPragmaLocation(S.PP.getLastFPEvalPragmaLocation()) {}
> > +
> > +Sema::FPFeaturesStateRAII::~FPFeaturesStateRAII() {
> > + S.CurFPFeatures = OldFPFeaturesState;
> > + S.FpPragmaStack.CurrentValue = OldOverrides;
> > + S.PP.setCurrentFPEvalMethod(OldFPPragmaLocation, OldEvalMethod);
> > +}
> >
> > diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
> > index 38e6e60af90db..d623060fd10cf 100644
> > --- a/clang/lib/Sema/SemaAttr.cpp
> > +++ b/clang/lib/Sema/SemaAttr.cpp
> > @@ -470,6 +470,27 @@ void Sema::ActOnPragmaDetectMismatch(SourceLocation
> Loc, StringRef Name,
> > Consumer.HandleTopLevelDecl(DeclGroupRef(PDMD));
> > }
> >
> > +void Sema::ActOnPragmaFPEvalMethod(SourceLocation Loc,
> > + LangOptions::FPEvalMethodKind Value)
> {
> > + FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
> > + switch (Value) {
> > + default:
> > + llvm_unreachable("invalid pragma eval_method kind");
> > + case LangOptions::FEM_Source:
> > + NewFPFeatures.setFPEvalMethodOverride(LangOptions::FEM_Source);
> > + break;
> > + case LangOptions::FEM_Double:
> > + NewFPFeatures.setFPEvalMethodOverride(LangOptions::FEM_Double);
> > + break;
> > + case LangOptions::FEM_Extended:
> > + NewFPFeatures.setFPEvalMethodOverride(LangOptions::FEM_Extended);
> > + break;
> > + }
> > + FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
> > + CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
> > + PP.setCurrentFPEvalMethod(Loc, Value);
> > +}
> > +
> > void Sema::ActOnPragmaFloatControl(SourceLocation Loc,
> > PragmaMsStackAction Action,
> > PragmaFloatControlKind Value) {
> >
> > diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
> > index 22b3f371afe79..88fc89bec629a 100644
> > --- a/clang/lib/Sema/SemaExpr.cpp
> > +++ b/clang/lib/Sema/SemaExpr.cpp
> > @@ -773,6 +773,40 @@ ExprResult Sema::UsualUnaryConversions(Expr *E) {
> > QualType Ty = E->getType();
> > assert(!Ty.isNull() && "UsualUnaryConversions - missing type");
> >
> > + LangOptions::FPEvalMethodKind EvalMethod =
> CurFPFeatures.getFPEvalMethod();
> > + if (EvalMethod != LangOptions::FEM_Source && Ty->isFloatingType() &&
> > + (getLangOpts().getFPEvalMethod() !=
> > + LangOptions::FPEvalMethodKind::FEM_UnsetOnCommandLine ||
> > + PP.getLastFPEvalPragmaLocation().isValid())) {
> > + switch (EvalMethod) {
> > + default:
> > + llvm_unreachable("Unrecognized float evaluation method");
> > + break;
> > + case LangOptions::FEM_UnsetOnCommandLine:
> > + llvm_unreachable("Float evaluation method should be set by now");
> > + break;
> > + case LangOptions::FEM_Double:
> > + if (Context.getFloatingTypeOrder(Context.DoubleTy, Ty) > 0)
> > + // Widen the expression to double.
> > + return Ty->isComplexType()
> > + ? ImpCastExprToType(E,
> > +
> Context.getComplexType(Context.DoubleTy),
> > + CK_FloatingComplexCast)
> > + : ImpCastExprToType(E, Context.DoubleTy,
> CK_FloatingCast);
> > + break;
> > + case LangOptions::FEM_Extended:
> > + if (Context.getFloatingTypeOrder(Context.LongDoubleTy, Ty) > 0)
> > + // Widen the expression to long double.
> > + return Ty->isComplexType()
> > + ? ImpCastExprToType(
> > + E,
> Context.getComplexType(Context.LongDoubleTy),
> > + CK_FloatingComplexCast)
> > + : ImpCastExprToType(E, Context.LongDoubleTy,
> > + CK_FloatingCast);
> > + break;
> > + }
> > + }
> > +
> > // Half FP have to be promoted to float unless it is natively
> supported
> > if (Ty->isHalfType() && !getLangOpts().NativeHalfType)
> > return ImpCastExprToType(Res.get(), Context.FloatTy,
> CK_FloatingCast);
> >
> > diff --git a/clang/test/CodeGen/X86/32bit-behavior-no-eval.c
> b/clang/test/CodeGen/X86/32bit-behavior-no-eval.c
> > new file mode 100644
> > index 0000000000000..d040e827ce31c
> > --- /dev/null
> > +++ b/clang/test/CodeGen/X86/32bit-behavior-no-eval.c
> > @@ -0,0 +1,30 @@
> > +// SSE
> > +// RUN: %clang_cc1 \
> > +// RUN: -triple i386-pc-windows -target-cpu pentium4 -target-feature
> +sse \
> > +// RUN: -emit-llvm -o - %s | FileCheck -check-prefix=CHECK %s
> > +
> > +// NO SSE
> > +// RUN: %clang_cc1 \
> > +// RUN: -triple i386-pc-windows -target-cpu pentium4 -target-feature
> -sse \
> > +// RUN: -emit-llvm -o - %s | FileCheck -check-prefix=CHECK %s
> > +
> > +// NO SSE Fast Math
> > +// RUN: %clang_cc1 \
> > +// RUN: -triple i386-pc-windows -target-cpu pentium4 -target-feature
> -sse \
> > +// RUN: -ffast-math -emit-llvm -o - %s | FileCheck
> -check-prefix=CHECK-FM %s
> > +
> > +float addit(float a, float b, float c) {
> > + // CHECK: load float, float*
> > + // CHECK: load float, float*
> > + // CHECK: fadd float
> > + // CHECK: load float, float*
> > + // CHECK: fadd float
> > +
> > + // CHECK-FM: load float, float*
> > + // CHECK-FM: load float, float*
> > + // CHECK-FM: fadd reassoc nnan ninf nsz arcp afn float
> > + // CHECK-FM: load float, float*
> > + // CHECK-FM: fadd reassoc nnan ninf nsz arcp afn float
> > +
> > + return a + b + c;
> > +}
> >
> > diff --git a/clang/test/CodeGen/X86/32bit-behavior.c
> b/clang/test/CodeGen/X86/32bit-behavior.c
> > new file mode 100644
> > index 0000000000000..a7e0f008c9f35
> > --- /dev/null
> > +++ b/clang/test/CodeGen/X86/32bit-behavior.c
> > @@ -0,0 +1,109 @@
> > +// SSE
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple i386-pc-windows -target-cpu pentium4 -target-feature
> +sse \
> > +// RUN: -emit-llvm -o - %s -ffp-eval-method=source \
> > +// RUN: | FileCheck -check-prefix=CHECK-SRC %s
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple i386-pc-windows -target-cpu pentium4 -target-feature
> +sse \
> > +// RUN: -emit-llvm -o - %s -ffp-eval-method=double \
> > +// RUN: | FileCheck -check-prefix=CHECK-DBL %s
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple i386-pc-windows -target-cpu pentium4 -target-feature
> +sse \
> > +// RUN: -emit-llvm -o - %s -ffp-eval-method=extended \
> > +// RUN: | FileCheck -check-prefix=CHECK-DBL %s
> > +
> > +// SSE Fast Math
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple i386-pc-windows -target-cpu pentium4 -target-feature
> +sse \
> > +// RUN: -emit-llvm -o - %s -ffp-eval-method=source \
> > +// RUN: -ffast-math | FileCheck -check-prefix=CHECK-FM-SRC %s
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple i386-pc-windows -target-cpu pentium4 -target-feature
> +sse \
> > +// RUN: -emit-llvm -o - %s -ffp-eval-method=double \
> > +// RUN: -ffast-math | FileCheck -check-prefix=CHECK-FM %s
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple i386-pc-windows -target-cpu pentium4 -target-feature
> +sse \
> > +// RUN: -emit-llvm -o - %s -ffp-eval-method=extended \
> > +// RUN: -ffast-math | FileCheck -check-prefix=CHECK-FM %s
> > +
> > +// NO SSE
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple i386-pc-windows -target-cpu pentium4 -target-feature
> -sse \
> > +// RUN: -emit-llvm -o - %s -ffp-eval-method=source \
> > +// RUN: | FileCheck -check-prefix=CHECK-SRC %s
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple i386-pc-windows -target-cpu pentium4 -target-feature
> -sse \
> > +// RUN: -emit-llvm -o - %s -ffp-eval-method=double \
> > +// RUN: | FileCheck -check-prefix=CHECK-DBL %s
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple i386-pc-windows -target-cpu pentium4 -target-feature
> -sse \
> > +// RUN: -emit-llvm -o - %s -ffp-eval-method=extended \
> > +// RUN: | FileCheck -check-prefix=CHECK-DBL %s
> > +
> > +// NO SSE Fast Math
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple i386-pc-windows -target-cpu pentium4 -target-feature
> -sse \
> > +// RUN: -emit-llvm -o - %s -ffp-eval-method=source \
> > +// RUN: -ffast-math | FileCheck -check-prefix=CHECK %s
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple i386-pc-windows -target-cpu pentium4 -target-feature
> -sse \
> > +// RUN: -emit-llvm -o - %s -ffp-eval-method=double \
> > +// RUN: -ffast-math | FileCheck -check-prefix=CHECK-DBL-FM %s
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple i386-pc-windows -target-cpu pentium4 -target-feature
> -sse \
> > +// RUN: -emit-llvm -o - %s -ffp-eval-method=extended \
> > +// RUN: -ffast-math | FileCheck -check-prefix=CHECK-DBL-FM %s
> > +
> > +float addit(float a, float b, float c) {
> > + // CHECK-SRC: load float, float*
> > + // CHECK-SRC: load float, float*
> > + // CHECK-SRC: fadd float
> > + // CHECK-SRC: load float, float*
> > + // CHECK-SRC: fadd float
> > +
> > + // CHECK-FM-SRC: load float, float*
> > + // CHECK-FM-SRC: load float, float*
> > + // CHECK-FM-SRC: fadd reassoc nnan ninf nsz arcp afn float
> > + // CHECK-FM-SRC: load float, float*
> > + // CHECK-FM-SRC: fadd reassoc nnan ninf nsz arcp afn float
> > +
> > + // CHECK-FM: load float, float*
> > + // CHECK-FM: fpext float {{.*}} to double
> > + // CHECK-FM: load float, float*
> > + // CHECK-FM: fpext float {{.*}} to double
> > + // CHECK-FM: fadd reassoc nnan ninf nsz arcp afn double
> > + // CHECK-FM: load float, float*
> > + // CHECK-FM: fadd reassoc nnan ninf nsz arcp afn double
> > + // CHECK-FM: fptrunc double {{.*}} to float
> > +
> > + // CHECK-DBL: load float, float*
> > + // CHECK-DBL: fpext float {{.*}} to double
> > + // CHECK-DBL: load float, float*
> > + // CHECK-DBL: fpext float {{.*}} to double
> > + // CHECK-DBL: fadd double
> > + // CHECK-DBL: load float, float*
> > + // CHECK-DBL: fpext float {{.*}} to double
> > + // CHECK-DBL: fadd double
> > + // CHECK-DBL: fptrunc double {{.*}} to float
> > +
> > + // CHECK-DBL-FM: load float, float*
> > + // CHECK-DBL-FM: fpext float {{.*}} to double
> > + // CHECK-DBL-FM: load float, float*
> > + // CHECK-DBL-FM: fpext float {{.*}} to double
> > + // CHECK-DBL-FM: fadd reassoc nnan ninf nsz arcp afn double
> > + // CHECK-DBL-FM: load float, float*
> > + // CHECK-DBL-FM: fpext float {{.*}} to double
> > + // CHECK-DBL-FM: fadd reassoc nnan ninf nsz arcp afn double
> > + // CHECK-DBL-FM: fptrunc double {{.*}} to float
> > +
> > + // CHECK: ret float
> > + return a + b + c;
> > +}
> >
> > diff --git a/clang/test/CodeGen/X86/fp-eval-method.c
> b/clang/test/CodeGen/X86/fp-eval-method.c
> > new file mode 100644
> > index 0000000000000..5bfc3701050f5
> > --- /dev/null
> > +++ b/clang/test/CodeGen/X86/fp-eval-method.c
> > @@ -0,0 +1,20 @@
> > +// RUN: %clang_cc1 -triple i386-unknown-netbsd6 -emit-llvm -o - %s \
> > +// RUN: | FileCheck %s -check-prefixes=CHECK
> > +
> > +// RUN: %clang_cc1 -triple i386-unknown-netbsd7 -emit-llvm -o - %s \
> > +// RUN: | FileCheck %s -check-prefixes=CHECK-EXT
> > +
> > +// RUN: %clang_cc1 -triple i386--linux -emit-llvm -o - %s \
> > +// RUN: | FileCheck %s -check-prefixes=CHECK-EXT
> > +
> > +float f(float x, float y) {
> > + // CHECK: define{{.*}} float @f
> > + // CHECK: fadd float
> > + return 2.0f + x + y;
> > +}
> > +
> > +int getEvalMethod() {
> > + // CHECK: ret i32 1
> > + // CHECK-EXT: ret i32 2
> > + return __FLT_EVAL_METHOD__;
> > +}
> >
> > diff --git a/clang/test/CodeGen/flt_eval_macro.cpp
> b/clang/test/CodeGen/flt_eval_macro.cpp
> > new file mode 100644
> > index 0000000000000..aa7455f0efe0b
> > --- /dev/null
> > +++ b/clang/test/CodeGen/flt_eval_macro.cpp
> > @@ -0,0 +1,79 @@
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point -DEXCEPT=1 \
> > +// RUN: -fcxx-exceptions -triple x86_64-linux-gnu -emit-llvm -o - %s \
> > +// RUN: | FileCheck -check-prefix=CHECK-SRC %s
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple x86_64-linux-gnu -emit-llvm -o - %s
> -ffp-eval-method=source \
> > +// RUN: | FileCheck -check-prefix=CHECK-SRC %s
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple x86_64-linux-gnu -emit-llvm -o - %s
> -ffp-eval-method=double \
> > +// RUN: | FileCheck -check-prefixes=CHECK-DBL %s
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple x86_64-linux-gnu -emit-llvm -o - %s
> -ffp-eval-method=extended \
> > +// RUN: | FileCheck -check-prefixes=CHECK-EXT-FLT %s
> > +
> > +// RUN: %clang_cc1 -triple powerpc-unknown-aix -emit-llvm -o - %s \
> > +// RUN: | FileCheck %s -check-prefix=CHECK-DBL-PPC
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point -triple
> i386-linux-gnu \
> > +// RUN: -emit-llvm -o - %s -ffp-eval-method=extended -mlong-double-80 \
> > +// RUN: | FileCheck %s -check-prefix=CHECK-EXT-FLT
> > +
> > +int getFEM() {
> > + // LABEL: define {{.*}}getFEM{{.*}}
> > + return __FLT_EVAL_METHOD__;
> > + // CHECK-SRC: ret {{.*}} 0
> > + // CHECK-DBL: ret {{.*}} 1
> > + // CHECK-DBL-PPC: ret {{.*}} 1
> > + // CHECK-EXT-FLT: ret {{.*}} 2
> > +}
> > +
> > +float func() {
> > + // LABEL: define {{.*}}@_Z4func{{.*}}
> > + float X = 100.0f;
> > + float Y = -45.3f;
> > + float Z = 393.78f;
> > + float temp;
> > +#if __FLT_EVAL_METHOD__ == 0
> > + temp = X + Y + Z;
> > +#elif __FLT_EVAL_METHOD__ == 1
> > + temp = X * Y * Z;
> > +#elif __FLT_EVAL_METHOD__ == 2
> > + temp = X * Y - Z;
> > +#endif
> > + // CHECK-SRC: load float, float*
> > + // CHECK-SRC: load float, float*
> > + // CHECK-SRC: fadd float
> > + // CHECK-SRC: load float, float*
> > + // CHECK-SRC: fadd float
> > +
> > + // CHECK-DBL: load float, float*
> > + // CHECK-DBL: fpext float
> > + // CHECK-DBL: load float, float*
> > + // CHECK-DBL: fpext float
> > + // CHECK-DBL: fmul double
> > + // CHECK-DBL: load float, float*
> > + // CHECK-DBL: fpext float
> > + // CHECK-DBL: fmul double
> > + // CHECK-DBL: fptrunc double
> > +
> > + // CHECK-EXT-FLT: load float, float*
> > + // CHECK-EXT-FLT: fpext float
> > + // CHECK-EXT-FLT: load float, float*
> > + // CHECK-EXT-FLT: fpext float
> > + // CHECK-EXT-FLT: fmul x86_fp80
> > + // CHECK-EXT-FLT: load float, float*
> > + // CHECK-EXT-FLT: fpext float
> > + // CHECK-EXT-FLT: fsub x86_fp80
> > + // CHECK-EXT-FLT: fptrunc x86_fp80
> > +
> > + // CHECK-DBL-PPC: load float, float*
> > + // CHECK-DBL-PPC: load float, float*
> > + // CHECK-DBL-PPC: fmul float
> > + // CHECK-DBL-PPC: load float, float*
> > + // CHECK-DBL-PPC: fmul float
> > +
> > + return temp;
> > +}
> >
> > diff --git a/clang/test/CodeGen/fp-floatcontrol-pragma.cpp
> b/clang/test/CodeGen/fp-floatcontrol-pragma.cpp
> > index ef29d24de1dbc..966eaf6053970 100644
> > --- a/clang/test/CodeGen/fp-floatcontrol-pragma.cpp
> > +++ b/clang/test/CodeGen/fp-floatcontrol-pragma.cpp
> > @@ -1,7 +1,53 @@
> > -// RUN: %clang_cc1 -fexperimental-strict-floating-point -DEXCEPT=1
> -fcxx-exceptions -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck
> -check-prefix=CHECK-NS %s
> > -// RUN: %clang_cc1 -fexperimental-strict-floating-point -triple
> x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
> > -// RUN: %clang_cc1 -fexperimental-strict-floating-point -DFENV_ON=1
> -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck
> -check-prefix=CHECK-FENV %s
> > -// RUN: %clang_cc1 -fexperimental-strict-floating-point -triple
> %itanium_abi_triple -O3 -emit-llvm -o - %s | FileCheck
> -check-prefix=CHECK-O3 %s
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point -DEXCEPT=1 \
> > +// RUN: -fcxx-exceptions -triple x86_64-linux-gnu -emit-llvm -o - %s \
> > +// RUN: | FileCheck -check-prefix=CHECK-NS %s
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s \
> > +// RUN: -check-prefixes=CHECK-DEFAULT,CHECK-CONST-ARGS
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point -DFENV_ON=1 \
> > +// RUN: -triple x86_64-linux-gnu -emit-llvm -o - %s \
> > +// RUN: | FileCheck -check-prefix=CHECK-FENV %s
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point -DNF128 \
> > +// RUN: -triple %itanium_abi_triple -O3 -emit-llvm -o - %s \
> > +// RUN: | FileCheck -check-prefix=CHECK-O3 %s
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple x86_64-linux-gnu -emit-llvm -o - %s
> -ffp-eval-method=source \
> > +// RUN: | FileCheck %s -check-prefixes=CHECK-SOURCE,CHECK-CONST-ARGS
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple x86_64-linux-gnu -emit-llvm -o - %s
> -ffp-eval-method=double \
> > +// RUN: | FileCheck %s -check-prefixes=CHECK-DOUBLE,CHECK-CONST-ARGS
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple x86_64-linux-gnu -emit-llvm -o - %s
> -ffp-eval-method=extended \
> > +// RUN: -mlong-double-80 | FileCheck %s \
> > +// RUN: -check-prefixes=CHECK-EXTENDED,CHECK-CONST-ARGS
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple i386-linux-gnu -emit-llvm -o - %s
> -ffp-eval-method=source \
> > +// RUN: | FileCheck %s -check-prefix=CHECK-SOURCE
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point -triple
> i386-linux-gnu \
> > +// RUN: -emit-llvm -o - %s -ffp-eval-method=double | FileCheck %s \
> > +// RUN: -check-prefix=CHECK-DOUBLE
> > +
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point -triple
> i386-linux-gnu \
> > +// RUN: -emit-llvm -o - %s -ffp-eval-method=extended -mlong-double-80 \
> > +// RUN: | FileCheck %s -check-prefix=CHECK-EXTENDED
> > +
> > +// RUN: %clang_cc1 -triple powerpc-unknown-aix -DNF128 -emit-llvm -o -
> %s \
> > +// RUN: | FileCheck %s -check-prefix=CHECK-AIX
> > +
> > +bool f() {
> > + // CHECK: define {{.*}}f{{.*}}
> > + return __FLT_EVAL_METHOD__ < 0 &&
> > + __FLT_EVAL_METHOD__ == -1;
> > + // CHECK: ret {{.*}} true
> > +}
> >
> > // Verify float_control(precise, off) enables fast math flags on fp
> operations.
> > float fp_precise_1(float a, float b, float c) {
> > @@ -229,3 +275,115 @@ float try_lam(float x, unsigned n) {
> > result = x + t;
> > return result;
> > }
> > +
> > +float mySub(float x, float y) {
> > + // CHECK: define {{.*}}float {{.*}}mySub{{.*}}
> > + // CHECK-NS: fsub float
> > + // CHECK-SOURCE: fsub float
> > + // CHECK-DOUBLE: fpext float
> > + // CHECK-DOUBLE: fpext float
> > + // CHECK-DOUBLE: fsub double
> > + // CHECK-DOUBLE: fptrunc double {{.*}} to float
> > + // CHECK-EXTENDED: fpext float
> > + // CHECK-EXTENDED: fpext float
> > + // CHECK-EXTENDED: fsub double
> > + // CHECK-EXTENDED: fptrunc double {{.*}} to float
> > + return x - y;
> > +}
> > +
> > +float mySubSource(float x, float y) {
> > +// CHECK: define {{.*}}float {{.*}}mySubSource{{.*}}
> > +#pragma clang fp eval_method(source)
> > + return x - y;
> > + // CHECK: fsub float
> > +}
> > +
> > +float mySubExtended(float x, float y) {
> > +// CHECK: define {{.*}}float {{.*}}mySubExtended{{.*}}
> > +#pragma clang fp eval_method(extended)
> > + return x - y;
> > + // CHECK: fpext float
> > + // CHECK: fpext float
> > + // CHECK: fsub x86_fp80
> > + // CHECK: fptrunc x86_fp80 {{.*}} to float
> > + // CHECK-AIX: fsub double
> > + // CHECK-AIX: fptrunc double
> > +}
> > +
> > +float mySubDouble(float x, float y) {
> > +// CHECK: define {{.*}}float {{.*}}mySubDouble{{.*}}
> > +#pragma clang fp eval_method(double)
> > + return x - y;
> > + // CHECK: fpext float
> > + // CHECK: fpext float
> > + // CHECK: fsub double
> > + // CHECK: fptrunc double {{.*}} to float
> > +}
> > +
> > +#ifndef NF128
> > +__float128 mySub128(__float128 x, __float128 y) {
> > + // CHECK: define {{.*}}mySub128{{.*}}
> > + // Expect no fpext since fp128 is already widest
> > + // CHECK: load fp128
> > + // CHECK-NEXT: load fp128
> > + // CHECK-NEXT: fsub fp128
> > + // CHECK-NEXT: ret fp128
> > + return x - y;
> > +}
> > +#endif
> > +
> > +void mySubfp16(__fp16 *res, __fp16 *x, __fp16 *y) {
> > + // CHECK: define {{.*}}mySubfp16{{.*}}
> > + *res = *x - *y;
> > + // CHECK: load half
> > + // CHECK-NEXT: load half
> > + // CHECK-NEXT: fpext half{{.*}}
> > + // CHECK-NEXT: load half
> > + // CHECK-NEXT: load half
> > + // CHECK-NS: fpext half{{.*}} to float
> > + // CHECK-DEFAULT: fpext half{{.*}} to float
> > + // CHECK-DOUBLE: fpext half{{.*}} to float
> > + // CHECK-EXTENDED: fpext half{{.*}} to float
> > + // CHECK-NEXT: fsub
> > + // CHECK-NEXT: fptrunc {{.*}}to half
> > + // CHECK-NS: fptrunc float {{.*}} to half
> > + // CHECK-DOUBLE: fptrunc float {{.*}} to half
> > + // CHECK-EXTENDED: fptrunc float {{.*}} to half
> > +}
> > +
> > +float Div(float x, float y, float z) {
> > + // CHECK: define{{.*}}float {{.*}}Div{{.*}}
> > + // CHECK-CONST-ARGS: fdiv float
> > + return x / (y / z);
> > +}
> > +
> > +float DivExtended(float x, float y, float z) {
> > +// CHECK: define{{.*}}float {{.*}}DivExtended{{.*}}
> > +#pragma clang fp eval_method(extended)
> > + // CHECK-CONST-ARGS: fdiv x86_fp80
> > + // CHECK-CONST-ARGS: fptrunc x86_fp80
> > + return x / (y / z);
> > +}
> > +
> > +float DivDouble(float x, float y, float z) {
> > +// CHECK: define{{.*}}float {{.*}}DivDouble{{.*}}
> > +#pragma clang fp eval_method(double)
> > + // CHECK-CONST-ARGS: fdiv double
> > + // CHECK-CONST-ARGS: fptrunc double
> > + return x / (y / z);
> > +}
> > +
> > +float DivSource(float x, float y, float z) {
> > +// CHECK: define{{.*}}float {{.*}}DivSource{{.*}}
> > +#pragma clang fp eval_method(source)
> > + // CHECK-CONST-ARGS: fdiv float
> > + return x / (y / z);
> > +}
> > +
> > +int main() {
> > + float f = Div(4.2f, 1.0f, 3.0f);
> > + float fextended = DivExtended(4.2f, 1.0f, 3.0f);
> > + float fdouble = DivDouble(4.2f, 1.0f, 3.0f);
> > + float fsource = DivSource(4.2f, 1.0f, 3.0f);
> > + // CHECK: store float
> > +}
> >
> > diff --git a/clang/test/Preprocessor/flt_eval_macro.cpp
> b/clang/test/Preprocessor/flt_eval_macro.cpp
> > new file mode 100644
> > index 0000000000000..47f2592e261bd
> > --- /dev/null
> > +++ b/clang/test/Preprocessor/flt_eval_macro.cpp
> > @@ -0,0 +1,59 @@
> > +// RUN: %clang_cc1 -E -dM %s -o - | FileCheck %s -strict-whitespace
> > +
> > +#ifdef __FLT_EVAL_METHOD__
> > +#if __FLT_EVAL_METHOD__ == 3
> > +#define __GLIBC_FLT_EVAL_METHOD 2
> > +#else
> > +#define __GLIBC_FLT_EVAL_METHOD __FLT_EVAL_METHOD__
> > +#endif
> > +#elif defined __x86_64__
> > +#define __GLIBC_FLT_EVAL_METHOD 0
> > +#else
> > +#define __GLIBC_FLT_EVAL_METHOD 2
> > +#endif
> > +
> > +#if __GLIBC_FLT_EVAL_METHOD == 0 || __GLIBC_FLT_EVAL_METHOD == 16
> > +#define Name "One"
> > +#elif __GLIBC_FLT_EVAL_METHOD == 1
> > +#define Name "Two"
> > +#elif __GLIBC_FLT_EVAL_METHOD == 2
> > +#define Name "Unset on command line"
> > +#elif __GLIBC_FLT_EVAL_METHOD == 32
> > +#define Name "Four"
> > +#elif __GLIBC_FLT_EVAL_METHOD == 33
> > +#define Name "Five"
> > +#elif __GLIBC_FLT_EVAL_METHOD == 64
> > +#define Name "Six"
> > +#elif __GLIBC_FLT_EVAL_METHOD == 65
> > +#define Name "Seven"
> > +#elif __GLIBC_FLT_EVAL_METHOD == 128
> > +#define Name "Eight"
> > +#elif __GLIBC_FLT_EVAL_METHOD == 129
> > +#define Name "Nine"
> > +#else
> > +#error "Unknown __GLIBC_FLT_EVAL_METHOD"
> > +#endif
> > +
> > +int foo() {
> > + // CHECK: #define Name "Unset on command line"
> > + return Name;
> > +}
> > +
> > +#if __FLT_EVAL_METHOD__ == 3
> > +#define Val "val0"
> > +#endif
> > +
> > +#pragma fp eval_method(double)
> > +
> > +#if __FLT_EVAL_METHOD__ == 0
> > +#define Val "val1"
> > +#elif __FLT_EVAL_METHOD__ == 1
> > +#define Val "val2"
> > +#elif __FLT_EVAL_METHOD__ == 2
> > +#define Val "val3"
> > +#endif
> > +
> > +int goo() {
> > + // CHECK: #define Val "val0"
> > + return Name;
> > +}
> >
> > diff --git a/clang/test/Preprocessor/init-aarch64.c
> b/clang/test/Preprocessor/init-aarch64.c
> > index f6809d8d9b48f..66cab8b1f8d04 100644
> > --- a/clang/test/Preprocessor/init-aarch64.c
> > +++ b/clang/test/Preprocessor/init-aarch64.c
> > @@ -93,7 +93,6 @@
> > // AARCH64-NEXT: #define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // AARCH64-NEXT: #define __FLT_DIG__ 6
> > // AARCH64-NEXT: #define __FLT_EPSILON__ 1.19209290e-7F
> > -// AARCH64-NEXT: #define __FLT_EVAL_METHOD__ 0
> > // AARCH64-NEXT: #define __FLT_HAS_DENORM__ 1
> > // AARCH64-NEXT: #define __FLT_HAS_INFINITY__ 1
> > // AARCH64-NEXT: #define __FLT_HAS_QUIET_NAN__ 1
> > @@ -388,7 +387,6 @@
> > // AARCH64-DARWIN: #define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // AARCH64-DARWIN: #define __FLT_DIG__ 6
> > // AARCH64-DARWIN: #define __FLT_EPSILON__ 1.19209290e-7F
> > -// AARCH64-DARWIN: #define __FLT_EVAL_METHOD__ 0
> > // AARCH64-DARWIN: #define __FLT_HAS_DENORM__ 1
> > // AARCH64-DARWIN: #define __FLT_HAS_INFINITY__ 1
> > // AARCH64-DARWIN: #define __FLT_HAS_QUIET_NAN__ 1
> > @@ -604,7 +602,6 @@
> > // AARCH64-MSVC: #define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // AARCH64-MSVC: #define __FLT_DIG__ 6
> > // AARCH64-MSVC: #define __FLT_EPSILON__ 1.19209290e-7F
> > -// AARCH64-MSVC: #define __FLT_EVAL_METHOD__ 0
> > // AARCH64-MSVC: #define __FLT_HAS_DENORM__ 1
> > // AARCH64-MSVC: #define __FLT_HAS_INFINITY__ 1
> > // AARCH64-MSVC: #define __FLT_HAS_QUIET_NAN__ 1
> >
> > diff --git a/clang/test/Preprocessor/init-arm.c
> b/clang/test/Preprocessor/init-arm.c
> > index 32eb2c513f8b0..2d1503c18560e 100644
> > --- a/clang/test/Preprocessor/init-arm.c
> > +++ b/clang/test/Preprocessor/init-arm.c
> > @@ -35,7 +35,6 @@
> > // ARM:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // ARM:#define __FLT_DIG__ 6
> > // ARM:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// ARM:#define __FLT_EVAL_METHOD__ 0
> > // ARM:#define __FLT_HAS_DENORM__ 1
> > // ARM:#define __FLT_HAS_INFINITY__ 1
> > // ARM:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -235,7 +234,6 @@
> > // ARM-BE:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // ARM-BE:#define __FLT_DIG__ 6
> > // ARM-BE:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// ARM-BE:#define __FLT_EVAL_METHOD__ 0
> > // ARM-BE:#define __FLT_HAS_DENORM__ 1
> > // ARM-BE:#define __FLT_HAS_INFINITY__ 1
> > // ARM-BE:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -428,7 +426,6 @@
> > // ARMEABISOFTFP:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // ARMEABISOFTFP:#define __FLT_DIG__ 6
> > // ARMEABISOFTFP:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// ARMEABISOFTFP:#define __FLT_EVAL_METHOD__ 0
> > // ARMEABISOFTFP:#define __FLT_HAS_DENORM__ 1
> > // ARMEABISOFTFP:#define __FLT_HAS_INFINITY__ 1
> > // ARMEABISOFTFP:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -623,7 +620,6 @@
> > // ARMEABIHARDFP:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // ARMEABIHARDFP:#define __FLT_DIG__ 6
> > // ARMEABIHARDFP:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// ARMEABIHARDFP:#define __FLT_EVAL_METHOD__ 0
> > // ARMEABIHARDFP:#define __FLT_HAS_DENORM__ 1
> > // ARMEABIHARDFP:#define __FLT_HAS_INFINITY__ 1
> > // ARMEABIHARDFP:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -821,7 +817,6 @@
> > // ARM-NETBSD:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // ARM-NETBSD:#define __FLT_DIG__ 6
> > // ARM-NETBSD:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// ARM-NETBSD:#define __FLT_EVAL_METHOD__ 0
> > // ARM-NETBSD:#define __FLT_HAS_DENORM__ 1
> > // ARM-NETBSD:#define __FLT_HAS_INFINITY__ 1
> > // ARM-NETBSD:#define __FLT_HAS_QUIET_NAN__ 1
> >
> > diff --git a/clang/test/Preprocessor/init-mips.c
> b/clang/test/Preprocessor/init-mips.c
> > index d76396aa35c91..a07cee64e6848 100644
> > --- a/clang/test/Preprocessor/init-mips.c
> > +++ b/clang/test/Preprocessor/init-mips.c
> > @@ -37,7 +37,6 @@
> > // MIPS32BE:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // MIPS32BE:#define __FLT_DIG__ 6
> > // MIPS32BE:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// MIPS32BE:#define __FLT_EVAL_METHOD__ 0
> > // MIPS32BE:#define __FLT_HAS_DENORM__ 1
> > // MIPS32BE:#define __FLT_HAS_INFINITY__ 1
> > // MIPS32BE:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -247,7 +246,6 @@
> > // MIPS32EL:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // MIPS32EL:#define __FLT_DIG__ 6
> > // MIPS32EL:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// MIPS32EL:#define __FLT_EVAL_METHOD__ 0
> > // MIPS32EL:#define __FLT_HAS_DENORM__ 1
> > // MIPS32EL:#define __FLT_HAS_INFINITY__ 1
> > // MIPS32EL:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -467,7 +465,6 @@
> > // MIPSN32BE: #define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // MIPSN32BE: #define __FLT_DIG__ 6
> > // MIPSN32BE: #define __FLT_EPSILON__ 1.19209290e-7F
> > -// MIPSN32BE: #define __FLT_EVAL_METHOD__ 0
> > // MIPSN32BE: #define __FLT_HAS_DENORM__ 1
> > // MIPSN32BE: #define __FLT_HAS_INFINITY__ 1
> > // MIPSN32BE: #define __FLT_HAS_QUIET_NAN__ 1
> > @@ -774,7 +771,6 @@
> > // MIPSN32EL: #define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // MIPSN32EL: #define __FLT_DIG__ 6
> > // MIPSN32EL: #define __FLT_EPSILON__ 1.19209290e-7F
> > -// MIPSN32EL: #define __FLT_EVAL_METHOD__ 0
> > // MIPSN32EL: #define __FLT_HAS_DENORM__ 1
> > // MIPSN32EL: #define __FLT_HAS_INFINITY__ 1
> > // MIPSN32EL: #define __FLT_HAS_QUIET_NAN__ 1
> > @@ -1074,7 +1070,6 @@
> > // MIPS64BE:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // MIPS64BE:#define __FLT_DIG__ 6
> > // MIPS64BE:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// MIPS64BE:#define __FLT_EVAL_METHOD__ 0
> > // MIPS64BE:#define __FLT_HAS_DENORM__ 1
> > // MIPS64BE:#define __FLT_HAS_INFINITY__ 1
> > // MIPS64BE:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -1284,7 +1279,6 @@
> > // MIPS64EL:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // MIPS64EL:#define __FLT_DIG__ 6
> > // MIPS64EL:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// MIPS64EL:#define __FLT_EVAL_METHOD__ 0
> > // MIPS64EL:#define __FLT_HAS_DENORM__ 1
> > // MIPS64EL:#define __FLT_HAS_INFINITY__ 1
> > // MIPS64EL:#define __FLT_HAS_QUIET_NAN__ 1
> >
> > diff --git a/clang/test/Preprocessor/init-ppc.c
> b/clang/test/Preprocessor/init-ppc.c
> > index 611b16dfb8f7e..45c8a5e53ad4f 100644
> > --- a/clang/test/Preprocessor/init-ppc.c
> > +++ b/clang/test/Preprocessor/init-ppc.c
> > @@ -30,7 +30,6 @@
> > // PPC603E:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // PPC603E:#define __FLT_DIG__ 6
> > // PPC603E:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// PPC603E:#define __FLT_EVAL_METHOD__ 0
> > // PPC603E:#define __FLT_HAS_DENORM__ 1
> > // PPC603E:#define __FLT_HAS_INFINITY__ 1
> > // PPC603E:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -224,7 +223,6 @@
> > // PPC:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // PPC:#define __FLT_DIG__ 6
> > // PPC:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// PPC:#define __FLT_EVAL_METHOD__ 0
> > // PPC:#define __FLT_HAS_DENORM__ 1
> > // PPC:#define __FLT_HAS_INFINITY__ 1
> > // PPC:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -425,7 +423,6 @@
> > // PPC-AIX:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // PPC-AIX:#define __FLT_DIG__ 6
> > // PPC-AIX:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// PPC-AIX:#define __FLT_EVAL_METHOD__ 1
> > // PPC-AIX:#define __FLT_HAS_DENORM__ 1
> > // PPC-AIX:#define __FLT_HAS_INFINITY__ 1
> > // PPC-AIX:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -798,7 +795,6 @@
> > // PPC-LINUX:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // PPC-LINUX:#define __FLT_DIG__ 6
> > // PPC-LINUX:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// PPC-LINUX:#define __FLT_EVAL_METHOD__ 0
> > // PPC-LINUX:#define __FLT_HAS_DENORM__ 1
> > // PPC-LINUX:#define __FLT_HAS_INFINITY__ 1
> > // PPC-LINUX:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -1006,7 +1002,6 @@
> > // PPC-DARWIN:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // PPC-DARWIN:#define __FLT_DIG__ 6
> > // PPC-DARWIN:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// PPC-DARWIN:#define __FLT_EVAL_METHOD__ 0
> > // PPC-DARWIN:#define __FLT_HAS_DENORM__ 1
> > // PPC-DARWIN:#define __FLT_HAS_INFINITY__ 1
> > // PPC-DARWIN:#define __FLT_HAS_QUIET_NAN__ 1
> >
> > diff --git a/clang/test/Preprocessor/init-ppc64.c
> b/clang/test/Preprocessor/init-ppc64.c
> > index 7a9525228c3b6..f0ccd1638c04d 100644
> > --- a/clang/test/Preprocessor/init-ppc64.c
> > +++ b/clang/test/Preprocessor/init-ppc64.c
> > @@ -35,7 +35,6 @@
> > // PPC64:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // PPC64:#define __FLT_DIG__ 6
> > // PPC64:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// PPC64:#define __FLT_EVAL_METHOD__ 0
> > // PPC64:#define __FLT_HAS_DENORM__ 1
> > // PPC64:#define __FLT_HAS_INFINITY__ 1
> > // PPC64:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -240,7 +239,6 @@
> > // PPC64LE:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // PPC64LE:#define __FLT_DIG__ 6
> > // PPC64LE:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// PPC64LE:#define __FLT_EVAL_METHOD__ 0
> > // PPC64LE:#define __FLT_HAS_DENORM__ 1
> > // PPC64LE:#define __FLT_HAS_INFINITY__ 1
> > // PPC64LE:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -703,7 +701,6 @@
> > // PPC64-AIX:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // PPC64-AIX:#define __FLT_DIG__ 6
> > // PPC64-AIX:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// PPC64-AIX:#define __FLT_EVAL_METHOD__ 1
> > // PPC64-AIX:#define __FLT_HAS_DENORM__ 1
> > // PPC64-AIX:#define __FLT_HAS_INFINITY__ 1
> > // PPC64-AIX:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -902,7 +899,6 @@
> > // PPC64-LINUX:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // PPC64-LINUX:#define __FLT_DIG__ 6
> > // PPC64-LINUX:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// PPC64-LINUX:#define __FLT_EVAL_METHOD__ 0
> > // PPC64-LINUX:#define __FLT_HAS_DENORM__ 1
> > // PPC64-LINUX:#define __FLT_HAS_INFINITY__ 1
> > // PPC64-LINUX:#define __FLT_HAS_QUIET_NAN__ 1
> >
> > diff --git a/clang/test/Preprocessor/init-s390x.c
> b/clang/test/Preprocessor/init-s390x.c
> > index b0e45b5348ce9..6c646527f50f7 100644
> > --- a/clang/test/Preprocessor/init-s390x.c
> > +++ b/clang/test/Preprocessor/init-s390x.c
> > @@ -23,7 +23,6 @@
> > // S390X:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // S390X:#define __FLT_DIG__ 6
> > // S390X:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// S390X:#define __FLT_EVAL_METHOD__ 0
> > // S390X:#define __FLT_HAS_DENORM__ 1
> > // S390X:#define __FLT_HAS_INFINITY__ 1
> > // S390X:#define __FLT_HAS_QUIET_NAN__ 1
> >
> > diff --git a/clang/test/Preprocessor/init-v7k-compat.c
> b/clang/test/Preprocessor/init-v7k-compat.c
> > index 482c7ad6ff687..ff5d4bbdea53a 100644
> > --- a/clang/test/Preprocessor/init-v7k-compat.c
> > +++ b/clang/test/Preprocessor/init-v7k-compat.c
> > @@ -28,7 +28,6 @@
> > // CHECK: #define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // CHECK: #define __FLT_DIG__ 6
> > // CHECK: #define __FLT_EPSILON__ 1.19209290e-7F
> > -// CHECK: #define __FLT_EVAL_METHOD__ 0
> > // CHECK: #define __FLT_HAS_DENORM__ 1
> > // CHECK: #define __FLT_HAS_INFINITY__ 1
> > // CHECK: #define __FLT_HAS_QUIET_NAN__ 1
> >
> > diff --git a/clang/test/Preprocessor/init-x86.c
> b/clang/test/Preprocessor/init-x86.c
> > index 527cd39508889..aa2e05ec807c7 100644
> > --- a/clang/test/Preprocessor/init-x86.c
> > +++ b/clang/test/Preprocessor/init-x86.c
> > @@ -24,7 +24,6 @@
> > // I386:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // I386:#define __FLT_DIG__ 6
> > // I386:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// I386:#define __FLT_EVAL_METHOD__ 2
> > // I386:#define __FLT_HAS_DENORM__ 1
> > // I386:#define __FLT_HAS_INFINITY__ 1
> > // I386:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -213,7 +212,6 @@
> > // I386-LINUX:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // I386-LINUX:#define __FLT_DIG__ 6
> > // I386-LINUX:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// I386-LINUX:#define __FLT_EVAL_METHOD__ 0
> > // I386-LINUX:#define __FLT_HAS_DENORM__ 1
> > // I386-LINUX:#define __FLT_HAS_INFINITY__ 1
> > // I386-LINUX:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -416,7 +414,6 @@
> > // I386-NETBSD:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // I386-NETBSD:#define __FLT_DIG__ 6
> > // I386-NETBSD:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// I386-NETBSD:#define __FLT_EVAL_METHOD__ 2
> > // I386-NETBSD:#define __FLT_HAS_DENORM__ 1
> > // I386-NETBSD:#define __FLT_HAS_INFINITY__ 1
> > // I386-NETBSD:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -590,13 +587,6 @@
> > // I386-NETBSD:#define __i386__ 1
> > // I386-NETBSD:#define i386 1
> >
> > -// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-netbsd
> -target-feature +sse2 < /dev/null | FileCheck -match-full-lines
> -check-prefix I386-NETBSD-SSE %s
> > -// I386-NETBSD-SSE:#define __FLT_EVAL_METHOD__ 0
> > -// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-netbsd6 <
> /dev/null | FileCheck -match-full-lines -check-prefix I386-NETBSD6 %s
> > -// I386-NETBSD6:#define __FLT_EVAL_METHOD__ 1
> > -// RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-netbsd6
> -target-feature +sse2 < /dev/null | FileCheck -match-full-lines
> -check-prefix I386-NETBSD6-SSE %s
> > -// I386-NETBSD6-SSE:#define __FLT_EVAL_METHOD__ 1
> > -
> > // RUN: %clang_cc1 -E -dM -triple=i686-pc-mingw32 < /dev/null |
> FileCheck -match-full-lines -check-prefix I386-DECLSPEC %s
> > // RUN: %clang_cc1 -E -dM -fms-extensions -triple=i686-pc-mingw32 <
> /dev/null | FileCheck -match-full-lines -check-prefix I386-DECLSPEC %s
> > // RUN: %clang_cc1 -E -dM -triple=i686-unknown-cygwin < /dev/null |
> FileCheck -match-full-lines -check-prefix I386-DECLSPEC %s
> > @@ -631,7 +621,6 @@
> > // X86_64:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // X86_64:#define __FLT_DIG__ 6
> > // X86_64:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// X86_64:#define __FLT_EVAL_METHOD__ 0
> > // X86_64:#define __FLT_HAS_DENORM__ 1
> > // X86_64:#define __FLT_HAS_INFINITY__ 1
> > // X86_64:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -839,7 +828,6 @@
> > // X32:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // X32:#define __FLT_DIG__ 6
> > // X32:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// X32:#define __FLT_EVAL_METHOD__ 0
> > // X32:#define __FLT_HAS_DENORM__ 1
> > // X32:#define __FLT_HAS_INFINITY__ 1
> > // X32:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -1046,7 +1034,6 @@
> > // X86_64-CLOUDABI:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // X86_64-CLOUDABI:#define __FLT_DIG__ 6
> > // X86_64-CLOUDABI:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// X86_64-CLOUDABI:#define __FLT_EVAL_METHOD__ 0
> > // X86_64-CLOUDABI:#define __FLT_HAS_DENORM__ 1
> > // X86_64-CLOUDABI:#define __FLT_HAS_INFINITY__ 1
> > // X86_64-CLOUDABI:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -1341,7 +1328,6 @@
> > // X86_64-LINUX:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // X86_64-LINUX:#define __FLT_DIG__ 6
> > // X86_64-LINUX:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// X86_64-LINUX:#define __FLT_EVAL_METHOD__ 0
> > // X86_64-LINUX:#define __FLT_HAS_DENORM__ 1
> > // X86_64-LINUX:#define __FLT_HAS_INFINITY__ 1
> > // X86_64-LINUX:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -1554,7 +1540,6 @@
> > // X86_64-NETBSD:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // X86_64-NETBSD:#define __FLT_DIG__ 6
> > // X86_64-NETBSD:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// X86_64-NETBSD:#define __FLT_EVAL_METHOD__ 0
> > // X86_64-NETBSD:#define __FLT_HAS_DENORM__ 1
> > // X86_64-NETBSD:#define __FLT_HAS_INFINITY__ 1
> > // X86_64-NETBSD:#define __FLT_HAS_QUIET_NAN__ 1
> >
> > diff --git a/clang/test/Preprocessor/init.c
> b/clang/test/Preprocessor/init.c
> > index dd645bf6003ce..a08e503570723 100644
> > --- a/clang/test/Preprocessor/init.c
> > +++ b/clang/test/Preprocessor/init.c
> > @@ -325,7 +325,6 @@
> > // MSP430:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // MSP430:#define __FLT_DIG__ 6
> > // MSP430:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// MSP430:#define __FLT_EVAL_METHOD__ 0
> > // MSP430:#define __FLT_HAS_DENORM__ 1
> > // MSP430:#define __FLT_HAS_INFINITY__ 1
> > // MSP430:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -513,7 +512,6 @@
> > // NVPTX32:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // NVPTX32:#define __FLT_DIG__ 6
> > // NVPTX32:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// NVPTX32:#define __FLT_EVAL_METHOD__ 0
> > // NVPTX32:#define __FLT_HAS_DENORM__ 1
> > // NVPTX32:#define __FLT_HAS_INFINITY__ 1
> > // NVPTX32:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -702,7 +700,6 @@
> > // NVPTX64:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // NVPTX64:#define __FLT_DIG__ 6
> > // NVPTX64:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// NVPTX64:#define __FLT_EVAL_METHOD__ 0
> > // NVPTX64:#define __FLT_HAS_DENORM__ 1
> > // NVPTX64:#define __FLT_HAS_INFINITY__ 1
> > // NVPTX64:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -906,7 +903,6 @@
> > // SPARC:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // SPARC:#define __FLT_DIG__ 6
> > // SPARC:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// SPARC:#define __FLT_EVAL_METHOD__ 0
> > // SPARC:#define __FLT_HAS_DENORM__ 1
> > // SPARC:#define __FLT_HAS_INFINITY__ 1
> > // SPARC:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -1107,7 +1103,6 @@
> > // TCE:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // TCE:#define __FLT_DIG__ 6
> > // TCE:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// TCE:#define __FLT_EVAL_METHOD__ 0
> > // TCE:#define __FLT_HAS_DENORM__ 1
> > // TCE:#define __FLT_HAS_INFINITY__ 1
> > // TCE:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -1274,7 +1269,6 @@
> > // PS4:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // PS4:#define __FLT_DIG__ 6
> > // PS4:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// PS4:#define __FLT_EVAL_METHOD__ 0
> > // PS4:#define __FLT_HAS_DENORM__ 1
> > // PS4:#define __FLT_HAS_INFINITY__ 1
> > // PS4:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -1576,7 +1570,6 @@
> > // WEBASSEMBLY-NEXT:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // WEBASSEMBLY-NEXT:#define __FLT_DIG__ 6
> > // WEBASSEMBLY-NEXT:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// WEBASSEMBLY-NEXT:#define __FLT_EVAL_METHOD__ 0
> > // WEBASSEMBLY-NEXT:#define __FLT_HAS_DENORM__ 1
> > // WEBASSEMBLY-NEXT:#define __FLT_HAS_INFINITY__ 1
> > // WEBASSEMBLY-NEXT:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -1946,7 +1939,6 @@
> > // AVR:#define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // AVR:#define __FLT_DIG__ 6
> > // AVR:#define __FLT_EPSILON__ 1.19209290e-7F
> > -// AVR:#define __FLT_EVAL_METHOD__ 0
> > // AVR:#define __FLT_HAS_DENORM__ 1
> > // AVR:#define __FLT_HAS_INFINITY__ 1
> > // AVR:#define __FLT_HAS_QUIET_NAN__ 1
> > @@ -2083,7 +2075,6 @@
> > // AVR:#define __WCHAR_TYPE__ int
> > // AVR:#define __WINT_TYPE__ int
> >
> > -
> > // RUN: %clang_cc1 -E -dM -ffreestanding \
> > // RUN: -triple i686-windows-msvc -fms-compatibility -x c++ <
> /dev/null \
> > // RUN: | FileCheck -match-full-lines -check-prefix MSVC-X32 %s
> > @@ -2229,7 +2220,6 @@
> > // RISCV32: #define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // RISCV32: #define __FLT_DIG__ 6
> > // RISCV32: #define __FLT_EPSILON__ 1.19209290e-7F
> > -// RISCV32: #define __FLT_EVAL_METHOD__ 0
> > // RISCV32: #define __FLT_HAS_DENORM__ 1
> > // RISCV32: #define __FLT_HAS_INFINITY__ 1
> > // RISCV32: #define __FLT_HAS_QUIET_NAN__ 1
> > @@ -2437,7 +2427,6 @@
> > // RISCV64: #define __FLT_DENORM_MIN__ 1.40129846e-45F
> > // RISCV64: #define __FLT_DIG__ 6
> > // RISCV64: #define __FLT_EPSILON__ 1.19209290e-7F
> > -// RISCV64: #define __FLT_EVAL_METHOD__ 0
> > // RISCV64: #define __FLT_HAS_DENORM__ 1
> > // RISCV64: #define __FLT_HAS_INFINITY__ 1
> > // RISCV64: #define __FLT_HAS_QUIET_NAN__ 1
> >
> > diff --git a/clang/test/Sema/fp-eval-pragma.cpp
> b/clang/test/Sema/fp-eval-pragma.cpp
> > new file mode 100644
> > index 0000000000000..42d88fd438e81
> > --- /dev/null
> > +++ b/clang/test/Sema/fp-eval-pragma.cpp
> > @@ -0,0 +1,87 @@
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple x86_64-linux-gnu -emit-llvm -o - -verify %s
> > +//
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple x86_64-linux-gnu -emit-llvm -o - -verify %s \
> > +// RUN: -ffp-eval-method=source
> > +//
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple x86_64-linux-gnu -emit-llvm -o - -verify %s \
> > +// RUN: -ffp-eval-method=double
> > +
> > +extern "C" int printf(const char *, ...);
> > +
> > +void foo1() {
> > + printf("FP: %d\n", __FLT_EVAL_METHOD__);
> > +}
> > +
> > +void apply_pragma() {
> > + // expected-note at +1{{#pragma entered here}}
> > +#pragma clang fp eval_method(double)
> > + // expected-error at +1{{'__FLT_EVAL_METHOD__' cannot be expanded
> inside a scope containing '#pragma clang fp eval_method'}}
> > + printf("FP: %d\n", __FLT_EVAL_METHOD__);
> > +}
> > +
> > +int foo2() {
> > + apply_pragma();
> > + return 0;
> > +}
> > +
> > +void foo() {
> > + auto a = __FLT_EVAL_METHOD__;
> > + {
> > + // expected-note at +1{{#pragma entered here}}
> > +#pragma clang fp eval_method(double)
> > + // expected-error at +1{{'__FLT_EVAL_METHOD__' cannot be expanded
> inside a scope containing '#pragma clang fp eval_method'}}
> > + auto b = __FLT_EVAL_METHOD__;
> > + }
> > + auto c = __FLT_EVAL_METHOD__;
> > +}
> > +
> > +void func() {
> > + {
> > + {
> > +#pragma clang fp eval_method(source)
> > + }
> > + int i = __FLT_EVAL_METHOD__; // ok, not in a scope changed by the
> pragma
> > + }
> > + {
> > + // expected-note at +1{{#pragma entered here}}
> > +#pragma clang fp eval_method(source)
> > + // expected-error at +1{{'__FLT_EVAL_METHOD__' cannot be expanded
> inside a scope containing '#pragma clang fp eval_method'}}
> > + int i = __FLT_EVAL_METHOD__;
> > + }
> > +}
> > +
> > +float G;
> > +
> > +int f(float x, float y, float z) {
> > + G = x * y + z;
> > + return __FLT_EVAL_METHOD__;
> > +}
> > +
> > +int foo(int flag, float x, float y, float z) {
> > + if (flag) {
> > + // expected-note at +1{{#pragma entered here}}
> > +#pragma clang fp eval_method(double)
> > + G = x + y + z;
> > + // expected-error at +1{{'__FLT_EVAL_METHOD__' cannot be expanded
> inside a scope containing '#pragma clang fp eval_method'}}
> > + return __FLT_EVAL_METHOD__;
> > + } else {
> > + // expected-note at +1{{#pragma entered here}}
> > +#pragma clang fp eval_method(extended)
> > + G = x + y + z;
> > + // expected-error at +1{{'__FLT_EVAL_METHOD__' cannot be expanded
> inside a scope containing '#pragma clang fp eval_method'}}
> > + return __FLT_EVAL_METHOD__;
> > + }
> > +}
> > +
> > +#if __FLT_EVAL_METHOD__ == 1
> > +#endif
> > +#pragma clang fp eval_method(source)
> > +
> > +// expected-note at +1{{#pragma entered here}}
> > +#pragma clang fp eval_method(double)
> > +// expected-error at +1{{'__FLT_EVAL_METHOD__' cannot be expanded inside
> a scope containing '#pragma clang fp eval_method'}}
> > +#if __FLT_EVAL_METHOD__ == 1
> > +#endif
> >
> > diff --git a/clang/test/Sema/x86-eval-method.c
> b/clang/test/Sema/x86-eval-method.c
> > new file mode 100644
> > index 0000000000000..90f2fefc511c0
> > --- /dev/null
> > +++ b/clang/test/Sema/x86-eval-method.c
> > @@ -0,0 +1,18 @@
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple i386-pc-windows -target-cpu pentium4 -target-feature
> -sse \
> > +// RUN: -emit-llvm -ffp-eval-method=source -o - -verify=warn %s
> > +//
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple i386-pc-windows -target-cpu pentium4 \
> > +// RUN: -emit-llvm -ffp-eval-method=source -o - -verify=no-warn %s
> > +
> > +// no-warn-no-diagnostics
> > +
> > +float add1(float a, float b, float c) {
> > + return a + b + c;
> > +} // warn-warning{{Setting FPEvalMethod to source on a 32bit target,
> with no SSE is not supported.}}
> > +
> > +float add2(float a, float b, float c) {
> > +#pragma clang fp eval_method(source)
> > + return a + b + c;
> > +} // warn-warning{{Setting FPEvalMethod to source on a 32bit target,
> with no SSE is not supported.}}
> >
> > diff --git a/clang/test/Sema/x86_64-eval-method.c
> b/clang/test/Sema/x86_64-eval-method.c
> > new file mode 100644
> > index 0000000000000..728423dd1b65b
> > --- /dev/null
> > +++ b/clang/test/Sema/x86_64-eval-method.c
> > @@ -0,0 +1,12 @@
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple x86_64-linux-gnu -target-feature -sse -emit-llvm -o -
> -verify %s
> > +//
> > +// RUN: %clang_cc1 -fexperimental-strict-floating-point \
> > +// RUN: -triple x86_64-linux-gnu -emit-llvm -o - -verify=no-warn %s
> > +
> > +// no-warn-no-diagnostics
> > +
> > +float add2(float a, float b, float c) {
> > +#pragma clang fp eval_method(source)
> > + return a + b + c;
> > +} // expected-warning{{Setting FPEvalMethod to source on a 32bit
> target, with no SSE is not supported.}}
> >
> >
> >
> > _______________________________________________
> > cfe-commits mailing list
> > cfe-commits at lists.llvm.org
> > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220215/d9a1bd9c/attachment-0001.html>
More information about the cfe-commits
mailing list