Add support for floating-point option `ffp-eval-method` and for

`pragma clang fp eval_method`.

Differential Revision: https://reviews.llvm.org/D109239
This commit is contained in:
Zahira Ammarguellat 2021-10-19 09:12:57 -07:00
parent 924032c592
commit 1592d88aa7
41 changed files with 904 additions and 72 deletions

View File

@ -3940,6 +3940,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 The ``#pragma float_control`` pragma allows precise floating-point
semantics and floating-point exception behavior to be specified semantics and floating-point exception behavior to be specified

View File

@ -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. * ``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. * ``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: .. option:: -f[no-]protect-parens:
This option pertains to floating-point types, complex types with 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 has no effect because the optimizer is prohibited from making unsafe
transformations. 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: .. _fp-constant-eval:
A note about Floating Point Constant Evaluation A note about Floating Point Constant Evaluation

View File

@ -321,6 +321,10 @@ def err_pragma_include_instead_system_reserved : Error<
"header '%0' is an implementation detail; #include %select{'%2'|either '%2' " "header '%0' is an implementation detail; #include %select{'%2'|either '%2' "
"or '%3'|one of %2}1 instead">; "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_poisoning_existing_macro : Warning<"poisoning existing macro">;
def pp_out_of_date_dependency : Warning< def pp_out_of_date_dependency : Warning<
"current file is older than dependency %0">; "current file is older than dependency %0">;

View File

@ -1267,6 +1267,9 @@ def err_pragma_attribute_namespace_on_attribute : Error<
def note_pragma_attribute_namespace_on_attribute : Note< def note_pragma_attribute_namespace_on_attribute : Note<
"omit the namespace to add attributes to the most-recently" "omit the namespace to add attributes to the most-recently"
" pushed attribute group">; " pushed attribute group">;
def warn_no_support_for_eval_method_source_on_m32 : Warning<
"Setting the floating point evaluation method to `source` on a target"
" without SSE is not supported.">, InGroup<Pragmas>;
// OpenCL EXTENSION pragma (OpenCL 1.1 [9.1]) // OpenCL EXTENSION pragma (OpenCL 1.1 [9.1])
def warn_pragma_expected_colon : Warning< def warn_pragma_expected_colon : Warning<

View File

@ -23,4 +23,5 @@ OPTION(NoHonorInfs, bool, 1, NoHonorNaNs)
OPTION(NoSignedZero, bool, 1, NoHonorInfs) OPTION(NoSignedZero, bool, 1, NoHonorInfs)
OPTION(AllowReciprocal, bool, 1, NoSignedZero) OPTION(AllowReciprocal, bool, 1, NoSignedZero)
OPTION(AllowApproxFunc, bool, 1, AllowReciprocal) OPTION(AllowApproxFunc, bool, 1, AllowReciprocal)
OPTION(FPEvalMethod, LangOptions::FPEvalMethodKind, 2, AllowApproxFunc)
#undef OPTION #undef OPTION

View File

@ -303,6 +303,7 @@ BENIGN_ENUM_LANGOPT(DefaultFPContractMode, FPModeKind, 2, FPM_Off, "FP contracti
COMPATIBLE_LANGOPT(ExpStrictFP, 1, false, "Enable experimental strict floating point") 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(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(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(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment")
LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility") LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility")
LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting") LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting")

View File

@ -235,6 +235,24 @@ public:
FPE_Strict 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. /// Possible exception handling behavior.
enum class ExceptionHandlingKind { None, SjLj, WinEH, DwarfCFI, Wasm }; enum class ExceptionHandlingKind { None, SjLj, WinEH, DwarfCFI, Wasm };

View File

@ -726,7 +726,11 @@ public:
} }
/// Return the value for the C99 FLT_EVAL_METHOD macro. /// 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 // getLargeArrayMinWidth/Align - Return the minimum array size that is
// 'large' and its alignment. // 'large' and its alignment.

View File

@ -1495,6 +1495,11 @@ def : Flag<["-"], "fextended-identifiers">, Group<clang_ignored_f_Group>;
def : Flag<["-"], "fno-extended-identifiers">, Group<f_Group>, Flags<[Unsupported]>; def : Flag<["-"], "fno-extended-identifiers">, Group<f_Group>, Flags<[Unsupported]>;
def fhosted : Flag<["-"], "fhosted">, Group<f_Group>; def fhosted : Flag<["-"], "fhosted">, Group<f_Group>;
def fdenormal_fp_math_EQ : Joined<["-"], "fdenormal-fp-math=">, Group<f_Group>, Flags<[CC1Option]>; 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]>, def ffp_model_EQ : Joined<["-"], "ffp-model=">, Group<f_Group>, Flags<[NoXarchOption]>,
HelpText<"Controls the semantics of floating-point calculations.">; HelpText<"Controls the semantics of floating-point calculations.">;
def ffp_exception_behavior_EQ : Joined<["-"], "ffp-exception-behavior=">, Group<f_Group>, Flags<[CC1Option]>, def ffp_exception_behavior_EQ : Joined<["-"], "ffp-exception-behavior=">, Group<f_Group>, Flags<[CC1Option]>,

View File

@ -179,12 +179,27 @@ class Preprocessor {
IdentifierInfo *Ident__is_target_vendor; // __is_target_vendor IdentifierInfo *Ident__is_target_vendor; // __is_target_vendor
IdentifierInfo *Ident__is_target_os; // __is_target_os IdentifierInfo *Ident__is_target_os; // __is_target_os
IdentifierInfo *Ident__is_target_environment; // __is_target_environment 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. // Weak, only valid (and set) while InMacroArgs is true.
Token* ArgMacro; Token* ArgMacro;
SourceLocation DATELoc, TIMELoc; 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. // Next __COUNTER__ value, starts at 0.
unsigned CounterValue = 0; unsigned CounterValue = 0;
@ -2048,6 +2063,38 @@ public:
unsigned getCounterValue() const { return CounterValue; } unsigned getCounterValue() const { return CounterValue; }
void setCounterValue(unsigned V) { CounterValue = V; } 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;
}
void setTUFPEvalMethod(LangOptions::FPEvalMethodKind Val) {
assert(Val != LangOptions::FEM_UnsetOnCommandLine &&
"TUPEvalMethod should never be set to FEM_UnsetOnCommandLine");
TUFPEvalMethod = Val;
}
/// Retrieves the module that we're currently building, if any. /// Retrieves the module that we're currently building, if any.
Module *getCurrentModule(); Module *getCurrentModule();

View File

@ -184,6 +184,7 @@ class Parser : public CodeCompletionHandler {
std::unique_ptr<PragmaHandler> PCSectionHandler; std::unique_ptr<PragmaHandler> PCSectionHandler;
std::unique_ptr<PragmaHandler> MSCommentHandler; std::unique_ptr<PragmaHandler> MSCommentHandler;
std::unique_ptr<PragmaHandler> MSDetectMismatchHandler; std::unique_ptr<PragmaHandler> MSDetectMismatchHandler;
std::unique_ptr<PragmaHandler> FPEvalMethodHandler;
std::unique_ptr<PragmaHandler> FloatControlHandler; std::unique_ptr<PragmaHandler> FloatControlHandler;
std::unique_ptr<PragmaHandler> MSPointersToMembers; std::unique_ptr<PragmaHandler> MSPointersToMembers;
std::unique_ptr<PragmaHandler> MSVtorDisp; std::unique_ptr<PragmaHandler> MSVtorDisp;

View File

@ -1541,19 +1541,16 @@ public:
/// statements. /// statements.
class FPFeaturesStateRAII { class FPFeaturesStateRAII {
public: public:
FPFeaturesStateRAII(Sema &S) : S(S), OldFPFeaturesState(S.CurFPFeatures) { FPFeaturesStateRAII(Sema &S);
OldOverrides = S.FpPragmaStack.CurrentValue; ~FPFeaturesStateRAII();
}
~FPFeaturesStateRAII() {
S.CurFPFeatures = OldFPFeaturesState;
S.FpPragmaStack.CurrentValue = OldOverrides;
}
FPOptionsOverride getOverrides() { return OldOverrides; } FPOptionsOverride getOverrides() { return OldOverrides; }
private: private:
Sema& S; Sema& S;
FPOptions OldFPFeaturesState; FPOptions OldFPFeaturesState;
FPOptionsOverride OldOverrides; FPOptionsOverride OldOverrides;
LangOptions::FPEvalMethodKind OldEvalMethod;
SourceLocation OldFPPragmaLocation;
}; };
void addImplicitTypedef(StringRef Name, QualType T); void addImplicitTypedef(StringRef Name, QualType T);
@ -10144,6 +10141,9 @@ public:
!CurFPFeatures.getAllowApproxFunc(); !CurFPFeatures.getAllowApproxFunc();
} }
void ActOnPragmaFPEvalMethod(SourceLocation Loc,
LangOptions::FPEvalMethodKind Value);
/// ActOnPragmaFloatControl - Call on well-formed \#pragma float_control /// ActOnPragmaFloatControl - Call on well-formed \#pragma float_control
void ActOnPragmaFloatControl(SourceLocation Loc, PragmaMsStackAction Action, void ActOnPragmaFloatControl(SourceLocation Loc, PragmaMsStackAction Action,
PragmaFloatControlKind Value); PragmaFloatControlKind Value);

View File

@ -749,7 +749,9 @@ public:
} }
// AIX sets FLT_EVAL_METHOD to be 1. // 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; } bool defaultsToAIXPowerAlignment() const override { return true; }
}; };

View File

@ -168,11 +168,15 @@ public:
return LongDoubleFormat == &llvm::APFloat::IEEEquad() ? "g" : "e"; return LongDoubleFormat == &llvm::APFloat::IEEEquad() ? "g" : "e";
} }
unsigned getFloatEvalMethod() const override { LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
// X87 evaluates with 80 bits "long double" precision. // 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<const char *> getGCCRegNames() const override;
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
@ -471,13 +475,13 @@ public:
NetBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) NetBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: NetBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {} : NetBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {}
unsigned getFloatEvalMethod() const override { LangOptions::FPEvalMethodKind getFPEvalMethod() const override {
VersionTuple OsVersion = getTriple().getOSVersion(); VersionTuple OsVersion = getTriple().getOSVersion();
// New NetBSD uses the default rounding mode. // New NetBSD uses the default rounding mode.
if (OsVersion >= VersionTuple(6, 99, 26) || OsVersion.getMajor() == 0) 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. // NetBSD before 6.99.26 defaults to "double" rounding.
return 1; return LangOptions::FPEvalMethodKind::FEM_Double;
} }
}; };

View File

@ -2726,6 +2726,8 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
StringRef FPModel = ""; StringRef FPModel = "";
// -ffp-exception-behavior options: strict, maytrap, ignore // -ffp-exception-behavior options: strict, maytrap, ignore
StringRef FPExceptionBehavior = ""; StringRef FPExceptionBehavior = "";
// -ffp-eval-method options: double, extended, source
StringRef FPEvalMethod = "";
const llvm::DenormalMode DefaultDenormalFPMath = const llvm::DenormalMode DefaultDenormalFPMath =
TC.getDefaultDenormalModeForType(Args, JA); TC.getDefaultDenormalModeForType(Args, JA);
const llvm::DenormalMode DefaultDenormalFP32Math = const llvm::DenormalMode DefaultDenormalFP32Math =
@ -2921,6 +2923,18 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
break; 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: case options::OPT_ffinite_math_only:
HonorINFs = false; HonorINFs = false;
HonorNaNs = false; HonorNaNs = false;
@ -3076,6 +3090,9 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
CmdArgs.push_back(Args.MakeArgString("-ffp-exception-behavior=" + CmdArgs.push_back(Args.MakeArgString("-ffp-exception-behavior=" +
FPExceptionBehavior)); FPExceptionBehavior));
if (!FPEvalMethod.empty())
CmdArgs.push_back(Args.MakeArgString("-ffp-eval-method=" + FPEvalMethod));
ParseMRecip(D, Args, CmdArgs); ParseMRecip(D, Args, CmdArgs);
// -ffast-math enables the __FAST_MATH__ preprocessor macro, but check for the // -ffast-math enables the __FAST_MATH__ preprocessor macro, but check for the

View File

@ -1136,7 +1136,6 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
} }
// Macros to control C99 numerics and <float.h> // Macros to control C99 numerics and <float.h>
Builder.defineMacro("__FLT_EVAL_METHOD__", Twine(TI.getFloatEvalMethod()));
Builder.defineMacro("__FLT_RADIX__", "2"); Builder.defineMacro("__FLT_RADIX__", "2");
Builder.defineMacro("__DECIMAL_DIG__", "__LDBL_DECIMAL_DIG__"); Builder.defineMacro("__DECIMAL_DIG__", "__LDBL_DECIMAL_DIG__");

View File

@ -342,6 +342,7 @@ void Preprocessor::RegisterBuiltinMacros() {
Ident__TIME__ = RegisterBuiltinMacro(*this, "__TIME__"); Ident__TIME__ = RegisterBuiltinMacro(*this, "__TIME__");
Ident__COUNTER__ = RegisterBuiltinMacro(*this, "__COUNTER__"); Ident__COUNTER__ = RegisterBuiltinMacro(*this, "__COUNTER__");
Ident_Pragma = RegisterBuiltinMacro(*this, "_Pragma"); Ident_Pragma = RegisterBuiltinMacro(*this, "_Pragma");
Ident__FLT_EVAL_METHOD__ = RegisterBuiltinMacro(*this, "__FLT_EVAL_METHOD__");
// C++ Standing Document Extensions. // C++ Standing Document Extensions.
if (getLangOpts().CPlusPlus) if (getLangOpts().CPlusPlus)
@ -1574,6 +1575,17 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
// Surround the string with " and strip the trailing newline. // Surround the string with " and strip the trailing newline.
OS << '"' << StringRef(Result).drop_back() << '"'; OS << '"' << StringRef(Result).drop_back() << '"';
Tok.setKind(tok::string_literal); 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__) { } else if (II == Ident__COUNTER__) {
// __COUNTER__ expands to a simple numeric value. // __COUNTER__ expands to a simple numeric value.
OS << CounterValue++; OS << CounterValue++;

View File

@ -208,6 +208,9 @@ void Preprocessor::Initialize(const TargetInfo &Target,
// Populate the identifier table with info about keywords for the current language. // Populate the identifier table with info about keywords for the current language.
Identifiers.AddKeywords(LangOpts); Identifiers.AddKeywords(LangOpts);
// Initialize the __FTL_EVAL_METHOD__ macro to the TargetInfo.
setTUFPEvalMethod(getTargetInfo().getFPEvalMethod());
} }
void Preprocessor::InitializeForModelFile() { void Preprocessor::InitializeForModelFile() {

View File

@ -3028,12 +3028,13 @@ void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP,
namespace { namespace {
/// Used as the annotation value for tok::annot_pragma_fp. /// Used as the annotation value for tok::annot_pragma_fp.
struct TokFPAnnotValue { struct TokFPAnnotValue {
enum FlagKinds { Contract, Reassociate, Exceptions }; enum FlagKinds { Contract, Reassociate, Exceptions, EvalMethod };
enum FlagValues { On, Off, Fast }; enum FlagValues { On, Off, Fast };
llvm::Optional<LangOptions::FPModeKind> ContractValue; llvm::Optional<LangOptions::FPModeKind> ContractValue;
llvm::Optional<LangOptions::FPModeKind> ReassociateValue; llvm::Optional<LangOptions::FPModeKind> ReassociateValue;
llvm::Optional<LangOptions::FPExceptionModeKind> ExceptionsValue; llvm::Optional<LangOptions::FPExceptionModeKind> ExceptionsValue;
llvm::Optional<LangOptions::FPEvalMethodKind> EvalMethodValue;
}; };
} // end anonymous namespace } // end anonymous namespace
@ -3060,6 +3061,7 @@ void PragmaFPHandler::HandlePragma(Preprocessor &PP,
.Case("contract", TokFPAnnotValue::Contract) .Case("contract", TokFPAnnotValue::Contract)
.Case("reassociate", TokFPAnnotValue::Reassociate) .Case("reassociate", TokFPAnnotValue::Reassociate)
.Case("exceptions", TokFPAnnotValue::Exceptions) .Case("exceptions", TokFPAnnotValue::Exceptions)
.Case("eval_method", TokFPAnnotValue::EvalMethod)
.Default(None); .Default(None);
if (!FlagKind) { if (!FlagKind) {
PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option) PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
@ -3074,8 +3076,11 @@ void PragmaFPHandler::HandlePragma(Preprocessor &PP,
return; return;
} }
PP.Lex(Tok); 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.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
<< PP.getSpelling(Tok) << OptionInfo->getName() << PP.getSpelling(Tok) << OptionInfo->getName()
<< static_cast<int>(*FlagKind); << static_cast<int>(*FlagKind);
@ -3121,6 +3126,19 @@ void PragmaFPHandler::HandlePragma(Preprocessor &PP,
<< PP.getSpelling(Tok) << OptionInfo->getName() << *FlagKind; << PP.getSpelling(Tok) << OptionInfo->getName() << *FlagKind;
return; 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); PP.Lex(Tok);
@ -3223,6 +3241,9 @@ void Parser::HandlePragmaFP() {
if (AnnotValue->ExceptionsValue) if (AnnotValue->ExceptionsValue)
Actions.ActOnPragmaFPExceptions(Tok.getLocation(), Actions.ActOnPragmaFPExceptions(Tok.getLocation(),
*AnnotValue->ExceptionsValue); *AnnotValue->ExceptionsValue);
if (AnnotValue->EvalMethodValue)
Actions.ActOnPragmaFPEvalMethod(Tok.getLocation(),
*AnnotValue->EvalMethodValue);
ConsumeAnnotationToken(); ConsumeAnnotationToken();
} }

View File

@ -1153,6 +1153,16 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
if (R.isUsable()) if (R.isUsable())
Stmts.push_back(R.get()); 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(); SourceLocation CloseLoc = Tok.getLocation();

View File

@ -242,6 +242,15 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
SemaPPCallbackHandler = Callbacks.get(); SemaPPCallbackHandler = Callbacks.get();
PP.addPPCallbacks(std::move(Callbacks)); PP.addPPCallbacks(std::move(Callbacks));
SemaPPCallbackHandler->set(*this); 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. // Anchor Sema's type info to this TU.
@ -2630,3 +2639,15 @@ const llvm::MapVector<FieldDecl *, Sema::DeleteLocs> &
Sema::getMismatchingDeleteExpressions() const { Sema::getMismatchingDeleteExpressions() const {
return DeleteExprs; 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);
}

View File

@ -470,6 +470,27 @@ void Sema::ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name,
Consumer.HandleTopLevelDecl(DeclGroupRef(PDMD)); 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, void Sema::ActOnPragmaFloatControl(SourceLocation Loc,
PragmaMsStackAction Action, PragmaMsStackAction Action,
PragmaFloatControlKind Value) { PragmaFloatControlKind Value) {

View File

@ -773,6 +773,40 @@ ExprResult Sema::UsualUnaryConversions(Expr *E) {
QualType Ty = E->getType(); QualType Ty = E->getType();
assert(!Ty.isNull() && "UsualUnaryConversions - missing type"); 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 // Half FP have to be promoted to float unless it is natively supported
if (Ty->isHalfType() && !getLangOpts().NativeHalfType) if (Ty->isHalfType() && !getLangOpts().NativeHalfType)
return ImpCastExprToType(Res.get(), Context.FloatTy, CK_FloatingCast); return ImpCastExprToType(Res.get(), Context.FloatTy, CK_FloatingCast);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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__;
}

View File

@ -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;
}

View File

@ -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 -DEXCEPT=1 \
// RUN: %clang_cc1 -fexperimental-strict-floating-point -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s // RUN: -fcxx-exceptions -triple x86_64-linux-gnu -emit-llvm -o - %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: | FileCheck -check-prefix=CHECK-NS %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 \
// 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. // Verify float_control(precise, off) enables fast math flags on fp operations.
float fp_precise_1(float a, float b, float c) { float fp_precise_1(float a, float b, float c) {
@ -229,3 +275,115 @@ float try_lam(float x, unsigned n) {
result = x + t; result = x + t;
return result; 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
}

View File

@ -0,0 +1,82 @@
// RUN: %clang_cc1 -E -dM -triple=x86_64-none-none %s -o - \
// RUN: | FileCheck %s -strict-whitespace
// RUN: %clang_cc1 -E -dM -triple=x86_64-none-none -target-feature -sse \
// RUN: %s -o - | FileCheck %s -check-prefix=EXT -strict-whitespace
// RUN: %clang_cc1 -E -dM -triple=arm64e-apple-ios -target-feature -sse \
// RUN: %s -o - | FileCheck %s -strict-whitespace
// RUN: %clang_cc1 -E -dM -triple=arm64e-apple-ios -target-feature +sse \
// RUN: %s -o - | FileCheck %s -strict-whitespace
// RUN: %clang_cc1 -E -dM -triple=arm64_32-apple-ios %s -o - \
// RUN: | FileCheck %s -strict-whitespace
// RUN: %clang_cc1 -E -dM -triple=arm64_32-apple-ios -target-feature -sse \
// RUN: %s -o - | FileCheck %s -strict-whitespace
// RUN: %clang_cc1 -E -dM -triple i386-pc-windows -target-cpu pentium4 %s -o - \
// RUN: | FileCheck %s -strict-whitespace
// RUN: %clang_cc1 -E -dM -triple i386-pc-windows -target-cpu pentium4 \
// RUN: -target-feature -sse %s -o - | FileCheck -check-prefix=EXT %s \
// RUN: -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 "Three"
#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 "One"
// EXT: #define Name "Three"
return Name;
}
#pragma fp eval_method(double)
#if __FLT_EVAL_METHOD__ == 3
#define Val "Unset"
#elif __FLT_EVAL_METHOD__ == 0
#define Val "val0"
#elif __FLT_EVAL_METHOD__ == 1
#define Val "val1"
#elif __FLT_EVAL_METHOD__ == 2
#define Val "val2"
#endif
int goo() {
// CHECK: #define Val "val0"
// EXT: #define Val "val2"
return Val;
}

View File

@ -93,7 +93,6 @@
// AARCH64-NEXT: #define __FLT_DENORM_MIN__ 1.40129846e-45F // AARCH64-NEXT: #define __FLT_DENORM_MIN__ 1.40129846e-45F
// AARCH64-NEXT: #define __FLT_DIG__ 6 // AARCH64-NEXT: #define __FLT_DIG__ 6
// AARCH64-NEXT: #define __FLT_EPSILON__ 1.19209290e-7F // 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_DENORM__ 1
// AARCH64-NEXT: #define __FLT_HAS_INFINITY__ 1 // AARCH64-NEXT: #define __FLT_HAS_INFINITY__ 1
// AARCH64-NEXT: #define __FLT_HAS_QUIET_NAN__ 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_DENORM_MIN__ 1.40129846e-45F
// AARCH64-DARWIN: #define __FLT_DIG__ 6 // AARCH64-DARWIN: #define __FLT_DIG__ 6
// AARCH64-DARWIN: #define __FLT_EPSILON__ 1.19209290e-7F // 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_DENORM__ 1
// AARCH64-DARWIN: #define __FLT_HAS_INFINITY__ 1 // AARCH64-DARWIN: #define __FLT_HAS_INFINITY__ 1
// AARCH64-DARWIN: #define __FLT_HAS_QUIET_NAN__ 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_DENORM_MIN__ 1.40129846e-45F
// AARCH64-MSVC: #define __FLT_DIG__ 6 // AARCH64-MSVC: #define __FLT_DIG__ 6
// AARCH64-MSVC: #define __FLT_EPSILON__ 1.19209290e-7F // 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_DENORM__ 1
// AARCH64-MSVC: #define __FLT_HAS_INFINITY__ 1 // AARCH64-MSVC: #define __FLT_HAS_INFINITY__ 1
// AARCH64-MSVC: #define __FLT_HAS_QUIET_NAN__ 1 // AARCH64-MSVC: #define __FLT_HAS_QUIET_NAN__ 1

View File

@ -35,7 +35,6 @@
// ARM:#define __FLT_DENORM_MIN__ 1.40129846e-45F // ARM:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// ARM:#define __FLT_DIG__ 6 // ARM:#define __FLT_DIG__ 6
// ARM:#define __FLT_EPSILON__ 1.19209290e-7F // ARM:#define __FLT_EPSILON__ 1.19209290e-7F
// ARM:#define __FLT_EVAL_METHOD__ 0
// ARM:#define __FLT_HAS_DENORM__ 1 // ARM:#define __FLT_HAS_DENORM__ 1
// ARM:#define __FLT_HAS_INFINITY__ 1 // ARM:#define __FLT_HAS_INFINITY__ 1
// ARM:#define __FLT_HAS_QUIET_NAN__ 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_DENORM_MIN__ 1.40129846e-45F
// ARM-BE:#define __FLT_DIG__ 6 // ARM-BE:#define __FLT_DIG__ 6
// ARM-BE:#define __FLT_EPSILON__ 1.19209290e-7F // 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_DENORM__ 1
// ARM-BE:#define __FLT_HAS_INFINITY__ 1 // ARM-BE:#define __FLT_HAS_INFINITY__ 1
// ARM-BE:#define __FLT_HAS_QUIET_NAN__ 1 // ARM-BE:#define __FLT_HAS_QUIET_NAN__ 1
@ -428,7 +426,6 @@
// ARMEABISOFTFP:#define __FLT_DENORM_MIN__ 1.40129846e-45F // ARMEABISOFTFP:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// ARMEABISOFTFP:#define __FLT_DIG__ 6 // ARMEABISOFTFP:#define __FLT_DIG__ 6
// ARMEABISOFTFP:#define __FLT_EPSILON__ 1.19209290e-7F // ARMEABISOFTFP:#define __FLT_EPSILON__ 1.19209290e-7F
// ARMEABISOFTFP:#define __FLT_EVAL_METHOD__ 0
// ARMEABISOFTFP:#define __FLT_HAS_DENORM__ 1 // ARMEABISOFTFP:#define __FLT_HAS_DENORM__ 1
// ARMEABISOFTFP:#define __FLT_HAS_INFINITY__ 1 // ARMEABISOFTFP:#define __FLT_HAS_INFINITY__ 1
// ARMEABISOFTFP:#define __FLT_HAS_QUIET_NAN__ 1 // ARMEABISOFTFP:#define __FLT_HAS_QUIET_NAN__ 1
@ -623,7 +620,6 @@
// ARMEABIHARDFP:#define __FLT_DENORM_MIN__ 1.40129846e-45F // ARMEABIHARDFP:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// ARMEABIHARDFP:#define __FLT_DIG__ 6 // ARMEABIHARDFP:#define __FLT_DIG__ 6
// ARMEABIHARDFP:#define __FLT_EPSILON__ 1.19209290e-7F // ARMEABIHARDFP:#define __FLT_EPSILON__ 1.19209290e-7F
// ARMEABIHARDFP:#define __FLT_EVAL_METHOD__ 0
// ARMEABIHARDFP:#define __FLT_HAS_DENORM__ 1 // ARMEABIHARDFP:#define __FLT_HAS_DENORM__ 1
// ARMEABIHARDFP:#define __FLT_HAS_INFINITY__ 1 // ARMEABIHARDFP:#define __FLT_HAS_INFINITY__ 1
// ARMEABIHARDFP:#define __FLT_HAS_QUIET_NAN__ 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_DENORM_MIN__ 1.40129846e-45F
// ARM-NETBSD:#define __FLT_DIG__ 6 // ARM-NETBSD:#define __FLT_DIG__ 6
// ARM-NETBSD:#define __FLT_EPSILON__ 1.19209290e-7F // 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_DENORM__ 1
// ARM-NETBSD:#define __FLT_HAS_INFINITY__ 1 // ARM-NETBSD:#define __FLT_HAS_INFINITY__ 1
// ARM-NETBSD:#define __FLT_HAS_QUIET_NAN__ 1 // ARM-NETBSD:#define __FLT_HAS_QUIET_NAN__ 1

View File

@ -37,7 +37,6 @@
// MIPS32BE:#define __FLT_DENORM_MIN__ 1.40129846e-45F // MIPS32BE:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// MIPS32BE:#define __FLT_DIG__ 6 // MIPS32BE:#define __FLT_DIG__ 6
// MIPS32BE:#define __FLT_EPSILON__ 1.19209290e-7F // MIPS32BE:#define __FLT_EPSILON__ 1.19209290e-7F
// MIPS32BE:#define __FLT_EVAL_METHOD__ 0
// MIPS32BE:#define __FLT_HAS_DENORM__ 1 // MIPS32BE:#define __FLT_HAS_DENORM__ 1
// MIPS32BE:#define __FLT_HAS_INFINITY__ 1 // MIPS32BE:#define __FLT_HAS_INFINITY__ 1
// MIPS32BE:#define __FLT_HAS_QUIET_NAN__ 1 // MIPS32BE:#define __FLT_HAS_QUIET_NAN__ 1
@ -247,7 +246,6 @@
// MIPS32EL:#define __FLT_DENORM_MIN__ 1.40129846e-45F // MIPS32EL:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// MIPS32EL:#define __FLT_DIG__ 6 // MIPS32EL:#define __FLT_DIG__ 6
// MIPS32EL:#define __FLT_EPSILON__ 1.19209290e-7F // MIPS32EL:#define __FLT_EPSILON__ 1.19209290e-7F
// MIPS32EL:#define __FLT_EVAL_METHOD__ 0
// MIPS32EL:#define __FLT_HAS_DENORM__ 1 // MIPS32EL:#define __FLT_HAS_DENORM__ 1
// MIPS32EL:#define __FLT_HAS_INFINITY__ 1 // MIPS32EL:#define __FLT_HAS_INFINITY__ 1
// MIPS32EL:#define __FLT_HAS_QUIET_NAN__ 1 // MIPS32EL:#define __FLT_HAS_QUIET_NAN__ 1
@ -467,7 +465,6 @@
// MIPSN32BE: #define __FLT_DENORM_MIN__ 1.40129846e-45F // MIPSN32BE: #define __FLT_DENORM_MIN__ 1.40129846e-45F
// MIPSN32BE: #define __FLT_DIG__ 6 // MIPSN32BE: #define __FLT_DIG__ 6
// MIPSN32BE: #define __FLT_EPSILON__ 1.19209290e-7F // MIPSN32BE: #define __FLT_EPSILON__ 1.19209290e-7F
// MIPSN32BE: #define __FLT_EVAL_METHOD__ 0
// MIPSN32BE: #define __FLT_HAS_DENORM__ 1 // MIPSN32BE: #define __FLT_HAS_DENORM__ 1
// MIPSN32BE: #define __FLT_HAS_INFINITY__ 1 // MIPSN32BE: #define __FLT_HAS_INFINITY__ 1
// MIPSN32BE: #define __FLT_HAS_QUIET_NAN__ 1 // MIPSN32BE: #define __FLT_HAS_QUIET_NAN__ 1
@ -774,7 +771,6 @@
// MIPSN32EL: #define __FLT_DENORM_MIN__ 1.40129846e-45F // MIPSN32EL: #define __FLT_DENORM_MIN__ 1.40129846e-45F
// MIPSN32EL: #define __FLT_DIG__ 6 // MIPSN32EL: #define __FLT_DIG__ 6
// MIPSN32EL: #define __FLT_EPSILON__ 1.19209290e-7F // MIPSN32EL: #define __FLT_EPSILON__ 1.19209290e-7F
// MIPSN32EL: #define __FLT_EVAL_METHOD__ 0
// MIPSN32EL: #define __FLT_HAS_DENORM__ 1 // MIPSN32EL: #define __FLT_HAS_DENORM__ 1
// MIPSN32EL: #define __FLT_HAS_INFINITY__ 1 // MIPSN32EL: #define __FLT_HAS_INFINITY__ 1
// MIPSN32EL: #define __FLT_HAS_QUIET_NAN__ 1 // MIPSN32EL: #define __FLT_HAS_QUIET_NAN__ 1
@ -1074,7 +1070,6 @@
// MIPS64BE:#define __FLT_DENORM_MIN__ 1.40129846e-45F // MIPS64BE:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// MIPS64BE:#define __FLT_DIG__ 6 // MIPS64BE:#define __FLT_DIG__ 6
// MIPS64BE:#define __FLT_EPSILON__ 1.19209290e-7F // MIPS64BE:#define __FLT_EPSILON__ 1.19209290e-7F
// MIPS64BE:#define __FLT_EVAL_METHOD__ 0
// MIPS64BE:#define __FLT_HAS_DENORM__ 1 // MIPS64BE:#define __FLT_HAS_DENORM__ 1
// MIPS64BE:#define __FLT_HAS_INFINITY__ 1 // MIPS64BE:#define __FLT_HAS_INFINITY__ 1
// MIPS64BE:#define __FLT_HAS_QUIET_NAN__ 1 // MIPS64BE:#define __FLT_HAS_QUIET_NAN__ 1
@ -1284,7 +1279,6 @@
// MIPS64EL:#define __FLT_DENORM_MIN__ 1.40129846e-45F // MIPS64EL:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// MIPS64EL:#define __FLT_DIG__ 6 // MIPS64EL:#define __FLT_DIG__ 6
// MIPS64EL:#define __FLT_EPSILON__ 1.19209290e-7F // MIPS64EL:#define __FLT_EPSILON__ 1.19209290e-7F
// MIPS64EL:#define __FLT_EVAL_METHOD__ 0
// MIPS64EL:#define __FLT_HAS_DENORM__ 1 // MIPS64EL:#define __FLT_HAS_DENORM__ 1
// MIPS64EL:#define __FLT_HAS_INFINITY__ 1 // MIPS64EL:#define __FLT_HAS_INFINITY__ 1
// MIPS64EL:#define __FLT_HAS_QUIET_NAN__ 1 // MIPS64EL:#define __FLT_HAS_QUIET_NAN__ 1

View File

@ -30,7 +30,6 @@
// PPC603E:#define __FLT_DENORM_MIN__ 1.40129846e-45F // PPC603E:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// PPC603E:#define __FLT_DIG__ 6 // PPC603E:#define __FLT_DIG__ 6
// PPC603E:#define __FLT_EPSILON__ 1.19209290e-7F // PPC603E:#define __FLT_EPSILON__ 1.19209290e-7F
// PPC603E:#define __FLT_EVAL_METHOD__ 0
// PPC603E:#define __FLT_HAS_DENORM__ 1 // PPC603E:#define __FLT_HAS_DENORM__ 1
// PPC603E:#define __FLT_HAS_INFINITY__ 1 // PPC603E:#define __FLT_HAS_INFINITY__ 1
// PPC603E:#define __FLT_HAS_QUIET_NAN__ 1 // PPC603E:#define __FLT_HAS_QUIET_NAN__ 1
@ -224,7 +223,6 @@
// PPC:#define __FLT_DENORM_MIN__ 1.40129846e-45F // PPC:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// PPC:#define __FLT_DIG__ 6 // PPC:#define __FLT_DIG__ 6
// PPC:#define __FLT_EPSILON__ 1.19209290e-7F // PPC:#define __FLT_EPSILON__ 1.19209290e-7F
// PPC:#define __FLT_EVAL_METHOD__ 0
// PPC:#define __FLT_HAS_DENORM__ 1 // PPC:#define __FLT_HAS_DENORM__ 1
// PPC:#define __FLT_HAS_INFINITY__ 1 // PPC:#define __FLT_HAS_INFINITY__ 1
// PPC:#define __FLT_HAS_QUIET_NAN__ 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_DENORM_MIN__ 1.40129846e-45F
// PPC-AIX:#define __FLT_DIG__ 6 // PPC-AIX:#define __FLT_DIG__ 6
// PPC-AIX:#define __FLT_EPSILON__ 1.19209290e-7F // 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_DENORM__ 1
// PPC-AIX:#define __FLT_HAS_INFINITY__ 1 // PPC-AIX:#define __FLT_HAS_INFINITY__ 1
// PPC-AIX:#define __FLT_HAS_QUIET_NAN__ 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_DENORM_MIN__ 1.40129846e-45F
// PPC-LINUX:#define __FLT_DIG__ 6 // PPC-LINUX:#define __FLT_DIG__ 6
// PPC-LINUX:#define __FLT_EPSILON__ 1.19209290e-7F // 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_DENORM__ 1
// PPC-LINUX:#define __FLT_HAS_INFINITY__ 1 // PPC-LINUX:#define __FLT_HAS_INFINITY__ 1
// PPC-LINUX:#define __FLT_HAS_QUIET_NAN__ 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_DENORM_MIN__ 1.40129846e-45F
// PPC-DARWIN:#define __FLT_DIG__ 6 // PPC-DARWIN:#define __FLT_DIG__ 6
// PPC-DARWIN:#define __FLT_EPSILON__ 1.19209290e-7F // 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_DENORM__ 1
// PPC-DARWIN:#define __FLT_HAS_INFINITY__ 1 // PPC-DARWIN:#define __FLT_HAS_INFINITY__ 1
// PPC-DARWIN:#define __FLT_HAS_QUIET_NAN__ 1 // PPC-DARWIN:#define __FLT_HAS_QUIET_NAN__ 1

View File

@ -35,7 +35,6 @@
// PPC64:#define __FLT_DENORM_MIN__ 1.40129846e-45F // PPC64:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// PPC64:#define __FLT_DIG__ 6 // PPC64:#define __FLT_DIG__ 6
// PPC64:#define __FLT_EPSILON__ 1.19209290e-7F // PPC64:#define __FLT_EPSILON__ 1.19209290e-7F
// PPC64:#define __FLT_EVAL_METHOD__ 0
// PPC64:#define __FLT_HAS_DENORM__ 1 // PPC64:#define __FLT_HAS_DENORM__ 1
// PPC64:#define __FLT_HAS_INFINITY__ 1 // PPC64:#define __FLT_HAS_INFINITY__ 1
// PPC64:#define __FLT_HAS_QUIET_NAN__ 1 // PPC64:#define __FLT_HAS_QUIET_NAN__ 1
@ -240,7 +239,6 @@
// PPC64LE:#define __FLT_DENORM_MIN__ 1.40129846e-45F // PPC64LE:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// PPC64LE:#define __FLT_DIG__ 6 // PPC64LE:#define __FLT_DIG__ 6
// PPC64LE:#define __FLT_EPSILON__ 1.19209290e-7F // PPC64LE:#define __FLT_EPSILON__ 1.19209290e-7F
// PPC64LE:#define __FLT_EVAL_METHOD__ 0
// PPC64LE:#define __FLT_HAS_DENORM__ 1 // PPC64LE:#define __FLT_HAS_DENORM__ 1
// PPC64LE:#define __FLT_HAS_INFINITY__ 1 // PPC64LE:#define __FLT_HAS_INFINITY__ 1
// PPC64LE:#define __FLT_HAS_QUIET_NAN__ 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_DENORM_MIN__ 1.40129846e-45F
// PPC64-AIX:#define __FLT_DIG__ 6 // PPC64-AIX:#define __FLT_DIG__ 6
// PPC64-AIX:#define __FLT_EPSILON__ 1.19209290e-7F // 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_DENORM__ 1
// PPC64-AIX:#define __FLT_HAS_INFINITY__ 1 // PPC64-AIX:#define __FLT_HAS_INFINITY__ 1
// PPC64-AIX:#define __FLT_HAS_QUIET_NAN__ 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_DENORM_MIN__ 1.40129846e-45F
// PPC64-LINUX:#define __FLT_DIG__ 6 // PPC64-LINUX:#define __FLT_DIG__ 6
// PPC64-LINUX:#define __FLT_EPSILON__ 1.19209290e-7F // 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_DENORM__ 1
// PPC64-LINUX:#define __FLT_HAS_INFINITY__ 1 // PPC64-LINUX:#define __FLT_HAS_INFINITY__ 1
// PPC64-LINUX:#define __FLT_HAS_QUIET_NAN__ 1 // PPC64-LINUX:#define __FLT_HAS_QUIET_NAN__ 1

View File

@ -23,7 +23,6 @@
// S390X:#define __FLT_DENORM_MIN__ 1.40129846e-45F // S390X:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// S390X:#define __FLT_DIG__ 6 // S390X:#define __FLT_DIG__ 6
// S390X:#define __FLT_EPSILON__ 1.19209290e-7F // S390X:#define __FLT_EPSILON__ 1.19209290e-7F
// S390X:#define __FLT_EVAL_METHOD__ 0
// S390X:#define __FLT_HAS_DENORM__ 1 // S390X:#define __FLT_HAS_DENORM__ 1
// S390X:#define __FLT_HAS_INFINITY__ 1 // S390X:#define __FLT_HAS_INFINITY__ 1
// S390X:#define __FLT_HAS_QUIET_NAN__ 1 // S390X:#define __FLT_HAS_QUIET_NAN__ 1

View File

@ -28,7 +28,6 @@
// CHECK: #define __FLT_DENORM_MIN__ 1.40129846e-45F // CHECK: #define __FLT_DENORM_MIN__ 1.40129846e-45F
// CHECK: #define __FLT_DIG__ 6 // CHECK: #define __FLT_DIG__ 6
// CHECK: #define __FLT_EPSILON__ 1.19209290e-7F // CHECK: #define __FLT_EPSILON__ 1.19209290e-7F
// CHECK: #define __FLT_EVAL_METHOD__ 0
// CHECK: #define __FLT_HAS_DENORM__ 1 // CHECK: #define __FLT_HAS_DENORM__ 1
// CHECK: #define __FLT_HAS_INFINITY__ 1 // CHECK: #define __FLT_HAS_INFINITY__ 1
// CHECK: #define __FLT_HAS_QUIET_NAN__ 1 // CHECK: #define __FLT_HAS_QUIET_NAN__ 1

View File

@ -24,7 +24,6 @@
// I386:#define __FLT_DENORM_MIN__ 1.40129846e-45F // I386:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// I386:#define __FLT_DIG__ 6 // I386:#define __FLT_DIG__ 6
// I386:#define __FLT_EPSILON__ 1.19209290e-7F // I386:#define __FLT_EPSILON__ 1.19209290e-7F
// I386:#define __FLT_EVAL_METHOD__ 2
// I386:#define __FLT_HAS_DENORM__ 1 // I386:#define __FLT_HAS_DENORM__ 1
// I386:#define __FLT_HAS_INFINITY__ 1 // I386:#define __FLT_HAS_INFINITY__ 1
// I386:#define __FLT_HAS_QUIET_NAN__ 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_DENORM_MIN__ 1.40129846e-45F
// I386-LINUX:#define __FLT_DIG__ 6 // I386-LINUX:#define __FLT_DIG__ 6
// I386-LINUX:#define __FLT_EPSILON__ 1.19209290e-7F // 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_DENORM__ 1
// I386-LINUX:#define __FLT_HAS_INFINITY__ 1 // I386-LINUX:#define __FLT_HAS_INFINITY__ 1
// I386-LINUX:#define __FLT_HAS_QUIET_NAN__ 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_DENORM_MIN__ 1.40129846e-45F
// I386-NETBSD:#define __FLT_DIG__ 6 // I386-NETBSD:#define __FLT_DIG__ 6
// I386-NETBSD:#define __FLT_EPSILON__ 1.19209290e-7F // 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_DENORM__ 1
// I386-NETBSD:#define __FLT_HAS_INFINITY__ 1 // I386-NETBSD:#define __FLT_HAS_INFINITY__ 1
// I386-NETBSD:#define __FLT_HAS_QUIET_NAN__ 1 // I386-NETBSD:#define __FLT_HAS_QUIET_NAN__ 1
@ -590,13 +587,6 @@
// I386-NETBSD:#define __i386__ 1 // I386-NETBSD:#define __i386__ 1
// 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 -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 -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 // 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_DENORM_MIN__ 1.40129846e-45F
// X86_64:#define __FLT_DIG__ 6 // X86_64:#define __FLT_DIG__ 6
// X86_64:#define __FLT_EPSILON__ 1.19209290e-7F // 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_DENORM__ 1
// X86_64:#define __FLT_HAS_INFINITY__ 1 // X86_64:#define __FLT_HAS_INFINITY__ 1
// X86_64:#define __FLT_HAS_QUIET_NAN__ 1 // X86_64:#define __FLT_HAS_QUIET_NAN__ 1
@ -839,7 +828,6 @@
// X32:#define __FLT_DENORM_MIN__ 1.40129846e-45F // X32:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// X32:#define __FLT_DIG__ 6 // X32:#define __FLT_DIG__ 6
// X32:#define __FLT_EPSILON__ 1.19209290e-7F // X32:#define __FLT_EPSILON__ 1.19209290e-7F
// X32:#define __FLT_EVAL_METHOD__ 0
// X32:#define __FLT_HAS_DENORM__ 1 // X32:#define __FLT_HAS_DENORM__ 1
// X32:#define __FLT_HAS_INFINITY__ 1 // X32:#define __FLT_HAS_INFINITY__ 1
// X32:#define __FLT_HAS_QUIET_NAN__ 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_DENORM_MIN__ 1.40129846e-45F
// X86_64-CLOUDABI:#define __FLT_DIG__ 6 // X86_64-CLOUDABI:#define __FLT_DIG__ 6
// X86_64-CLOUDABI:#define __FLT_EPSILON__ 1.19209290e-7F // 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_DENORM__ 1
// X86_64-CLOUDABI:#define __FLT_HAS_INFINITY__ 1 // X86_64-CLOUDABI:#define __FLT_HAS_INFINITY__ 1
// X86_64-CLOUDABI:#define __FLT_HAS_QUIET_NAN__ 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_DENORM_MIN__ 1.40129846e-45F
// X86_64-LINUX:#define __FLT_DIG__ 6 // X86_64-LINUX:#define __FLT_DIG__ 6
// X86_64-LINUX:#define __FLT_EPSILON__ 1.19209290e-7F // 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_DENORM__ 1
// X86_64-LINUX:#define __FLT_HAS_INFINITY__ 1 // X86_64-LINUX:#define __FLT_HAS_INFINITY__ 1
// X86_64-LINUX:#define __FLT_HAS_QUIET_NAN__ 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_DENORM_MIN__ 1.40129846e-45F
// X86_64-NETBSD:#define __FLT_DIG__ 6 // X86_64-NETBSD:#define __FLT_DIG__ 6
// X86_64-NETBSD:#define __FLT_EPSILON__ 1.19209290e-7F // 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_DENORM__ 1
// X86_64-NETBSD:#define __FLT_HAS_INFINITY__ 1 // X86_64-NETBSD:#define __FLT_HAS_INFINITY__ 1
// X86_64-NETBSD:#define __FLT_HAS_QUIET_NAN__ 1 // X86_64-NETBSD:#define __FLT_HAS_QUIET_NAN__ 1

View File

@ -325,7 +325,6 @@
// MSP430:#define __FLT_DENORM_MIN__ 1.40129846e-45F // MSP430:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// MSP430:#define __FLT_DIG__ 6 // MSP430:#define __FLT_DIG__ 6
// MSP430:#define __FLT_EPSILON__ 1.19209290e-7F // MSP430:#define __FLT_EPSILON__ 1.19209290e-7F
// MSP430:#define __FLT_EVAL_METHOD__ 0
// MSP430:#define __FLT_HAS_DENORM__ 1 // MSP430:#define __FLT_HAS_DENORM__ 1
// MSP430:#define __FLT_HAS_INFINITY__ 1 // MSP430:#define __FLT_HAS_INFINITY__ 1
// MSP430:#define __FLT_HAS_QUIET_NAN__ 1 // MSP430:#define __FLT_HAS_QUIET_NAN__ 1
@ -513,7 +512,6 @@
// NVPTX32:#define __FLT_DENORM_MIN__ 1.40129846e-45F // NVPTX32:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// NVPTX32:#define __FLT_DIG__ 6 // NVPTX32:#define __FLT_DIG__ 6
// NVPTX32:#define __FLT_EPSILON__ 1.19209290e-7F // NVPTX32:#define __FLT_EPSILON__ 1.19209290e-7F
// NVPTX32:#define __FLT_EVAL_METHOD__ 0
// NVPTX32:#define __FLT_HAS_DENORM__ 1 // NVPTX32:#define __FLT_HAS_DENORM__ 1
// NVPTX32:#define __FLT_HAS_INFINITY__ 1 // NVPTX32:#define __FLT_HAS_INFINITY__ 1
// NVPTX32:#define __FLT_HAS_QUIET_NAN__ 1 // NVPTX32:#define __FLT_HAS_QUIET_NAN__ 1
@ -702,7 +700,6 @@
// NVPTX64:#define __FLT_DENORM_MIN__ 1.40129846e-45F // NVPTX64:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// NVPTX64:#define __FLT_DIG__ 6 // NVPTX64:#define __FLT_DIG__ 6
// NVPTX64:#define __FLT_EPSILON__ 1.19209290e-7F // NVPTX64:#define __FLT_EPSILON__ 1.19209290e-7F
// NVPTX64:#define __FLT_EVAL_METHOD__ 0
// NVPTX64:#define __FLT_HAS_DENORM__ 1 // NVPTX64:#define __FLT_HAS_DENORM__ 1
// NVPTX64:#define __FLT_HAS_INFINITY__ 1 // NVPTX64:#define __FLT_HAS_INFINITY__ 1
// NVPTX64:#define __FLT_HAS_QUIET_NAN__ 1 // NVPTX64:#define __FLT_HAS_QUIET_NAN__ 1
@ -906,7 +903,6 @@
// SPARC:#define __FLT_DENORM_MIN__ 1.40129846e-45F // SPARC:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// SPARC:#define __FLT_DIG__ 6 // SPARC:#define __FLT_DIG__ 6
// SPARC:#define __FLT_EPSILON__ 1.19209290e-7F // SPARC:#define __FLT_EPSILON__ 1.19209290e-7F
// SPARC:#define __FLT_EVAL_METHOD__ 0
// SPARC:#define __FLT_HAS_DENORM__ 1 // SPARC:#define __FLT_HAS_DENORM__ 1
// SPARC:#define __FLT_HAS_INFINITY__ 1 // SPARC:#define __FLT_HAS_INFINITY__ 1
// SPARC:#define __FLT_HAS_QUIET_NAN__ 1 // SPARC:#define __FLT_HAS_QUIET_NAN__ 1
@ -1107,7 +1103,6 @@
// TCE:#define __FLT_DENORM_MIN__ 1.40129846e-45F // TCE:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// TCE:#define __FLT_DIG__ 6 // TCE:#define __FLT_DIG__ 6
// TCE:#define __FLT_EPSILON__ 1.19209290e-7F // TCE:#define __FLT_EPSILON__ 1.19209290e-7F
// TCE:#define __FLT_EVAL_METHOD__ 0
// TCE:#define __FLT_HAS_DENORM__ 1 // TCE:#define __FLT_HAS_DENORM__ 1
// TCE:#define __FLT_HAS_INFINITY__ 1 // TCE:#define __FLT_HAS_INFINITY__ 1
// TCE:#define __FLT_HAS_QUIET_NAN__ 1 // TCE:#define __FLT_HAS_QUIET_NAN__ 1
@ -1274,7 +1269,6 @@
// PS4:#define __FLT_DENORM_MIN__ 1.40129846e-45F // PS4:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// PS4:#define __FLT_DIG__ 6 // PS4:#define __FLT_DIG__ 6
// PS4:#define __FLT_EPSILON__ 1.19209290e-7F // PS4:#define __FLT_EPSILON__ 1.19209290e-7F
// PS4:#define __FLT_EVAL_METHOD__ 0
// PS4:#define __FLT_HAS_DENORM__ 1 // PS4:#define __FLT_HAS_DENORM__ 1
// PS4:#define __FLT_HAS_INFINITY__ 1 // PS4:#define __FLT_HAS_INFINITY__ 1
// PS4:#define __FLT_HAS_QUIET_NAN__ 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_DENORM_MIN__ 1.40129846e-45F
// WEBASSEMBLY-NEXT:#define __FLT_DIG__ 6 // WEBASSEMBLY-NEXT:#define __FLT_DIG__ 6
// WEBASSEMBLY-NEXT:#define __FLT_EPSILON__ 1.19209290e-7F // 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_DENORM__ 1
// WEBASSEMBLY-NEXT:#define __FLT_HAS_INFINITY__ 1 // WEBASSEMBLY-NEXT:#define __FLT_HAS_INFINITY__ 1
// WEBASSEMBLY-NEXT:#define __FLT_HAS_QUIET_NAN__ 1 // WEBASSEMBLY-NEXT:#define __FLT_HAS_QUIET_NAN__ 1
@ -1946,7 +1939,6 @@
// AVR:#define __FLT_DENORM_MIN__ 1.40129846e-45F // AVR:#define __FLT_DENORM_MIN__ 1.40129846e-45F
// AVR:#define __FLT_DIG__ 6 // AVR:#define __FLT_DIG__ 6
// AVR:#define __FLT_EPSILON__ 1.19209290e-7F // AVR:#define __FLT_EPSILON__ 1.19209290e-7F
// AVR:#define __FLT_EVAL_METHOD__ 0
// AVR:#define __FLT_HAS_DENORM__ 1 // AVR:#define __FLT_HAS_DENORM__ 1
// AVR:#define __FLT_HAS_INFINITY__ 1 // AVR:#define __FLT_HAS_INFINITY__ 1
// AVR:#define __FLT_HAS_QUIET_NAN__ 1 // AVR:#define __FLT_HAS_QUIET_NAN__ 1
@ -2083,7 +2075,6 @@
// AVR:#define __WCHAR_TYPE__ int // AVR:#define __WCHAR_TYPE__ int
// AVR:#define __WINT_TYPE__ int // AVR:#define __WINT_TYPE__ int
// RUN: %clang_cc1 -E -dM -ffreestanding \ // RUN: %clang_cc1 -E -dM -ffreestanding \
// RUN: -triple i686-windows-msvc -fms-compatibility -x c++ < /dev/null \ // RUN: -triple i686-windows-msvc -fms-compatibility -x c++ < /dev/null \
// RUN: | FileCheck -match-full-lines -check-prefix MSVC-X32 %s // 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_DENORM_MIN__ 1.40129846e-45F
// RISCV32: #define __FLT_DIG__ 6 // RISCV32: #define __FLT_DIG__ 6
// RISCV32: #define __FLT_EPSILON__ 1.19209290e-7F // RISCV32: #define __FLT_EPSILON__ 1.19209290e-7F
// RISCV32: #define __FLT_EVAL_METHOD__ 0
// RISCV32: #define __FLT_HAS_DENORM__ 1 // RISCV32: #define __FLT_HAS_DENORM__ 1
// RISCV32: #define __FLT_HAS_INFINITY__ 1 // RISCV32: #define __FLT_HAS_INFINITY__ 1
// RISCV32: #define __FLT_HAS_QUIET_NAN__ 1 // RISCV32: #define __FLT_HAS_QUIET_NAN__ 1
@ -2437,7 +2427,6 @@
// RISCV64: #define __FLT_DENORM_MIN__ 1.40129846e-45F // RISCV64: #define __FLT_DENORM_MIN__ 1.40129846e-45F
// RISCV64: #define __FLT_DIG__ 6 // RISCV64: #define __FLT_DIG__ 6
// RISCV64: #define __FLT_EPSILON__ 1.19209290e-7F // RISCV64: #define __FLT_EPSILON__ 1.19209290e-7F
// RISCV64: #define __FLT_EVAL_METHOD__ 0
// RISCV64: #define __FLT_HAS_DENORM__ 1 // RISCV64: #define __FLT_HAS_DENORM__ 1
// RISCV64: #define __FLT_HAS_INFINITY__ 1 // RISCV64: #define __FLT_HAS_INFINITY__ 1
// RISCV64: #define __FLT_HAS_QUIET_NAN__ 1 // RISCV64: #define __FLT_HAS_QUIET_NAN__ 1

View File

@ -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@+1{{#pragma entered here}}
#pragma clang fp eval_method(double)
// expected-error@+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@+1{{#pragma entered here}}
#pragma clang fp eval_method(double)
// expected-error@+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@+1{{#pragma entered here}}
#pragma clang fp eval_method(source)
// expected-error@+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@+1{{#pragma entered here}}
#pragma clang fp eval_method(double)
G = x + y + z;
// expected-error@+1{{'__FLT_EVAL_METHOD__' cannot be expanded inside a scope containing '#pragma clang fp eval_method'}}
return __FLT_EVAL_METHOD__;
} else {
// expected-note@+1{{#pragma entered here}}
#pragma clang fp eval_method(extended)
G = x + y + z;
// expected-error@+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@+1{{#pragma entered here}}
#pragma clang fp eval_method(double)
// expected-error@+1{{'__FLT_EVAL_METHOD__' cannot be expanded inside a scope containing '#pragma clang fp eval_method'}}
#if __FLT_EVAL_METHOD__ == 1
#endif

View File

@ -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 the floating point evaluation method to `source` on a target without 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 the floating point evaluation method to `source` on a target without SSE is not supported.}}

View File

@ -0,0 +1,13 @@
// RUN: %clang_cc1 -fexperimental-strict-floating-point \
// RUN: -triple x86_64-linux-gnu -target-feature -sse -emit-llvm \
// RUN: -o - -verify=warn %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;
} // warn-warning{{Setting the floating point evaluation method to `source` on a target without SSE is not supported.}}