forked from OSchip/llvm-project
Add support for floating-point option `ffp-eval-method` and for
`pragma clang fp eval_method`. https://reviews.llvm.org/D109239
This commit is contained in:
parent
7adb85884b
commit
32b73bc6ab
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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">;
|
||||
|
|
|
@ -1267,6 +1267,9 @@ def err_pragma_attribute_namespace_on_attribute : Error<
|
|||
def note_pragma_attribute_namespace_on_attribute : Note<
|
||||
"omit the namespace to add attributes to the most-recently"
|
||||
" 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])
|
||||
def warn_pragma_expected_colon : Warning<
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -235,6 +235,24 @@ public:
|
|||
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 };
|
||||
|
||||
|
|
|
@ -726,7 +726,11 @@ public:
|
|||
}
|
||||
|
||||
/// 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.
|
||||
|
|
|
@ -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]>,
|
||||
|
|
|
@ -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 @@ public:
|
|||
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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1541,19 +1541,16 @@ public:
|
|||
/// 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 @@ public:
|
|||
!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);
|
||||
|
|
|
@ -749,7 +749,9 @@ public:
|
|||
}
|
||||
|
||||
// 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; }
|
||||
};
|
||||
|
|
|
@ -168,11 +168,15 @@ public:
|
|||
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 @@ public:
|
|||
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;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -2726,6 +2726,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 =
|
||||
|
@ -2921,6 +2923,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;
|
||||
|
@ -3076,6 +3090,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
|
||||
|
|
|
@ -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__");
|
||||
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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__;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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.}}
|
|
@ -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.}}
|
Loading…
Reference in New Issue