From: Melanie Blower Date: Fri, 1 May 2020 17:31:09 +0000 (-0700) Subject: Revert "Reapply "Add support for #pragma float_control" with improvements to" X-Git-Tag: llvmorg-12-init~7212 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fce82c0ed310174fe48e2402ac731b6340098389;p=platform%2Fupstream%2Fllvm.git Revert "Reapply "Add support for #pragma float_control" with improvements to" This reverts commit 69aacaf699922ffe0450f567e21208c10c84731f. --- diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 1c753ea..11114e8 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -3197,41 +3197,6 @@ The pragma can also be used with ``off`` which turns FP contraction off for a section of the code. This can be useful when fast contraction is otherwise enabled for the translation unit with the ``-ffp-contract=fast`` flag. -The ``#pragma float_control`` pragma allows precise floating-point -semantics and floating-point exception behavior to be specified -for a section of the source code. This pragma can only appear at file scope or -at the start of a compound statement (excluding comments). When using within a -compound statement, the pragma is active within the scope of the compound -statement. This pragma is modeled after a Microsoft pragma with the -same spelling and syntax. For pragmas specified at file scope, a stack -is supported so that the ``pragma float_control`` settings can be pushed or popped. - -When ``pragma float_control(precise, on)`` is enabled, the section of code -governed by the pragma uses precise floating point semantics, effectively -``-ffast-math`` is disabled and ``-ffp-contract=on`` -(fused multiply add) is enabled. - -When ``pragma float_control(except, on)`` is enabled, the section of code governed -by the pragma behaves as though the command-line option -``-ffp-exception-behavior=strict`` is enabled, -when ``pragma float_control(precise, off)`` is enabled, the section of code -governed by the pragma behaves as though the command-line option -``-ffp-exception-behavior=ignore`` is enabled. - -The full syntax this pragma supports is -``float_control(except|precise, on|off [, push])`` and -``float_control(push|pop)``. -The ``push`` and ``pop`` forms, including using ``push`` as the optional -third argument, can only occur at file scope. - -.. code-block:: c++ - - for(...) { - // This block will be compiled with -fno-fast-math and -ffp-contract=on - #pragma float_control(precise, on) - a = b[i] * c[i] + e; - } - Specifying an attribute for multiple declarations (#pragma clang attribute) =========================================================================== diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 6c83bc6..4d89234 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -2107,48 +2107,26 @@ public: /// applied to a non-complex value, the former returns its operand and the /// later returns zero in the type of the operand. /// -class UnaryOperator final - : public Expr, - private llvm::TrailingObjects { +class UnaryOperator : public Expr { Stmt *Val; - size_t numTrailingObjects(OverloadToken) const { - return UnaryOperatorBits.HasFPFeatures ? 1 : 0; - } - - FPOptions &getTrailingFPFeatures() { - assert(UnaryOperatorBits.HasFPFeatures); - return *getTrailingObjects(); - } - - const FPOptions &getTrailingFPFeatures() const { - assert(UnaryOperatorBits.HasFPFeatures); - return *getTrailingObjects(); - } - public: typedef UnaryOperatorKind Opcode; -protected: - UnaryOperator(const ASTContext &Ctx, Expr *input, Opcode opc, QualType type, - ExprValueKind VK, ExprObjectKind OK, SourceLocation l, - bool CanOverflow, FPOptions FPFeatures); + UnaryOperator(Expr *input, Opcode opc, QualType type, ExprValueKind VK, + ExprObjectKind OK, SourceLocation l, bool CanOverflow) + : Expr(UnaryOperatorClass, type, VK, OK), Val(input) { + UnaryOperatorBits.Opc = opc; + UnaryOperatorBits.CanOverflow = CanOverflow; + UnaryOperatorBits.Loc = l; + setDependence(computeDependence(this)); + } /// Build an empty unary operator. - explicit UnaryOperator(bool HasFPFeatures, EmptyShell Empty) - : Expr(UnaryOperatorClass, Empty) { + explicit UnaryOperator(EmptyShell Empty) : Expr(UnaryOperatorClass, Empty) { UnaryOperatorBits.Opc = UO_AddrOf; - UnaryOperatorBits.HasFPFeatures = HasFPFeatures; } -public: - static UnaryOperator *CreateEmpty(const ASTContext &C, bool hasFPFeatures); - - static UnaryOperator *Create(const ASTContext &C, Expr *input, Opcode opc, - QualType type, ExprValueKind VK, - ExprObjectKind OK, SourceLocation l, - bool CanOverflow, FPOptions FPFeatures); - Opcode getOpcode() const { return static_cast(UnaryOperatorBits.Opc); } @@ -2170,18 +2148,6 @@ public: bool canOverflow() const { return UnaryOperatorBits.CanOverflow; } void setCanOverflow(bool C) { UnaryOperatorBits.CanOverflow = C; } - // Get the FP contractability status of this operator. Only meaningful for - // operations on floating point types. - bool isFPContractableWithinStatement(const LangOptions &LO) const { - return getFPFeatures(LO).allowFPContractWithinStatement(); - } - - // Get the FENV_ACCESS status of this operator. Only meaningful for - // operations on floating point types. - bool isFEnvAccessOn(const LangOptions &LO) const { - return getFPFeatures(LO).allowFEnvAccess(); - } - /// isPostfix - Return true if this is a postfix operation, like x++. static bool isPostfix(Opcode Op) { return Op == UO_PostInc || Op == UO_PostDec; @@ -2248,30 +2214,6 @@ public: const_child_range children() const { return const_child_range(&Val, &Val + 1); } - - /// Is FPFeatures in Trailing Storage? - bool hasStoredFPFeatures() const { return UnaryOperatorBits.HasFPFeatures; } - -protected: - /// Get FPFeatures from trailing storage - FPOptions getStoredFPFeatures() const { return getTrailingFPFeatures(); } - - /// Set FPFeatures in trailing storage, used only by Serialization - void setStoredFPFeatures(FPOptions F) { getTrailingFPFeatures() = F; } - -public: - // Get the FP features status of this operator. Only meaningful for - // operations on floating point types. - FPOptions getFPFeatures(const LangOptions &LO) const { - if (UnaryOperatorBits.HasFPFeatures) - return getStoredFPFeatures(); - return FPOptions::defaultWithoutTrailingStorage(LO); - } - - friend TrailingObjects; - friend class ASTReader; - friend class ASTStmtReader; - friend class ASTStmtWriter; }; /// Helper class for OffsetOfExpr. diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 5db3ad3..58c0329 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -427,11 +427,6 @@ protected: unsigned Opc : 5; unsigned CanOverflow : 1; - // - /// This is only meaningful for operations on floating point - /// types when additional values need to be in trailing storage. - /// It is 0 otherwise. - unsigned HasFPFeatures : 1; SourceLocation Loc; }; @@ -615,7 +610,7 @@ protected: unsigned OperatorKind : 6; // Only meaningful for floating point types. - unsigned FPFeatures : 14; + unsigned FPFeatures : 8; }; class CXXRewrittenBinaryOperatorBitfields { diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 9400a87..337614c 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1097,9 +1097,9 @@ def warn_pragma_init_seg_unsupported_target : Warning< "'#pragma init_seg' is only supported when targeting a " "Microsoft environment">, InGroup; -// - #pragma restricted to file scope or start of compound statement -def err_pragma_file_or_compound_scope : Error< - "'#pragma %0' can only appear at file scope or at the start of a " +// - #pragma fp_contract +def err_pragma_fp_contract_scope : Error< + "'#pragma fp_contract' can only appear at file scope or at the start of a " "compound statement">; // - #pragma stdc unknown def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">, @@ -1118,10 +1118,6 @@ def warn_pragma_comment_ignored : Warning<"'#pragma comment %0' ignored">, def err_pragma_detect_mismatch_malformed : Error< "pragma detect_mismatch is malformed; it requires two comma-separated " "string literals">; -// - #pragma float_control -def err_pragma_float_control_malformed : Error< - "pragma float_control is malformed; use 'float_control({push|pop})' or " - "'float_control({precise|except}, {on|off} [,push])'">; // - #pragma pointers_to_members def err_pragma_pointers_to_members_unknown_kind : Error< "unexpected %0, expected to see one of %select{|'best_case', 'full_generality', }1" @@ -1336,6 +1332,9 @@ def err_pragma_fp_invalid_option : Error< def err_pragma_fp_invalid_argument : Error< "unexpected argument '%0' to '#pragma clang fp %1'; " "expected 'on', 'fast' or 'off'">; +def err_pragma_fp_scope : Error< + "'#pragma clang fp' can only appear at file scope or at the start of a " + "compound statement">; def err_pragma_invalid_keyword : Error< "invalid argument; expected 'enable'%select{|, 'full'}0%select{|, 'assume_safety'}1 or 'disable'">; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index ac53ad6..154da86 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -858,16 +858,6 @@ def warn_pragma_pack_pop_identifier_and_alignment : Warning< "specifying both a name and alignment to 'pop' is undefined">; def warn_pragma_pop_failed : Warning<"#pragma %0(pop, ...) failed: %1">, InGroup; -def err_pragma_fc_pp_scope : Error< - "'#pragma float_control push/pop' can only appear at file scope">; -def err_pragma_fc_noprecise_requires_nofenv : Error< - "'#pragma float_control(precise, off)' is illegal when fenv_access is enabled">; -def err_pragma_fc_except_requires_precise : Error< - "'#pragma float_control(except, on)' is illegal when precise is disabled">; -def err_pragma_fc_noprecise_requires_noexcept : Error< - "'#pragma float_control(precise, off)' is illegal when except is enabled">; -def err_pragma_fenv_requires_precise : Error< - "'#pragma STDC FENV_ACCESS ON' is illegal when precise is disabled">; def warn_cxx_ms_struct : Warning<"ms_struct may not produce Microsoft-compatible layouts for classes " "with base classes or virtual functions">, diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 289f9c3..1464aac 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -191,12 +191,6 @@ COMPATIBLE_LANGOPT(Deprecated , 1, 0, "__DEPRECATED predefined macro") COMPATIBLE_LANGOPT(FastMath , 1, 0, "fast FP math optimizations, and __FAST_MATH__ predefined macro") COMPATIBLE_LANGOPT(FiniteMathOnly , 1, 0, "__FINITE_MATH_ONLY__ predefined macro") COMPATIBLE_LANGOPT(UnsafeFPMath , 1, 0, "Unsafe Floating Point Math") -COMPATIBLE_LANGOPT(AllowFPReassoc , 1, 0, "Permit Floating Point reassociation") -COMPATIBLE_LANGOPT(NoHonorNaNs , 1, 0, "Permit Floating Point optimization without regard to NaN") -COMPATIBLE_LANGOPT(NoHonorInfs , 1, 0, "Permit Floating Point optimization without regard to infinities") -COMPATIBLE_LANGOPT(NoSignedZero , 1, 0, "Permit Floating Point optimization without regard to signed zeros") -COMPATIBLE_LANGOPT(AllowRecip , 1, 0, "Permit Floating Point reciprocal") -COMPATIBLE_LANGOPT(ApproxFunc , 1, 0, "Permit Floating Point approximation") BENIGN_LANGOPT(ObjCGCBitmapPrint , 1, 0, "printing of GC's bitmap layout for __weak/__strong ivars") diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 61b4b87..76ddd70 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -304,8 +304,6 @@ public: /// input is a header file (i.e. -x c-header). bool IsHeaderFile = false; - bool denormalIsIEEE = false; - LangOptions(); // Define accessors/mutators for language options of enumeration type. @@ -379,33 +377,28 @@ class FPOptions { using RoundingMode = llvm::RoundingMode; public: - FPOptions() - : fp_contract(LangOptions::FPC_Off), fenv_access(LangOptions::FEA_Off), - rounding(LangOptions::FPR_ToNearest), - exceptions(LangOptions::FPE_Ignore), allow_reassoc(0), no_nans(0), - no_infs(0), no_signed_zeros(0), allow_reciprocal(0), approx_func(0) {} + FPOptions() : fp_contract(LangOptions::FPC_Off), + fenv_access(LangOptions::FEA_Off), + rounding(LangOptions::FPR_ToNearest), + exceptions(LangOptions::FPE_Ignore) + {} // Used for serializing. - explicit FPOptions(unsigned I) { getFromOpaqueInt(I); } + explicit FPOptions(unsigned I) + : fp_contract(I & 3), + fenv_access((I >> 2) & 1), + rounding ((I >> 3) & 7), + exceptions ((I >> 6) & 3) + {} explicit FPOptions(const LangOptions &LangOpts) : fp_contract(LangOpts.getDefaultFPContractMode()), fenv_access(LangOptions::FEA_Off), - rounding(static_cast(LangOpts.getFPRoundingMode())), - exceptions(LangOpts.getFPExceptionMode()), - allow_reassoc(LangOpts.FastMath || LangOpts.AllowFPReassoc), - no_nans(LangOpts.FastMath || LangOpts.NoHonorNaNs), - no_infs(LangOpts.FastMath || LangOpts.NoHonorInfs), - no_signed_zeros(LangOpts.FastMath || LangOpts.NoSignedZero), - allow_reciprocal(LangOpts.FastMath || LangOpts.AllowRecip), - approx_func(LangOpts.FastMath || LangOpts.ApproxFunc) {} + rounding(LangOptions::FPR_ToNearest), + exceptions(LangOptions::FPE_Ignore) + {} // FIXME: Use getDefaultFEnvAccessMode() when available. - void setFastMath(bool B = true) { - allow_reassoc = no_nans = no_infs = no_signed_zeros = approx_func = - allow_reciprocal = B; - } - /// Return the default value of FPOptions that's used when trailing /// storage isn't required. static FPOptions defaultWithoutTrailingStorage(const LangOptions &LO); @@ -440,18 +433,6 @@ public: fenv_access = LangOptions::FEA_On; } - void setFPPreciseEnabled(bool Value) { - if (Value) { - /* Precise mode implies fp_contract=on and disables ffast-math */ - setFastMath(false); - setAllowFPContractWithinStatement(); - } else { - /* Precise mode implies fp_contract=fast and enables ffast-math */ - setFastMath(true); - setAllowFPContractAcrossStatement(); - } - } - void setDisallowFEnvAccess() { fenv_access = LangOptions::FEA_Off; } RoundingMode getRoundingMode() const { @@ -470,22 +451,6 @@ public: exceptions = EM; } - /// FMF Flag queries - bool allowAssociativeMath() const { return allow_reassoc; } - bool noHonorNaNs() const { return no_nans; } - bool noHonorInfs() const { return no_infs; } - bool noSignedZeros() const { return no_signed_zeros; } - bool allowReciprocalMath() const { return allow_reciprocal; } - bool allowApproximateFunctions() const { return approx_func; } - - /// Flag setters - void setAllowAssociativeMath(bool B = true) { allow_reassoc = B; } - void setNoHonorNaNs(bool B = true) { no_nans = B; } - void setNoHonorInfs(bool B = true) { no_infs = B; } - void setNoSignedZeros(bool B = true) { no_signed_zeros = B; } - void setAllowReciprocalMath(bool B = true) { allow_reciprocal = B; } - void setAllowApproximateFunctions(bool B = true) { approx_func = B; } - bool isFPConstrained() const { return getRoundingMode() != RoundingMode::NearestTiesToEven || getExceptionMode() != LangOptions::FPE_Ignore || @@ -495,23 +460,7 @@ public: /// Used to serialize this. unsigned getAsOpaqueInt() const { return fp_contract | (fenv_access << 2) | (rounding << 3) | - (exceptions << 6) | (allow_reassoc << 8) | (no_nans << 9) | - (no_infs << 10) | (no_signed_zeros << 11) | - (allow_reciprocal << 12) | (approx_func << 13); - } - - /// Used with getAsOpaqueInt() to manage the float_control pragma stack. - void getFromOpaqueInt(unsigned I) { - fp_contract = (static_cast(I & 3)); - fenv_access = (static_cast((I >> 2) & 1)); - rounding = static_cast(static_cast((I >> 3) & 7)); - exceptions = (static_cast((I >> 6) & 3)); - allow_reassoc = ((I >> 8) & 1); - no_nans = ((I >> 9) & 1); - no_infs = ((I >> 10) & 1); - no_signed_zeros = ((I >> 11) & 1); - allow_reciprocal = ((I >> 12) & 1); - approx_func = ((I >> 13) & 1); + (exceptions << 6); } private: @@ -522,25 +471,6 @@ private: unsigned fenv_access : 1; unsigned rounding : 3; unsigned exceptions : 2; - /// Allow reassociation transformations for floating-point instructions. - unsigned allow_reassoc : 1; - /// No NaNs - Allow optimizations to assume the arguments and result - /// are not NaN. If an argument is a nan, or the result would be a nan, - /// it produces a :ref:`poison value ` instead. - unsigned no_nans : 1; - /// No Infs - Allow optimizations to assume the arguments and result - /// are not +/-Inf. If an argument is +/-Inf, or the result would be +/-Inf, - /// it produces a :ref:`poison value ` instead. - unsigned no_infs : 1; - /// No Signed Zeros - Allow optimizations to treat the sign of a zero - /// argument or result as insignificant. - unsigned no_signed_zeros : 1; - /// Allow Reciprocal - Allow optimizations to use the reciprocal - /// of an argument rather than perform division. - unsigned allow_reciprocal : 1; - /// Approximate functions - Allow substitution of approximate calculations - /// for functions (sin, log, sqrt, etc). - unsigned approx_func : 1; }; /// Describes the kind of translation unit being processed. diff --git a/clang/include/clang/Basic/PragmaKinds.h b/clang/include/clang/Basic/PragmaKinds.h index 82c0d5f..103b97d 100644 --- a/clang/include/clang/Basic/PragmaKinds.h +++ b/clang/include/clang/Basic/PragmaKinds.h @@ -25,15 +25,6 @@ enum PragmaMSStructKind { PMSST_ON // #pragms ms_struct on }; -enum PragmaFloatControlKind { - PFC_Unknown, - PFC_Precise, // #pragma float_control(precise, [,on]) - PFC_NoPrecise, // #pragma float_control(precise, off) - PFC_Except, // #pragma float_control(except [,on]) - PFC_NoExcept, // #pragma float_control(except, off) - PFC_Push, // #pragma float_control(push) - PFC_Pop // #pragma float_control(pop) -}; } #endif diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 6ca5f0e30..0705896 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -809,11 +809,6 @@ PRAGMA_ANNOTATION(pragma_fp_contract) // handles them. PRAGMA_ANNOTATION(pragma_fenv_access) -// Annotation for #pragma float_control -// The lexer produces these so that they only take effect when the parser -// handles them. -PRAGMA_ANNOTATION(pragma_float_control) - // Annotation for #pragma pointers_to_members... // The lexer produces these so that they only take effect when the parser // handles them. diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 4a8acf5..d864299 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -182,7 +182,6 @@ class Parser : public CodeCompletionHandler { std::unique_ptr PCSectionHandler; std::unique_ptr MSCommentHandler; std::unique_ptr MSDetectMismatchHandler; - std::unique_ptr FloatControlHandler; std::unique_ptr MSPointersToMembers; std::unique_ptr MSVtorDisp; std::unique_ptr MSInitSeg; @@ -742,10 +741,6 @@ private: /// #pragma STDC FENV_ACCESS... void HandlePragmaFEnvAccess(); - /// Handle the annotation token produced for - /// #pragma float_control - void HandlePragmaFloatControl(); - /// \brief Handle the annotation token produced for /// #pragma clang fp ... void HandlePragmaFP(); diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 394a783..0c1241f 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -555,9 +555,6 @@ public: PragmaStack ConstSegStack; PragmaStack CodeSegStack; - // This stack tracks the current state of Sema.CurFPFeatures. - PragmaStack FpPragmaStack; - // RAII object to push / pop sentinel slots for all MS #pragma stacks. // Actions should be performed only if we enter / exit a C++ method body. class PragmaStackSentinelRAII { @@ -1353,7 +1350,7 @@ public: /// should not be used elsewhere. void EmitCurrentDiagnostic(unsigned DiagID); - /// Records and restores the CurFPFeatures state on entry/exit of compound + /// Records and restores the FPFeatures state on entry/exit of compound /// statements. class FPFeaturesStateRAII { public: @@ -9569,18 +9566,6 @@ public: void ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name, StringRef Value); - /// Are precise floating point semantics currently enabled? - bool isPreciseFPEnabled() { - return LangOpts.denormalIsIEEE && !CurFPFeatures.allowAssociativeMath() && - !CurFPFeatures.noSignedZeros() && - !CurFPFeatures.allowReciprocalMath() && - !CurFPFeatures.allowApproximateFunctions(); - } - - /// ActOnPragmaFloatControl - Call on well-formed \#pragma float_control - void ActOnPragmaFloatControl(SourceLocation Loc, PragmaMsStackAction Action, - PragmaFloatControlKind Value); - /// ActOnPragmaUnused - Called on well-formed '\#pragma unused'. void ActOnPragmaUnused(const Token &Identifier, Scope *curScope, @@ -9621,8 +9606,7 @@ public: /// ActOnPragmaFenvAccess - Called on well formed /// \#pragma STDC FENV_ACCESS - void ActOnPragmaFEnvAccess(SourceLocation Loc, - LangOptions::FEnvAccessModeKind FPC); + void ActOnPragmaFEnvAccess(LangOptions::FEnvAccessModeKind FPC); /// Called to set rounding mode for floating point operations. void setRoundingMode(llvm::RoundingMode); diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 14d052a..d5a27f4 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -686,9 +686,6 @@ namespace serialization { /// Record code for the Decls to be checked for deferred diags. DECLS_TO_CHECK_FOR_DEFERRED_DIAGS = 64, - - /// Record code for \#pragma float_control options. - FLOAT_CONTROL_PRAGMA_OPTIONS = 65, }; /// Record types used within a source manager block. diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index beaacef..11a537f 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -857,18 +857,6 @@ private: int PragmaMSPointersToMembersState = -1; SourceLocation PointersToMembersPragmaLocation; - /// The pragma float_control state. - Optional FpPragmaCurrentValue; - SourceLocation FpPragmaCurrentLocation; - struct FpPragmaStackEntry { - unsigned Value; - SourceLocation Location; - SourceLocation PushLocation; - StringRef SlotLabel; - }; - llvm::SmallVector FpPragmaStack; - llvm::SmallVector FpPragmaStrings; - /// The pragma pack state. Optional PragmaPackCurrentValue; SourceLocation PragmaPackCurrentLocation; diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index 398fa40..bc5a782 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -505,7 +505,6 @@ private: void WriteMSStructPragmaOptions(Sema &SemaRef); void WriteMSPointersToMembersPragmaOptions(Sema &SemaRef); void WritePackPragmaOptions(Sema &SemaRef); - void WriteFloatControlPragmaOptions(Sema &SemaRef); void WriteModuleFileExtension(Sema &SemaRef, ModuleFileExtensionWriter &Writer); diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 1003516..477c035 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -6660,10 +6660,9 @@ ExpectedStmt ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) { if (Err) return std::move(Err); - return UnaryOperator::Create( - Importer.getToContext(), ToSubExpr, E->getOpcode(), ToType, - E->getValueKind(), E->getObjectKind(), ToOperatorLoc, E->canOverflow(), - E->getFPFeatures(Importer.getFromContext().getLangOpts())); + return new (Importer.getToContext()) UnaryOperator( + ToSubExpr, E->getOpcode(), ToType, E->getValueKind(), E->getObjectKind(), + ToOperatorLoc, E->canOverflow()); } ExpectedStmt diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 36083d3..bb27f40 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1358,8 +1358,7 @@ CallExpr *CallExpr::CreateTemporary(void *Mem, Expr *Fn, QualType Ty, assert(!(reinterpret_cast(Mem) % alignof(CallExpr)) && "Misaligned memory in CallExpr::CreateTemporary!"); return new (Mem) CallExpr(CallExprClass, Fn, /*PreArgs=*/{}, /*Args=*/{}, Ty, - VK, RParenLoc, - /*MinNumArgs=*/0, UsesADL); + VK, RParenLoc, /*MinNumArgs=*/0, UsesADL); } CallExpr *CallExpr::CreateEmpty(const ASTContext &Ctx, unsigned NumArgs, @@ -4446,38 +4445,6 @@ CompoundAssignOperator *CompoundAssignOperator::Create( CompLHSType, CompResultType); } -UnaryOperator *UnaryOperator::CreateEmpty(const ASTContext &C, - bool hasFPFeatures) { - void *Mem = C.Allocate(totalSizeToAlloc(hasFPFeatures), - alignof(UnaryOperator)); - return new (Mem) UnaryOperator(hasFPFeatures, EmptyShell()); -} - -UnaryOperator::UnaryOperator(const ASTContext &Ctx, Expr *input, Opcode opc, - QualType type, ExprValueKind VK, ExprObjectKind OK, - SourceLocation l, bool CanOverflow, - FPOptions FPFeatures) - : Expr(UnaryOperatorClass, type, VK, OK), Val(input) { - UnaryOperatorBits.Opc = opc; - UnaryOperatorBits.CanOverflow = CanOverflow; - UnaryOperatorBits.Loc = l; - UnaryOperatorBits.HasFPFeatures = - FPFeatures.requiresTrailingStorage(Ctx.getLangOpts()); - setDependence(computeDependence(this)); -} - -UnaryOperator *UnaryOperator::Create(const ASTContext &C, Expr *input, - Opcode opc, QualType type, - ExprValueKind VK, ExprObjectKind OK, - SourceLocation l, bool CanOverflow, - FPOptions FPFeatures) { - bool HasFPFeatures = FPFeatures.requiresTrailingStorage(C.getLangOpts()); - unsigned Size = totalSizeToAlloc(HasFPFeatures); - void *Mem = C.Allocate(Size, alignof(UnaryOperator)); - return new (Mem) - UnaryOperator(C, input, opc, type, VK, OK, l, CanOverflow, FPFeatures); -} - const OpaqueValueExpr *OpaqueValueExpr::findInCopyConstruct(const Expr *e) { if (const ExprWithCleanups *ewc = dyn_cast(e)) e = ewc->getSubExpr(); diff --git a/clang/lib/Analysis/BodyFarm.cpp b/clang/lib/Analysis/BodyFarm.cpp index e10fbce..8529546 100644 --- a/clang/lib/Analysis/BodyFarm.cpp +++ b/clang/lib/Analysis/BodyFarm.cpp @@ -146,10 +146,9 @@ DeclRefExpr *ASTMaker::makeDeclRefExpr( } UnaryOperator *ASTMaker::makeDereference(const Expr *Arg, QualType Ty) { - return UnaryOperator::Create(C, const_cast(Arg), UO_Deref, Ty, + return new (C) UnaryOperator(const_cast(Arg), UO_Deref, Ty, VK_LValue, OK_Ordinary, SourceLocation(), - /*CanOverflow*/ false, - FPOptions(C.getLangOpts())); + /*CanOverflow*/ false); } ImplicitCastExpr *ASTMaker::makeLvalueToRvalue(const Expr *Arg, QualType Ty) { @@ -448,16 +447,15 @@ static Stmt *create_call_once(ASTContext &C, const FunctionDecl *D) { QualType DerefType = Deref->getType(); // Negation predicate. - UnaryOperator *FlagCheck = UnaryOperator::Create( - C, + UnaryOperator *FlagCheck = new (C) UnaryOperator( /* input=*/ M.makeImplicitCast(M.makeLvalueToRvalue(Deref, DerefType), DerefType, CK_IntegralToBoolean), - /* opc=*/UO_LNot, - /* QualType=*/C.IntTy, - /* ExprValueKind=*/VK_RValue, - /* ExprObjectKind=*/OK_Ordinary, SourceLocation(), - /* CanOverflow*/ false, FPOptions(C.getLangOpts())); + /* opc=*/ UO_LNot, + /* QualType=*/ C.IntTy, + /* ExprValueKind=*/ VK_RValue, + /* ExprObjectKind=*/ OK_Ordinary, SourceLocation(), + /* CanOverflow*/ false); // Create assignment. BinaryOperator *FlagAssignment = M.makeAssignment( @@ -520,9 +518,9 @@ static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) { // (2) Create the assignment to the predicate. Expr *DoneValue = - UnaryOperator::Create(C, M.makeIntegerLiteral(0, C.LongTy), UO_Not, - C.LongTy, VK_RValue, OK_Ordinary, SourceLocation(), - /*CanOverflow*/ false, FPOptions(C.getLangOpts())); + new (C) UnaryOperator(M.makeIntegerLiteral(0, C.LongTy), UO_Not, C.LongTy, + VK_RValue, OK_Ordinary, SourceLocation(), + /*CanOverflow*/false); BinaryOperator *B = M.makeAssignment( diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 76f58b2..c3f2352 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -217,14 +217,7 @@ static bool CanElideOverflowCheck(const ASTContext &Ctx, const BinOpInfo &Op) { /// Update the FastMathFlags of LLVM IR from the FPOptions in LangOptions. static void updateFastMathFlags(llvm::FastMathFlags &FMF, FPOptions FPFeatures) { - FMF.setAllowReassoc(FPFeatures.allowAssociativeMath()); - FMF.setNoNaNs(FPFeatures.noHonorNaNs()); - FMF.setNoInfs(FPFeatures.noHonorInfs()); - FMF.setNoSignedZeros(FPFeatures.noSignedZeros()); - FMF.setAllowReciprocal(FPFeatures.allowReciprocalMath()); - FMF.setApproxFunc(FPFeatures.allowApproximateFunctions()); - FMF.setAllowContract(FPFeatures.allowFPContractAcrossStatement() || - FPFeatures.allowFPContractWithinStatement()); + FMF.setAllowContract(FPFeatures.allowFPContractAcrossStatement()); } /// Propagate fast-math flags from \p Op to the instruction in \p V. @@ -237,25 +230,6 @@ static Value *propagateFMFlags(Value *V, const BinOpInfo &Op) { return V; } -static void setBuilderFlagsFromFPFeatures(CGBuilderTy &Builder, - CodeGenFunction &CGF, - FPOptions FPFeatures) { - auto NewRoundingBehavior = FPFeatures.getRoundingMode(); - Builder.setDefaultConstrainedRounding(NewRoundingBehavior); - auto NewExceptionBehavior = - ToConstrainedExceptMD(FPFeatures.getExceptionMode()); - Builder.setDefaultConstrainedExcept(NewExceptionBehavior); - auto FMF = Builder.getFastMathFlags(); - updateFastMathFlags(FMF, FPFeatures); - Builder.setFastMathFlags(FMF); - assert((CGF.CurFuncDecl == nullptr || Builder.getIsFPConstrained() || - isa(CGF.CurFuncDecl) || - isa(CGF.CurFuncDecl) || - (NewExceptionBehavior == llvm::fp::ebIgnore && - NewRoundingBehavior == llvm::RoundingMode::NearestTiesToEven)) && - "FPConstrained should be enabled on entire function"); -} - class ScalarExprEmitter : public StmtVisitor { CodeGenFunction &CGF; @@ -770,9 +744,6 @@ public: return EmitOverflowCheckedBinOp(Ops); if (Ops.LHS->getType()->isFPOrFPVectorTy()) { - // Preserve the old values - llvm::IRBuilder<>::FastMathFlagGuard FMFG(Builder); - setBuilderFlagsFromFPFeatures(Builder, CGF, Ops.FPFeatures); Value *V = Builder.CreateFMul(Ops.LHS, Ops.RHS, "mul"); return propagateFMFlags(V, Ops); } @@ -2362,14 +2333,13 @@ Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) { //===----------------------------------------------------------------------===// static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E, - llvm::Value *InVal, bool IsInc, - FPOptions FPFeatures) { + llvm::Value *InVal, bool IsInc) { BinOpInfo BinOp; BinOp.LHS = InVal; BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1, false); BinOp.Ty = E->getType(); BinOp.Opcode = IsInc ? BO_Add : BO_Sub; - BinOp.FPFeatures = FPFeatures; + // FIXME: once UnaryOperator carries FPFeatures, copy it here. BinOp.E = E; return BinOp; } @@ -2389,8 +2359,7 @@ llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior( case LangOptions::SOB_Trapping: if (!E->canOverflow()) return Builder.CreateNSWAdd(InVal, Amount, Name); - return EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec( - E, InVal, IsInc, E->getFPFeatures(CGF.getLangOpts()))); + return EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(E, InVal, IsInc)); } llvm_unreachable("Unknown SignedOverflowBehaviorTy"); } @@ -2536,8 +2505,8 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, value = EmitIncDecConsiderOverflowBehavior(E, value, isInc); } else if (E->canOverflow() && type->isUnsignedIntegerType() && CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow)) { - value = EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec( - E, value, isInc, E->getFPFeatures(CGF.getLangOpts()))); + value = + EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(E, value, isInc)); } else { llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount, true); value = Builder.CreateAdd(value, amt, isInc ? "inc" : "dec"); @@ -2737,7 +2706,7 @@ Value *ScalarExprEmitter::VisitUnaryMinus(const UnaryOperator *E) { BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType()); BinOp.Ty = E->getType(); BinOp.Opcode = BO_Sub; - BinOp.FPFeatures = E->getFPFeatures(CGF.getLangOpts()); + // FIXME: once UnaryOperator carries FPFeatures, copy it here. BinOp.E = E; return EmitSub(BinOp); } @@ -2754,12 +2723,9 @@ Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) { Value *Oper = Visit(E->getSubExpr()); Value *Zero = llvm::Constant::getNullValue(Oper->getType()); Value *Result; - if (Oper->getType()->isFPOrFPVectorTy()) { - llvm::IRBuilder<>::FastMathFlagGuard FMFG(Builder); - setBuilderFlagsFromFPFeatures(Builder, CGF, - E->getFPFeatures(CGF.getLangOpts())); + if (Oper->getType()->isFPOrFPVectorTy()) Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper, Zero, "cmp"); - } else + else Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper, Zero, "cmp"); return Builder.CreateSExt(Result, ConvertType(E->getType()), "sext"); } @@ -3168,10 +3134,7 @@ Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) { } if (Ops.LHS->getType()->isFPOrFPVectorTy()) { - llvm::Value *Val; - llvm::IRBuilder<>::FastMathFlagGuard FMFG(Builder); - setBuilderFlagsFromFPFeatures(Builder, CGF, Ops.FPFeatures); - Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div"); + llvm::Value *Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div"); if (CGF.getLangOpts().OpenCL && !CGF.CGM.getCodeGenOpts().CorrectlyRoundedDivSqrt) { // OpenCL v1.1 s7.4: minimum accuracy of single precision / is 2.5ulp @@ -3543,8 +3506,6 @@ Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &op) { return EmitOverflowCheckedBinOp(op); if (op.LHS->getType()->isFPOrFPVectorTy()) { - llvm::IRBuilder<>::FastMathFlagGuard FMFG(Builder); - setBuilderFlagsFromFPFeatures(Builder, CGF, op.FPFeatures); // Try to form an fmuladd. if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder)) return FMulAdd; @@ -3727,8 +3688,6 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) { return EmitOverflowCheckedBinOp(op); if (op.LHS->getType()->isFPOrFPVectorTy()) { - llvm::IRBuilder<>::FastMathFlagGuard FMFG(Builder); - setBuilderFlagsFromFPFeatures(Builder, CGF, op.FPFeatures); // Try to form an fmuladd. if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder, true)) return FMulAdd; @@ -4055,8 +4014,6 @@ Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E, if (BOInfo.isFixedPointOp()) { Result = EmitFixedPointBinOp(BOInfo); } else if (LHS->getType()->isFPOrFPVectorTy()) { - llvm::IRBuilder<>::FastMathFlagGuard FMFG(Builder); - setBuilderFlagsFromFPFeatures(Builder, CGF, BOInfo.FPFeatures); if (!IsSignaling) Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS, "cmp"); else @@ -4209,9 +4166,6 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { Value *RHS = Visit(E->getRHS()); Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType()); if (LHS->getType()->isFPOrFPVectorTy()) { - llvm::IRBuilder<>::FastMathFlagGuard FMFG(Builder); - setBuilderFlagsFromFPFeatures(Builder, CGF, - E->getFPFeatures(CGF.getLangOpts())); LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp"); RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp"); } else { @@ -4296,9 +4250,6 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { Value *RHS = Visit(E->getRHS()); Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType()); if (LHS->getType()->isFPOrFPVectorTy()) { - llvm::IRBuilder<>::FastMathFlagGuard FMFG(Builder); - setBuilderFlagsFromFPFeatures(Builder, CGF, - E->getFPFeatures(CGF.getLangOpts())); LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS, Zero, "cmp"); RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS, Zero, "cmp"); } else { diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index ff4591a..e3df22a 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -3556,17 +3556,17 @@ CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction( StartFunction(FD, ReturnTy, Fn, FI, args); - DeclRefExpr DstExpr(C, &DstDecl, false, DestTy, VK_RValue, SourceLocation()); - UnaryOperator *DST = UnaryOperator::Create( - C, &DstExpr, UO_Deref, DestTy->getPointeeType(), VK_LValue, OK_Ordinary, - SourceLocation(), false, FPOptions(C.getLangOpts())); + DeclRefExpr DstExpr(getContext(), &DstDecl, false, DestTy, VK_RValue, + SourceLocation()); + UnaryOperator DST(&DstExpr, UO_Deref, DestTy->getPointeeType(), + VK_LValue, OK_Ordinary, SourceLocation(), false); - DeclRefExpr SrcExpr(C, &SrcDecl, false, SrcTy, VK_RValue, SourceLocation()); - UnaryOperator *SRC = UnaryOperator::Create( - C, &SrcExpr, UO_Deref, SrcTy->getPointeeType(), VK_LValue, OK_Ordinary, - SourceLocation(), false, FPOptions(C.getLangOpts())); + DeclRefExpr SrcExpr(getContext(), &SrcDecl, false, SrcTy, VK_RValue, + SourceLocation()); + UnaryOperator SRC(&SrcExpr, UO_Deref, SrcTy->getPointeeType(), + VK_LValue, OK_Ordinary, SourceLocation(), false); - Expr *Args[2] = {DST, SRC}; + Expr *Args[2] = { &DST, &SRC }; CallExpr *CalleeExp = cast(PID->getSetterCXXAssignment()); CXXOperatorCallExpr *TheCall = CXXOperatorCallExpr::Create( C, OO_Equal, CalleeExp->getCallee(), Args, DestTy->getPointeeType(), @@ -3642,15 +3642,14 @@ CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction( DeclRefExpr SrcExpr(getContext(), &SrcDecl, false, SrcTy, VK_RValue, SourceLocation()); - UnaryOperator *SRC = UnaryOperator::Create( - C, &SrcExpr, UO_Deref, SrcTy->getPointeeType(), VK_LValue, OK_Ordinary, - SourceLocation(), false, FPOptions(C.getLangOpts())); + UnaryOperator SRC(&SrcExpr, UO_Deref, SrcTy->getPointeeType(), + VK_LValue, OK_Ordinary, SourceLocation(), false); CXXConstructExpr *CXXConstExpr = cast(PID->getGetterCXXConstructor()); SmallVector ConstructorArgs; - ConstructorArgs.push_back(SRC); + ConstructorArgs.push_back(&SRC); ConstructorArgs.append(std::next(CXXConstExpr->arg_begin()), CXXConstExpr->arg_end()); diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index ae30944..02075be 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -3055,9 +3055,8 @@ void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { C, &IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue, OK_Ordinary, S.getBeginLoc(), FPOptions(C.getLangOpts())); // Increment for loop counter. - UnaryOperator *Inc = UnaryOperator::Create( - C, &IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue, OK_Ordinary, - S.getBeginLoc(), true, FPOptions(C.getLangOpts())); + UnaryOperator Inc(&IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue, OK_Ordinary, + S.getBeginLoc(), true); auto &&BodyGen = [CapturedStmt, CS, &S, &IV](CodeGenFunction &CGF) { // Iterate through all sections and emit a switch construct: // switch (IV) { @@ -3127,7 +3126,7 @@ void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { // IV = LB; CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getBeginLoc()), IV); // while (idx <= UB) { BODY; ++idx; } - CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, Cond, Inc, BodyGen, + CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, Cond, &Inc, BodyGen, [](CodeGenFunction &) {}); // Tell the runtime we are done. auto &&CodeGen = [&S](CodeGenFunction &CGF) { diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 4fcf31a..24e01c4 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -117,8 +117,8 @@ CodeGenFunction::~CodeGenFunction() { // Map the LangOption for exception behavior into // the corresponding enum in the IR. -llvm::fp::ExceptionBehavior -clang::ToConstrainedExceptMD(LangOptions::FPExceptionModeKind Kind) { +static llvm::fp::ExceptionBehavior ToConstrainedExceptMD( + LangOptions::FPExceptionModeKind Kind) { switch (Kind) { case LangOptions::FPE_Ignore: return llvm::fp::ebIgnore; @@ -133,10 +133,15 @@ void CodeGenFunction::SetFPModel() { auto fpExceptionBehavior = ToConstrainedExceptMD( getLangOpts().getFPExceptionMode()); - Builder.setDefaultConstrainedRounding(RM); - Builder.setDefaultConstrainedExcept(fpExceptionBehavior); - Builder.setIsFPConstrained(fpExceptionBehavior != llvm::fp::ebIgnore || - RM != llvm::RoundingMode::NearestTiesToEven); + if (fpExceptionBehavior == llvm::fp::ebIgnore && + RM == llvm::RoundingMode::NearestTiesToEven) + // Constrained intrinsics are not used. + ; + else { + Builder.setIsFPConstrained(true); + Builder.setDefaultConstrainedRounding(RM); + Builder.setDefaultConstrainedExcept(fpExceptionBehavior); + } } CharUnits CodeGenFunction::getNaturalPointeeTypeAlignment(QualType T, @@ -914,11 +919,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, Fn->addFnAttr(llvm::Attribute::NoRecurse); } - if (const FunctionDecl *FD = dyn_cast_or_null(D)) { - Builder.setIsFPConstrained(FD->usesFPIntrin()); + if (const FunctionDecl *FD = dyn_cast_or_null(D)) if (FD->usesFPIntrin()) Fn->addFnAttr(llvm::Attribute::StrictFP); - } // If a custom alignment is used, force realigning to this alignment on // any main function which certainly will need it. diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 2639fd8..0e09eb7 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -4575,11 +4575,6 @@ inline llvm::Value *DominatingLLVMValue::restore(CodeGenFunction &CGF, } } // end namespace CodeGen - -// Map the LangOption for floating point exception behavior into -// the corresponding enum in the IR. -llvm::fp::ExceptionBehavior -ToConstrainedExceptMD(LangOptions::FPExceptionModeKind Kind); } // end namespace clang #endif diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 391f0e9..b327fa9 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -2455,7 +2455,7 @@ static const StringRef GetInputKindName(InputKind IK) { static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, const TargetOptions &TargetOpts, - PreprocessorOptions &PPOpts, CodeGenOptions &CGOpts, + PreprocessorOptions &PPOpts, DiagnosticsEngine &Diags) { // FIXME: Cleanup per-file based stuff. LangStandard::Kind LangStd = LangStandard::lang_unspecified; @@ -3187,19 +3187,6 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.UnsafeFPMath = Args.hasArg(OPT_menable_unsafe_fp_math) || Args.hasArg(OPT_cl_unsafe_math_optimizations) || Args.hasArg(OPT_cl_fast_relaxed_math); - Opts.AllowFPReassoc = Opts.FastMath || CGOpts.Reassociate; - Opts.NoHonorNaNs = - Opts.FastMath || CGOpts.NoNaNsFPMath || Opts.FiniteMathOnly; - Opts.NoHonorInfs = - Opts.FastMath || CGOpts.NoInfsFPMath || Opts.FiniteMathOnly; - Opts.NoSignedZero = Opts.FastMath || CGOpts.NoSignedZeros; - Opts.AllowRecip = Opts.FastMath || CGOpts.ReciprocalMath; - // Currently there's no clang option to enable this individually - Opts.ApproxFunc = Opts.FastMath; - Opts.denormalIsIEEE = - !(CGOpts.FPDenormalMode.isValid() && CGOpts.FP32DenormalMode.isValid()) || - (CGOpts.FPDenormalMode == llvm::DenormalMode::getIEEE() && - CGOpts.FP32DenormalMode == llvm::DenormalMode::getIEEE()); if (Arg *A = Args.getLastArg(OPT_ffp_contract)) { StringRef Val = A->getValue(); @@ -3653,7 +3640,7 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, // Other LangOpts are only initialized when the input is not AST or LLVM IR. // FIXME: Should we really be calling this for an Language::Asm input? ParseLangArgs(LangOpts, Args, DashX, Res.getTargetOpts(), - Res.getPreprocessorOpts(), Res.getCodeGenOpts(), Diags); + Res.getPreprocessorOpts(), Diags); if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC) LangOpts.ObjCExceptions = 1; if (T.isOSDarwin() && DashX.isPreprocessed()) { diff --git a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp index bb195ad..c46ba98 100644 --- a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp @@ -2587,10 +2587,9 @@ Stmt *RewriteModernObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { strType, nullptr, SC_Static); DeclRefExpr *DRE = new (Context) DeclRefExpr(*Context, NewVD, false, strType, VK_LValue, SourceLocation()); - Expr *Unop = UnaryOperator::Create( - const_cast(*Context), DRE, UO_AddrOf, - Context->getPointerType(DRE->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + Expr *Unop = new (Context) + UnaryOperator(DRE, UO_AddrOf, Context->getPointerType(DRE->getType()), + VK_RValue, OK_Ordinary, SourceLocation(), false); // cast to NSConstantString * CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(), CK_CPointerToObjCPointerCast, Unop); @@ -3284,10 +3283,10 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, // we need the cast below. For example: // (struct __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) // - SuperRep = UnaryOperator::Create( - const_cast(*Context), SuperRep, UO_AddrOf, - Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, + Context->getPointerType(SuperRep->getType()), + VK_RValue, OK_Ordinary, + SourceLocation(), false); SuperRep = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(superType), CK_BitCast, SuperRep); @@ -3302,10 +3301,10 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, superType, VK_LValue, ILE, false); // struct __rw_objc_super * - SuperRep = UnaryOperator::Create( - const_cast(*Context), SuperRep, UO_AddrOf, - Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, + Context->getPointerType(SuperRep->getType()), + VK_RValue, OK_Ordinary, + SourceLocation(), false); } MsgExprs.push_back(SuperRep); break; @@ -3379,10 +3378,10 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp, // we need the cast below. For example: // (struct __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) // - SuperRep = UnaryOperator::Create( - const_cast(*Context), SuperRep, UO_AddrOf, - Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, + Context->getPointerType(SuperRep->getType()), + VK_RValue, OK_Ordinary, + SourceLocation(), false); SuperRep = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(superType), CK_BitCast, SuperRep); @@ -4706,10 +4705,9 @@ Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) { if (VarDecl *Var = dyn_cast(VD)) if (!ImportedLocalExternalDecls.count(Var)) return DRE; - Expr *Exp = UnaryOperator::Create(const_cast(*Context), DRE, - UO_Deref, DRE->getType(), VK_LValue, - OK_Ordinary, DRE->getLocation(), false, - FPOptions(Context->getLangOpts())); + Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(), + VK_LValue, OK_Ordinary, + DRE->getLocation(), false); // Need parens to enforce precedence. ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), Exp); @@ -5295,12 +5293,11 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, VarDecl *NewVD = VarDecl::Create( *Context, TUDecl, SourceLocation(), SourceLocation(), &Context->Idents.get(DescData), Context->VoidPtrTy, nullptr, SC_Static); - UnaryOperator *DescRefExpr = UnaryOperator::Create( - const_cast(*Context), + UnaryOperator *DescRefExpr = new (Context) UnaryOperator( new (Context) DeclRefExpr(*Context, NewVD, false, Context->VoidPtrTy, VK_LValue, SourceLocation()), UO_AddrOf, Context->getPointerType(Context->VoidPtrTy), VK_RValue, - OK_Ordinary, SourceLocation(), false, FPOptions(Context->getLangOpts())); + OK_Ordinary, SourceLocation(), false); InitExprs.push_back(DescRefExpr); // Add initializers for any closure decl refs. @@ -5317,10 +5314,9 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, if (HasLocalVariableExternalStorage(*I)) { QualType QT = (*I)->getType(); QT = Context->getPointerType(QT); - Exp = UnaryOperator::Create(const_cast(*Context), Exp, - UO_AddrOf, QT, VK_RValue, OK_Ordinary, - SourceLocation(), false, - FPOptions(Context->getLangOpts())); + Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, + OK_Ordinary, SourceLocation(), + false); } } else if (isTopLevelBlockPointerType((*I)->getType())) { FD = SynthBlockInitFunctionDecl((*I)->getName()); @@ -5335,10 +5331,9 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, if (HasLocalVariableExternalStorage(*I)) { QualType QT = (*I)->getType(); QT = Context->getPointerType(QT); - Exp = UnaryOperator::Create(const_cast(*Context), Exp, - UO_AddrOf, QT, VK_RValue, OK_Ordinary, - SourceLocation(), false, - FPOptions(Context->getLangOpts())); + Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, + OK_Ordinary, SourceLocation(), + false); } } @@ -5376,10 +5371,10 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, // captured nested byref variable has its address passed. Do not take // its address again. if (!isNestedCapturedVar) - Exp = UnaryOperator::Create( - const_cast(*Context), Exp, UO_AddrOf, - Context->getPointerType(Exp->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, + Context->getPointerType(Exp->getType()), + VK_RValue, OK_Ordinary, SourceLocation(), + false); Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp); InitExprs.push_back(Exp); } @@ -5403,10 +5398,9 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp, NewRep = DRE; } - NewRep = UnaryOperator::Create( - const_cast(*Context), NewRep, UO_AddrOf, - Context->getPointerType(NewRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf, + Context->getPointerType(NewRep->getType()), + VK_RValue, OK_Ordinary, SourceLocation(), false); NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast, NewRep); // Put Paren around the call. @@ -7545,10 +7539,10 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { CK_BitCast, PE); - Expr *Exp = UnaryOperator::Create(const_cast(*Context), - castExpr, UO_Deref, IvarT, VK_LValue, - OK_Ordinary, SourceLocation(), false, - FPOptions(Context->getLangOpts())); + + Expr *Exp = new (Context) UnaryOperator(castExpr, UO_Deref, IvarT, + VK_LValue, OK_Ordinary, + SourceLocation(), false); PE = new (Context) ParenExpr(OldRange.getBegin(), OldRange.getEnd(), Exp); diff --git a/clang/lib/Frontend/Rewrite/RewriteObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteObjC.cpp index 8b618d9..4674f7c 100644 --- a/clang/lib/Frontend/Rewrite/RewriteObjC.cpp +++ b/clang/lib/Frontend/Rewrite/RewriteObjC.cpp @@ -2514,10 +2514,9 @@ Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { strType, nullptr, SC_Static); DeclRefExpr *DRE = new (Context) DeclRefExpr(*Context, NewVD, false, strType, VK_LValue, SourceLocation()); - Expr *Unop = UnaryOperator::Create( - const_cast(*Context), DRE, UO_AddrOf, - Context->getPointerType(DRE->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + Expr *Unop = new (Context) + UnaryOperator(DRE, UO_AddrOf, Context->getPointerType(DRE->getType()), + VK_RValue, OK_Ordinary, SourceLocation(), false); // cast to NSConstantString * CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(), CK_CPointerToObjCPointerCast, Unop); @@ -2715,10 +2714,10 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, // we need the cast below. For example: // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) // - SuperRep = UnaryOperator::Create( - const_cast(*Context), SuperRep, UO_AddrOf, - Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, + Context->getPointerType(SuperRep->getType()), + VK_RValue, OK_Ordinary, + SourceLocation(), false); SuperRep = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(superType), CK_BitCast, SuperRep); @@ -2733,10 +2732,10 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, superType, VK_LValue, ILE, false); // struct objc_super * - SuperRep = UnaryOperator::Create( - const_cast(*Context), SuperRep, UO_AddrOf, - Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, + Context->getPointerType(SuperRep->getType()), + VK_RValue, OK_Ordinary, + SourceLocation(), false); } MsgExprs.push_back(SuperRep); break; @@ -2810,10 +2809,10 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, // we need the cast below. For example: // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER")) // - SuperRep = UnaryOperator::Create( - const_cast(*Context), SuperRep, UO_AddrOf, - Context->getPointerType(SuperRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, + Context->getPointerType(SuperRep->getType()), + VK_RValue, OK_Ordinary, + SourceLocation(), false); SuperRep = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(superType), CK_BitCast, SuperRep); @@ -3049,10 +3048,9 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) { nullptr, SC_Extern); DeclRefExpr *DRE = new (Context) DeclRefExpr( *Context, VD, false, getProtocolType(), VK_LValue, SourceLocation()); - Expr *DerefExpr = UnaryOperator::Create( - const_cast(*Context), DRE, UO_AddrOf, - Context->getPointerType(DRE->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf, + Context->getPointerType(DRE->getType()), + VK_RValue, OK_Ordinary, SourceLocation(), false); CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(), CK_BitCast, DerefExpr); @@ -3877,10 +3875,9 @@ Stmt *RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) { if (VarDecl *Var = dyn_cast(VD)) if (!ImportedLocalExternalDecls.count(Var)) return DRE; - Expr *Exp = UnaryOperator::Create(const_cast(*Context), DRE, - UO_Deref, DRE->getType(), VK_LValue, - OK_Ordinary, DRE->getLocation(), false, - FPOptions(Context->getLangOpts())); + Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(), + VK_LValue, OK_Ordinary, + DRE->getLocation(), false); // Need parens to enforce precedence. ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), Exp); @@ -4435,12 +4432,11 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, VarDecl *NewVD = VarDecl::Create( *Context, TUDecl, SourceLocation(), SourceLocation(), &Context->Idents.get(DescData), Context->VoidPtrTy, nullptr, SC_Static); - UnaryOperator *DescRefExpr = UnaryOperator::Create( - const_cast(*Context), + UnaryOperator *DescRefExpr = new (Context) UnaryOperator( new (Context) DeclRefExpr(*Context, NewVD, false, Context->VoidPtrTy, VK_LValue, SourceLocation()), UO_AddrOf, Context->getPointerType(Context->VoidPtrTy), VK_RValue, - OK_Ordinary, SourceLocation(), false, FPOptions(Context->getLangOpts())); + OK_Ordinary, SourceLocation(), false); InitExprs.push_back(DescRefExpr); // Add initializers for any closure decl refs. @@ -4457,10 +4453,9 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, if (HasLocalVariableExternalStorage(*I)) { QualType QT = (*I)->getType(); QT = Context->getPointerType(QT); - Exp = UnaryOperator::Create(const_cast(*Context), Exp, - UO_AddrOf, QT, VK_RValue, OK_Ordinary, - SourceLocation(), false, - FPOptions(Context->getLangOpts())); + Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, + OK_Ordinary, SourceLocation(), + false); } } else if (isTopLevelBlockPointerType((*I)->getType())) { FD = SynthBlockInitFunctionDecl((*I)->getName()); @@ -4475,10 +4470,9 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, if (HasLocalVariableExternalStorage(*I)) { QualType QT = (*I)->getType(); QT = Context->getPointerType(QT); - Exp = UnaryOperator::Create(const_cast(*Context), Exp, - UO_AddrOf, QT, VK_RValue, OK_Ordinary, - SourceLocation(), false, - FPOptions(Context->getLangOpts())); + Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, + OK_Ordinary, SourceLocation(), + false); } } InitExprs.push_back(Exp); @@ -4515,10 +4509,9 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, // captured nested byref variable has its address passed. Do not take // its address again. if (!isNestedCapturedVar) - Exp = UnaryOperator::Create( - const_cast(*Context), Exp, UO_AddrOf, - Context->getPointerType(Exp->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + Exp = new (Context) UnaryOperator( + Exp, UO_AddrOf, Context->getPointerType(Exp->getType()), VK_RValue, + OK_Ordinary, SourceLocation(), false); Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp); InitExprs.push_back(Exp); } @@ -4534,10 +4527,9 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, } NewRep = CallExpr::Create(*Context, DRE, InitExprs, FType, VK_LValue, SourceLocation()); - NewRep = UnaryOperator::Create( - const_cast(*Context), NewRep, UO_AddrOf, - Context->getPointerType(NewRep->getType()), VK_RValue, OK_Ordinary, - SourceLocation(), false, FPOptions(Context->getLangOpts())); + NewRep = new (Context) UnaryOperator( + NewRep, UO_AddrOf, Context->getPointerType(NewRep->getType()), VK_RValue, + OK_Ordinary, SourceLocation(), false); NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast, NewRep); BlockDeclRefs.clear(); diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index f8c6379..6b91919 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -3365,14 +3365,6 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, // are complete and we can parse the delayed portions of method // declarations and the lexed inline method definitions, along with any // delayed attributes. - - // Save the state of Sema.FPFeatures, and change the setting - // to the levels specified on the command line. Previous level - // will be restored when the RAII object is destroyed. - Sema::FPFeaturesStateRAII SaveFPFeaturesState(Actions); - FPOptions fpOptions(getLangOpts()); - Actions.CurFPFeatures.getFromOpaqueInt(fpOptions.getAsOpaqueInt()); - SourceLocation SavedPrevTokLocation = PrevTokLocation; ParseLexedPragmas(getCurrentClass()); ParseLexedAttributes(getCurrentClass()); diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index 3b5b7154..3423243 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -184,16 +184,6 @@ private: Sema &Actions; }; -struct PragmaFloatControlHandler : public PragmaHandler { - PragmaFloatControlHandler(Sema &Actions) - : PragmaHandler("float_control"), Actions(Actions) {} - void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, - Token &FirstToken) override; - -private: - Sema &Actions; -}; - struct PragmaMSPointersToMembers : public PragmaHandler { explicit PragmaMSPointersToMembers() : PragmaHandler("pointers_to_members") {} void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer, @@ -344,8 +334,6 @@ void Parser::initializePragmaHandlers() { PP.AddPragmaHandler(MSCommentHandler.get()); } - FloatControlHandler = std::make_unique(Actions); - PP.AddPragmaHandler(FloatControlHandler.get()); if (getLangOpts().MicrosoftExt) { MSDetectMismatchHandler = std::make_unique(Actions); @@ -450,8 +438,6 @@ void Parser::resetPragmaHandlers() { PP.RemovePragmaHandler("clang", PCSectionHandler.get()); PCSectionHandler.reset(); - PP.RemovePragmaHandler(FloatControlHandler.get()); - FloatControlHandler.reset(); if (getLangOpts().MicrosoftExt) { PP.RemovePragmaHandler(MSDetectMismatchHandler.get()); MSDetectMismatchHandler.reset(); @@ -660,22 +646,6 @@ void Parser::HandlePragmaFPContract() { ConsumeAnnotationToken(); } -void Parser::HandlePragmaFloatControl() { - assert(Tok.is(tok::annot_pragma_float_control)); - - // The value that is held on the PragmaFloatControlStack encodes - // the PragmaFloatControl kind and the MSStackAction kind - // into a single 32-bit word. The MsStackAction is the high 16 bits - // and the FloatControl is the lower 16 bits. Use shift and bit-and - // to decode the parts. - uintptr_t Value = reinterpret_cast(Tok.getAnnotationValue()); - Sema::PragmaMsStackAction Action = - static_cast((Value >> 16) & 0xFFFF); - PragmaFloatControlKind Kind = PragmaFloatControlKind(Value & 0xFFFF); - SourceLocation PragmaLoc = ConsumeAnnotationToken(); - Actions.ActOnPragmaFloatControl(PragmaLoc, Action, Kind); -} - void Parser::HandlePragmaFEnvAccess() { assert(Tok.is(tok::annot_pragma_fenv_access)); tok::OnOffSwitch OOS = @@ -695,8 +665,8 @@ void Parser::HandlePragmaFEnvAccess() { break; } - SourceLocation PragmaLoc = ConsumeAnnotationToken(); - Actions.ActOnPragmaFEnvAccess(PragmaLoc, FPC); + Actions.ActOnPragmaFEnvAccess(FPC); + ConsumeAnnotationToken(); } @@ -2519,129 +2489,6 @@ void PragmaMSPragma::HandlePragma(Preprocessor &PP, PP.EnterToken(AnnotTok, /*IsReinject*/ false); } -/// Handle the \#pragma float_control extension. -/// -/// The syntax is: -/// \code -/// #pragma float_control(keyword[, setting] [,push]) -/// \endcode -/// Where 'keyword' and 'setting' are identifiers. -// 'keyword' can be: precise, except, push, pop -// 'setting' can be: on, off -/// The optional arguments 'setting' and 'push' are supported only -/// when the keyword is 'precise' or 'except'. -void PragmaFloatControlHandler::HandlePragma(Preprocessor &PP, - PragmaIntroducer Introducer, - Token &Tok) { - Sema::PragmaMsStackAction Action = Sema::PSK_Set; - SourceLocation FloatControlLoc = Tok.getLocation(); - PP.Lex(Tok); - if (Tok.isNot(tok::l_paren)) { - PP.Diag(FloatControlLoc, diag::err_expected) << tok::l_paren; - return; - } - - // Read the identifier. - PP.Lex(Tok); - if (Tok.isNot(tok::identifier)) { - PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed); - return; - } - - // Verify that this is one of the float control options. - IdentifierInfo *II = Tok.getIdentifierInfo(); - PragmaFloatControlKind Kind = - llvm::StringSwitch(II->getName()) - .Case("precise", PFC_Precise) - .Case("except", PFC_Except) - .Case("push", PFC_Push) - .Case("pop", PFC_Pop) - .Default(PFC_Unknown); - PP.Lex(Tok); // the identifier - if (Kind == PFC_Unknown) { - PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed); - return; - } else if (Kind == PFC_Push || Kind == PFC_Pop) { - if (Tok.isNot(tok::r_paren)) { - PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed); - return; - } - PP.Lex(Tok); // Eat the r_paren - Action = (Kind == PFC_Pop) ? Sema::PSK_Pop : Sema::PSK_Push; - } else { - if (Tok.is(tok::r_paren)) - // Selecting Precise or Except - PP.Lex(Tok); // the r_paren - else if (Tok.isNot(tok::comma)) { - PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed); - return; - } else { - PP.Lex(Tok); // , - if (!Tok.isAnyIdentifier()) { - PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed); - return; - } - StringRef PushOnOff = Tok.getIdentifierInfo()->getName(); - if (PushOnOff == "on") - // Kind is set correctly - ; - else if (PushOnOff == "off") { - if (Kind == PFC_Precise) - Kind = PFC_NoPrecise; - if (Kind == PFC_Except) - Kind = PFC_NoExcept; - } else if (PushOnOff == "push") { - Action = Sema::PSK_Push_Set; - } else { - PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed); - return; - } - PP.Lex(Tok); // the identifier - if (Tok.is(tok::comma)) { - PP.Lex(Tok); // , - if (!Tok.isAnyIdentifier()) { - PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed); - return; - } - StringRef ExpectedPush = Tok.getIdentifierInfo()->getName(); - if (ExpectedPush == "push") { - Action = Sema::PSK_Push_Set; - } else { - PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed); - return; - } - PP.Lex(Tok); // the push identifier - } - if (Tok.isNot(tok::r_paren)) { - PP.Diag(Tok.getLocation(), diag::err_pragma_float_control_malformed); - return; - } - PP.Lex(Tok); // the r_paren - } - } - SourceLocation EndLoc = Tok.getLocation(); - if (Tok.isNot(tok::eod)) { - PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) - << "float_control"; - return; - } - - // Note: there is no accomodation for PP callback for this pragma. - - // Enter the annotation. - auto TokenArray = std::make_unique(1); - TokenArray[0].startToken(); - TokenArray[0].setKind(tok::annot_pragma_float_control); - TokenArray[0].setLocation(FloatControlLoc); - TokenArray[0].setAnnotationEndLoc(EndLoc); - // Create an encoding of Action and Value by shifting the Action into - // the high 16 bits then union with the Kind. - TokenArray[0].setAnnotationValue(reinterpret_cast( - static_cast((Action << 16) | (Kind & 0xFFFF)))); - PP.EnterTokenStream(std::move(TokenArray), 1, - /*DisableMacroExpansion=*/false, /*IsReinject=*/false); -} - /// Handle the Microsoft \#pragma detect_mismatch extension. /// /// The syntax is: @@ -2902,7 +2749,7 @@ void PragmaFPHandler::HandlePragma(Preprocessor &PP, auto *AnnotValue = new (PP.getPreprocessorAllocator()) TokFPAnnotValue{*FlagKind, *FlagValue}; - // Generate the fp annotation token. + // Generate the loop hint token. Token FPTok; FPTok.startToken(); FPTok.setKind(tok::annot_pragma_fp); diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 84166bb..7704021 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -354,13 +354,13 @@ Retry: case tok::annot_pragma_fp_contract: ProhibitAttributes(Attrs); - Diag(Tok, diag::err_pragma_file_or_compound_scope) << "fp_contract"; + Diag(Tok, diag::err_pragma_fp_contract_scope); ConsumeAnnotationToken(); return StmtError(); case tok::annot_pragma_fp: ProhibitAttributes(Attrs); - Diag(Tok, diag::err_pragma_file_or_compound_scope) << "clang fp"; + Diag(Tok, diag::err_pragma_fp_scope); ConsumeAnnotationToken(); return StmtError(); @@ -369,12 +369,6 @@ Retry: HandlePragmaFEnvAccess(); return StmtEmpty(); - case tok::annot_pragma_float_control: - ProhibitAttributes(Attrs); - Diag(Tok, diag::err_pragma_file_or_compound_scope) << "float_control"; - ConsumeAnnotationToken(); - return StmtError(); - case tok::annot_pragma_opencl_extension: ProhibitAttributes(Attrs); HandlePragmaOpenCLExtension(); @@ -943,9 +937,6 @@ void Parser::ParseCompoundStatementLeadingPragmas() { case tok::annot_pragma_fenv_access: HandlePragmaFEnvAccess(); break; - case tok::annot_pragma_float_control: - HandlePragmaFloatControl(); - break; case tok::annot_pragma_ms_pointers_to_members: HandlePragmaMSPointersToMembers(); break; diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index de809b9..5fa23f2 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -752,9 +752,6 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, case tok::annot_pragma_fenv_access: HandlePragmaFEnvAccess(); return nullptr; - case tok::annot_pragma_float_control: - HandlePragmaFloatControl(); - return nullptr; case tok::annot_pragma_fp: HandlePragmaFP(); break; diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 0d2877e..405b6c33 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -159,8 +159,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, LangOpts.getMSPointerToMemberRepresentationMethod()), VtorDispStack(LangOpts.getVtorDispMode()), PackStack(0), DataSegStack(nullptr), BSSSegStack(nullptr), ConstSegStack(nullptr), - CodeSegStack(nullptr), FpPragmaStack(CurFPFeatures.getAsOpaqueInt()), - CurInitSeg(nullptr), VisContext(nullptr), + CodeSegStack(nullptr), CurInitSeg(nullptr), VisContext(nullptr), PragmaAttributeCurrentTargetDecl(nullptr), IsBuildingRecoveryCallExpr(false), Cleanup{}, LateTemplateParser(nullptr), LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr), IdResolver(pp), diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index 518ac0f..8633581 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -407,65 +407,6 @@ void Sema::ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name, Consumer.HandleTopLevelDecl(DeclGroupRef(PDMD)); } -void Sema::ActOnPragmaFloatControl(SourceLocation Loc, - PragmaMsStackAction Action, - PragmaFloatControlKind Value) { - auto NewValue = FpPragmaStack.CurrentValue; - FPOptions NewFPFeatures(NewValue); - if ((Action == PSK_Push_Set || Action == PSK_Push || Action == PSK_Pop) && - !CurContext->isTranslationUnit()) { - // Push and pop can only occur at file scope. - Diag(Loc, diag::err_pragma_fc_pp_scope); - return; - } - switch (Value) { - default: - llvm_unreachable("invalid pragma float_control kind"); - case PFC_Precise: - CurFPFeatures.setFPPreciseEnabled(true); - NewValue = CurFPFeatures.getAsOpaqueInt(); - FpPragmaStack.Act(Loc, Action, StringRef(), NewValue); - break; - case PFC_NoPrecise: - if (CurFPFeatures.getExceptionMode() == LangOptions::FPE_Strict) - Diag(Loc, diag::err_pragma_fc_noprecise_requires_noexcept); - else if (CurFPFeatures.allowFEnvAccess()) - Diag(Loc, diag::err_pragma_fc_noprecise_requires_nofenv); - else - CurFPFeatures.setFPPreciseEnabled(false); - NewValue = CurFPFeatures.getAsOpaqueInt(); - FpPragmaStack.Act(Loc, Action, StringRef(), NewValue); - break; - case PFC_Except: - if (!isPreciseFPEnabled()) - Diag(Loc, diag::err_pragma_fc_except_requires_precise); - else - CurFPFeatures.setExceptionMode(LangOptions::FPE_Strict); - NewValue = CurFPFeatures.getAsOpaqueInt(); - FpPragmaStack.Act(Loc, Action, StringRef(), NewValue); - break; - case PFC_NoExcept: - CurFPFeatures.setExceptionMode(LangOptions::FPE_Ignore); - NewValue = CurFPFeatures.getAsOpaqueInt(); - FpPragmaStack.Act(Loc, Action, StringRef(), NewValue); - break; - case PFC_Push: - Action = Sema::PSK_Push_Set; - FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures.getAsOpaqueInt()); - break; - case PFC_Pop: - if (FpPragmaStack.Stack.empty()) { - Diag(Loc, diag::warn_pragma_pop_failed) << "float_control" - << "stack empty"; - return; - } - FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures.getAsOpaqueInt()); - NewValue = FpPragmaStack.CurrentValue; - CurFPFeatures.getFromOpaqueInt(NewValue); - break; - } -} - void Sema::ActOnPragmaMSPointersToMembers( LangOptions::PragmaMSPointersToMembersKind RepresentationMethod, SourceLocation PragmaLoc) { @@ -1007,16 +948,9 @@ void Sema::setExceptionMode(LangOptions::FPExceptionModeKind FPE) { CurFPFeatures.setExceptionMode(FPE); } -void Sema::ActOnPragmaFEnvAccess(SourceLocation Loc, - LangOptions::FEnvAccessModeKind FPC) { +void Sema::ActOnPragmaFEnvAccess(LangOptions::FEnvAccessModeKind FPC) { switch (FPC) { case LangOptions::FEA_On: - // Verify Microsoft restriction: - // You can't enable fenv_access unless precise semantics are enabled. - // Precise semantics can be enabled either by the float_control - // pragma, or by using the /fp:precise or /fp:strict compiler options - if (!isPreciseFPEnabled()) - Diag(Loc, diag::err_pragma_fenv_requires_precise); CurFPFeatures.setAllowFEnvAccess(); break; case LangOptions::FEA_Off: @@ -1025,6 +959,7 @@ void Sema::ActOnPragmaFEnvAccess(SourceLocation Loc, } } + void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr, SourceLocation Loc) { // Visibility calculations will consider the namespace's visibility. diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 935ac93..78d9322 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -13455,13 +13455,13 @@ buildMemcpyForAssignmentOp(Sema &S, SourceLocation Loc, QualType T, // directly construct UnaryOperators here because semantic analysis // does not permit us to take the address of an xvalue. Expr *From = FromB.build(S, Loc); - From = UnaryOperator::Create( - S.Context, From, UO_AddrOf, S.Context.getPointerType(From->getType()), - VK_RValue, OK_Ordinary, Loc, false, S.CurFPFeatures); + From = new (S.Context) UnaryOperator(From, UO_AddrOf, + S.Context.getPointerType(From->getType()), + VK_RValue, OK_Ordinary, Loc, false); Expr *To = ToB.build(S, Loc); - To = UnaryOperator::Create(S.Context, To, UO_AddrOf, - S.Context.getPointerType(To->getType()), VK_RValue, - OK_Ordinary, Loc, false, S.CurFPFeatures); + To = new (S.Context) UnaryOperator(To, UO_AddrOf, + S.Context.getPointerType(To->getType()), + VK_RValue, OK_Ordinary, Loc, false); const Type *E = T->getBaseElementTypeUnsafe(); bool NeedsCollectableMemCpy = @@ -13703,9 +13703,9 @@ buildSingleCopyAssignRecursively(Sema &S, SourceLocation Loc, QualType T, // Create the pre-increment of the iteration variable. We can determine // whether the increment will overflow based on the value of the array // bound. - Expr *Increment = UnaryOperator::Create( - S.Context, IterationVarRef.build(S, Loc), UO_PreInc, SizeType, VK_LValue, - OK_Ordinary, Loc, Upper.isMaxValue(), S.CurFPFeatures); + Expr *Increment = new (S.Context) + UnaryOperator(IterationVarRef.build(S, Loc), UO_PreInc, SizeType, + VK_LValue, OK_Ordinary, Loc, Upper.isMaxValue()); // Construct the loop that copies all elements of this array. return S.ActOnForStmt( diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 7e8446c..5b28015 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -13662,6 +13662,14 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, if (ResultTy.isNull() || LHS.isInvalid() || RHS.isInvalid()) return ExprError(); + if (ResultTy->isRealFloatingType() && + (getLangOpts().getFPRoundingMode() != RoundingMode::NearestTiesToEven || + getLangOpts().getFPExceptionMode() != LangOptions::FPE_Ignore)) + // Mark the current function as usng floating point constrained intrinsics + if (FunctionDecl *F = dyn_cast(CurContext)) { + F->setUsesFPIntrin(true); + } + // Some of the binary operations require promoting operands of half vector to // float vectors and truncating the result back to half vector. For now, we do // this only when HalfArgsAndReturn is set (that is, when the target is arm or @@ -14311,8 +14319,8 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, if (Opc != UO_AddrOf && Opc != UO_Deref) CheckArrayAccess(Input.get()); - auto *UO = UnaryOperator::Create(Context, Input.get(), Opc, resultType, VK, - OK, OpLoc, CanOverflow, CurFPFeatures); + auto *UO = new (Context) + UnaryOperator(Input.get(), Opc, resultType, VK, OK, OpLoc, CanOverflow); if (Opc == UO_Deref && UO->getType()->hasAttr(attr::NoDeref) && !isa(UO->getType().getDesugaredType(Context))) diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 11ab4db..10a7cf3 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -4427,9 +4427,9 @@ Expr *Sema::stripARCUnbridgedCast(Expr *e) { } else if (UnaryOperator *uo = dyn_cast(e)) { assert(uo->getOpcode() == UO_Extension); Expr *sub = stripARCUnbridgedCast(uo->getSubExpr()); - return UnaryOperator::Create(Context, sub, UO_Extension, sub->getType(), - sub->getValueKind(), sub->getObjectKind(), - uo->getOperatorLoc(), false, CurFPFeatures); + return new (Context) + UnaryOperator(sub, UO_Extension, sub->getType(), sub->getValueKind(), + sub->getObjectKind(), uo->getOperatorLoc(), false); } else if (GenericSelectionExpr *gse = dyn_cast(e)) { assert(!gse->isResultDependent()); diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 57b650d..fb5eff0 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -13001,9 +13001,8 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, if (Input->isTypeDependent()) { if (Fns.empty()) - return UnaryOperator::Create(Context, Input, Opc, Context.DependentTy, - VK_RValue, OK_Ordinary, OpLoc, false, - CurFPFeatures); + return new (Context) UnaryOperator(Input, Opc, Context.DependentTy, + VK_RValue, OK_Ordinary, OpLoc, false); CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators UnresolvedLookupExpr *Fn = UnresolvedLookupExpr::Create( @@ -14803,9 +14802,9 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, if (Context.getTargetInfo().getCXXABI().isMicrosoft()) (void)isCompleteType(UnOp->getOperatorLoc(), MemPtrType); - return UnaryOperator::Create( - Context, SubExpr, UO_AddrOf, MemPtrType, VK_RValue, OK_Ordinary, - UnOp->getOperatorLoc(), false, CurFPFeatures); + return new (Context) UnaryOperator(SubExpr, UO_AddrOf, MemPtrType, + VK_RValue, OK_Ordinary, + UnOp->getOperatorLoc(), false); } } Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(), @@ -14813,9 +14812,10 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, if (SubExpr == UnOp->getSubExpr()) return UnOp; - return UnaryOperator::Create( - Context, SubExpr, UO_AddrOf, Context.getPointerType(SubExpr->getType()), - VK_RValue, OK_Ordinary, UnOp->getOperatorLoc(), false, CurFPFeatures); + return new (Context) UnaryOperator(SubExpr, UO_AddrOf, + Context.getPointerType(SubExpr->getType()), + VK_RValue, OK_Ordinary, + UnOp->getOperatorLoc(), false); } if (UnresolvedLookupExpr *ULE = dyn_cast(E)) { diff --git a/clang/lib/Sema/SemaPseudoObject.cpp b/clang/lib/Sema/SemaPseudoObject.cpp index da77720..0ed4522 100644 --- a/clang/lib/Sema/SemaPseudoObject.cpp +++ b/clang/lib/Sema/SemaPseudoObject.cpp @@ -127,10 +127,12 @@ namespace { if (UnaryOperator *uop = dyn_cast(e)) { assert(uop->getOpcode() == UO_Extension); e = rebuild(uop->getSubExpr()); - return UnaryOperator::Create( - S.Context, e, uop->getOpcode(), uop->getType(), uop->getValueKind(), - uop->getObjectKind(), uop->getOperatorLoc(), uop->canOverflow(), - S.CurFPFeatures); + return new (S.Context) UnaryOperator(e, uop->getOpcode(), + uop->getType(), + uop->getValueKind(), + uop->getObjectKind(), + uop->getOperatorLoc(), + uop->canOverflow()); } if (GenericSelectionExpr *gse = dyn_cast(e)) { @@ -524,14 +526,12 @@ PseudoOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc, (result.get()->isTypeDependent() || CanCaptureValue(result.get()))) setResultToLastSemantic(); - UnaryOperator *syntactic = - UnaryOperator::Create(S.Context, syntacticOp, opcode, resultType, - VK_LValue, OK_Ordinary, opcLoc, - !resultType->isDependentType() - ? S.Context.getTypeSize(resultType) >= - S.Context.getTypeSize(S.Context.IntTy) - : false, - S.CurFPFeatures); + UnaryOperator *syntactic = new (S.Context) UnaryOperator( + syntacticOp, opcode, resultType, VK_LValue, OK_Ordinary, opcLoc, + !resultType->isDependentType() + ? S.Context.getTypeSize(resultType) >= + S.Context.getTypeSize(S.Context.IntTy) + : false); return complete(syntactic); } @@ -1551,9 +1551,8 @@ ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc, UnaryOperatorKind opcode, Expr *op) { // Do nothing if the operand is dependent. if (op->isTypeDependent()) - return UnaryOperator::Create(Context, op, opcode, Context.DependentTy, - VK_RValue, OK_Ordinary, opcLoc, false, - CurFPFeatures); + return new (Context) UnaryOperator(op, opcode, Context.DependentTy, + VK_RValue, OK_Ordinary, opcLoc, false); assert(UnaryOperator::isIncrementDecrementOp(opcode)); Expr *opaqueRef = op->IgnoreParens(); @@ -1637,10 +1636,9 @@ Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) { Expr *syntax = E->getSyntacticForm(); if (UnaryOperator *uop = dyn_cast(syntax)) { Expr *op = stripOpaqueValuesFromPseudoObjectRef(*this, uop->getSubExpr()); - return UnaryOperator::Create(Context, op, uop->getOpcode(), uop->getType(), - uop->getValueKind(), uop->getObjectKind(), - uop->getOperatorLoc(), uop->canOverflow(), - CurFPFeatures); + return new (Context) UnaryOperator( + op, uop->getOpcode(), uop->getType(), uop->getValueKind(), + uop->getObjectKind(), uop->getOperatorLoc(), uop->canOverflow()); } else if (CompoundAssignOperator *cop = dyn_cast(syntax)) { Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, cop->getLHS()); diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index f76994a..aa0d89a 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -394,11 +394,6 @@ StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef Elts, bool isStmtExpr) { const unsigned NumElts = Elts.size(); - // Mark the current function as usng floating point constrained intrinsics - if (getCurFPFeatures().isFPConstrained()) - if (FunctionDecl *F = dyn_cast(CurContext)) - F->setUsesFPIntrin(true); - // If we're in C89 mode, check that we don't have any decls after stmts. If // so, emit an extension diagnostic. if (!getLangOpts().C99 && !getLangOpts().CPlusPlus) { diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 187665b..3ead713 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -3779,29 +3779,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { break; } - case FLOAT_CONTROL_PRAGMA_OPTIONS: { - if (Record.size() < 3) { - Error("invalid pragma pack record"); - return Failure; - } - FpPragmaCurrentValue = Record[0]; - FpPragmaCurrentLocation = ReadSourceLocation(F, Record[1]); - unsigned NumStackEntries = Record[2]; - unsigned Idx = 3; - // Reset the stack when importing a new module. - FpPragmaStack.clear(); - for (unsigned I = 0; I < NumStackEntries; ++I) { - FpPragmaStackEntry Entry; - Entry.Value = Record[Idx++]; - Entry.Location = ReadSourceLocation(F, Record[Idx++]); - Entry.PushLocation = ReadSourceLocation(F, Record[Idx++]); - FpPragmaStrings.push_back(ReadString(Record, Idx)); - Entry.SlotLabel = FpPragmaStrings.back(); - FpPragmaStack.push_back(Entry); - } - break; - } - case DECLS_TO_CHECK_FOR_DEFERRED_DIAGS: for (unsigned I = 0, N = Record.size(); I != N; ++I) DeclsToCheckForDeferredDiags.push_back(getGlobalDeclID(F, Record[I])); @@ -7876,34 +7853,6 @@ void ASTReader::UpdateSema() { SemaObj->PackStack.CurrentPragmaLocation = PragmaPackCurrentLocation; } } - if (FpPragmaCurrentValue) { - // The bottom of the stack might have a default value. It must be adjusted - // to the current value to ensure that fp-pragma state is preserved after - // popping entries that were included/imported from a PCH/module. - bool DropFirst = false; - if (!FpPragmaStack.empty() && FpPragmaStack.front().Location.isInvalid()) { - assert(FpPragmaStack.front().Value == - SemaObj->FpPragmaStack.DefaultValue && - "Expected a default pragma float_control value"); - SemaObj->FpPragmaStack.Stack.emplace_back( - FpPragmaStack.front().SlotLabel, SemaObj->FpPragmaStack.CurrentValue, - SemaObj->FpPragmaStack.CurrentPragmaLocation, - FpPragmaStack.front().PushLocation); - DropFirst = true; - } - for (const auto &Entry : - llvm::makeArrayRef(FpPragmaStack).drop_front(DropFirst ? 1 : 0)) - SemaObj->FpPragmaStack.Stack.emplace_back( - Entry.SlotLabel, Entry.Value, Entry.Location, Entry.PushLocation); - if (FpPragmaCurrentLocation.isInvalid()) { - assert(*FpPragmaCurrentValue == SemaObj->FpPragmaStack.DefaultValue && - "Expected a default pragma float_control value"); - // Keep the current values. - } else { - SemaObj->FpPragmaStack.CurrentValue = *FpPragmaCurrentValue; - SemaObj->FpPragmaStack.CurrentPragmaLocation = FpPragmaCurrentLocation; - } - } } IdentifierInfo *ASTReader::get(StringRef Name) { diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index e6d9396..ea21d5e 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -682,14 +682,10 @@ void ASTStmtReader::VisitParenListExpr(ParenListExpr *E) { void ASTStmtReader::VisitUnaryOperator(UnaryOperator *E) { VisitExpr(E); - bool hasFP_Features = Record.readInt(); - assert(hasFP_Features == E->hasStoredFPFeatures()); E->setSubExpr(Record.readSubExpr()); E->setOpcode((UnaryOperator::Opcode)Record.readInt()); E->setOperatorLoc(readSourceLocation()); E->setCanOverflow(Record.readInt()); - if (hasFP_Features) - E->setStoredFPFeatures(FPOptions(Record.readInt())); } void ASTStmtReader::VisitOffsetOfExpr(OffsetOfExpr *E) { @@ -2904,8 +2900,7 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; case EXPR_UNARY_OPERATOR: - S = UnaryOperator::CreateEmpty(Context, - Record[ASTStmtReader::NumExprFields]); + S = new (Context) UnaryOperator(Empty); break; case EXPR_OFFSETOF: diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index b2281ab..462f275 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -4139,26 +4139,6 @@ void ASTWriter::WritePackPragmaOptions(Sema &SemaRef) { Stream.EmitRecord(PACK_PRAGMA_OPTIONS, Record); } -/// Write the state of 'pragma float_control' at the end of the module. -void ASTWriter::WriteFloatControlPragmaOptions(Sema &SemaRef) { - // Don't serialize pragma float_control state for modules, - // since it should only take effect on a per-submodule basis. - if (WritingModule) - return; - - RecordData Record; - Record.push_back(SemaRef.FpPragmaStack.CurrentValue); - AddSourceLocation(SemaRef.FpPragmaStack.CurrentPragmaLocation, Record); - Record.push_back(SemaRef.FpPragmaStack.Stack.size()); - for (const auto &StackEntry : SemaRef.FpPragmaStack.Stack) { - Record.push_back(StackEntry.Value); - AddSourceLocation(StackEntry.PragmaLocation, Record); - AddSourceLocation(StackEntry.PragmaPushLocation, Record); - AddString(StackEntry.StackSlotLabel, Record); - } - Stream.EmitRecord(FLOAT_CONTROL_PRAGMA_OPTIONS, Record); -} - void ASTWriter::WriteModuleFileExtension(Sema &SemaRef, ModuleFileExtensionWriter &Writer) { // Enter the extension block. @@ -4887,7 +4867,6 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot, WriteMSPointersToMembersPragmaOptions(SemaRef); } WritePackPragmaOptions(SemaRef); - WriteFloatControlPragmaOptions(SemaRef); // Some simple statistics RecordData::value_type Record[] = { diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 12a9d27..7c450bc 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -702,16 +702,10 @@ void ASTStmtWriter::VisitParenListExpr(ParenListExpr *E) { void ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) { VisitExpr(E); - bool HasFPFeatures = E->hasStoredFPFeatures(); - // Write this first for easy access when deserializing, as they affect the - // size of the UnaryOperator. - Record.push_back(HasFPFeatures); Record.AddStmt(E->getSubExpr()); Record.push_back(E->getOpcode()); // FIXME: stable encoding Record.AddSourceLocation(E->getOperatorLoc()); Record.push_back(E->canOverflow()); - if (HasFPFeatures) - Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt()); Code = serialization::EXPR_UNARY_OPERATOR; } diff --git a/clang/test/CodeGen/builtins-nvptx.c b/clang/test/CodeGen/builtins-nvptx.c index 1f7a8c6..31c3ecd 100644 --- a/clang/test/CodeGen/builtins-nvptx.c +++ b/clang/test/CodeGen/builtins-nvptx.c @@ -1,11 +1,11 @@ // REQUIRES: nvptx-registered-target -// RUN: %clang_cc1 -ffp-contract=off -triple nvptx-unknown-unknown -target-cpu sm_60 \ +// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_60 \ // RUN: -fcuda-is-device -S -emit-llvm -o - -x cuda %s \ // RUN: | FileCheck -check-prefix=CHECK -check-prefix=LP32 %s -// RUN: %clang_cc1 -ffp-contract=off -triple nvptx64-unknown-unknown -target-cpu sm_60 \ +// RUN: %clang_cc1 -triple nvptx64-unknown-unknown -target-cpu sm_60 \ // RUN: -fcuda-is-device -S -emit-llvm -o - -x cuda %s \ // RUN: | FileCheck -check-prefix=CHECK -check-prefix=LP64 %s -// RUN: %clang_cc1 -ffp-contract=off -triple nvptx64-unknown-unknown -target-cpu sm_61 \ +// RUN: %clang_cc1 -triple nvptx64-unknown-unknown -target-cpu sm_61 \ // RUN: -fcuda-is-device -S -emit-llvm -o - -x cuda %s \ // RUN: | FileCheck -check-prefix=CHECK -check-prefix=LP64 %s // RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_53 \ diff --git a/clang/test/CodeGen/constrained-math-builtins.c b/clang/test/CodeGen/constrained-math-builtins.c index fe303eb..b22cfe6 100644 --- a/clang/test/CodeGen/constrained-math-builtins.c +++ b/clang/test/CodeGen/constrained-math-builtins.c @@ -154,9 +154,9 @@ void bar(float f) { (double)f * f - f; (long double)-f * f + f; - // CHECK: call contract float @llvm.experimental.constrained.fmuladd.f32 - // CHECK: fneg - // CHECK: call contract double @llvm.experimental.constrained.fmuladd.f64 - // CHECK: fneg - // CHECK: call contract x86_fp80 @llvm.experimental.constrained.fmuladd.f80 +// CHECK: call float @llvm.experimental.constrained.fmuladd.f32 +// CHECK: fneg +// CHECK: call double @llvm.experimental.constrained.fmuladd.f64 +// CHECK: fneg +// CHECK: call x86_fp80 @llvm.experimental.constrained.fmuladd.f80 }; diff --git a/clang/test/CodeGen/fast-math.c b/clang/test/CodeGen/fast-math.c index 6ebd65a..6f98b84 100644 --- a/clang/test/CodeGen/fast-math.c +++ b/clang/test/CodeGen/fast-math.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -ffast-math -ffp-contract=fast -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -ffast-math -emit-llvm -o - %s | FileCheck %s float f0, f1, f2; void foo(void) { diff --git a/clang/test/CodeGen/fp-contract-on-pragma.cpp b/clang/test/CodeGen/fp-contract-on-pragma.cpp index 5f74636..812a717 100644 --- a/clang/test/CodeGen/fp-contract-on-pragma.cpp +++ b/clang/test/CodeGen/fp-contract-on-pragma.cpp @@ -3,7 +3,7 @@ // Is FP_CONTRACT honored in a simple case? float fp_contract_1(float a, float b, float c) { // CHECK: _Z13fp_contract_1fff -// CHECK: tail call contract float @llvm.fmuladd +// CHECK: tail call float @llvm.fmuladd #pragma clang fp contract(on) return a * b + c; } @@ -31,7 +31,7 @@ T template_muladd(T a, T b, T c) { float fp_contract_3(float a, float b, float c) { // CHECK: _Z13fp_contract_3fff - // CHECK: tail call contract float @llvm.fmuladd + // CHECK: tail call float @llvm.fmuladd return template_muladd(a, b, c); } @@ -45,13 +45,13 @@ class fp_contract_4 { template class fp_contract_4; // CHECK: _ZN13fp_contract_4IiE6methodEfff -// CHECK: tail call contract float @llvm.fmuladd +// CHECK: tail call float @llvm.fmuladd // Check file-scoped FP_CONTRACT #pragma clang fp contract(on) float fp_contract_5(float a, float b, float c) { // CHECK: _Z13fp_contract_5fff - // CHECK: tail call contract float @llvm.fmuladd + // CHECK: tail call float @llvm.fmuladd return a * b + c; } @@ -69,8 +69,8 @@ float fp_contract_6(float a, float b, float c) { float fp_contract_7(float a, float b, float c) { // CHECK: _Z13fp_contract_7fff -// CHECK: %[[M:.+]] = fmul contract float %b, 2.000000e+00 -// CHECK-NEXT: fsub contract float %[[M]], %c +// CHECK: %[[M:.+]] = fmul float %b, 2.000000e+00 +// CHECK-NEXT: fsub float %[[M]], %c #pragma clang fp contract(on) return (a = 2 * b) - c; } diff --git a/clang/test/CodeGen/fp-contract-pragma.cpp b/clang/test/CodeGen/fp-contract-pragma.cpp index 3a861ab..805cc5d 100644 --- a/clang/test/CodeGen/fp-contract-pragma.cpp +++ b/clang/test/CodeGen/fp-contract-pragma.cpp @@ -2,9 +2,9 @@ // Is FP_CONTRACT honored in a simple case? float fp_contract_1(float a, float b, float c) { - // CHECK: _Z13fp_contract_1fff - // CHECK: tail call contract float @llvm.fmuladd -#pragma STDC FP_CONTRACT ON +// CHECK: _Z13fp_contract_1fff +// CHECK: tail call float @llvm.fmuladd + #pragma STDC FP_CONTRACT ON return a * b + c; } @@ -30,8 +30,8 @@ T template_muladd(T a, T b, T c) { } float fp_contract_3(float a, float b, float c) { - // CHECK: _Z13fp_contract_3fff - // CHECK: tail call contract float @llvm.fmuladd +// CHECK: _Z13fp_contract_3fff +// CHECK: tail call float @llvm.fmuladd return template_muladd(a, b, c); } @@ -44,13 +44,13 @@ template class fp_contract_4 { template class fp_contract_4; // CHECK: _ZN13fp_contract_4IiE6methodEfff -// CHECK: tail call contract float @llvm.fmuladd +// CHECK: tail call float @llvm.fmuladd // Check file-scoped FP_CONTRACT #pragma STDC FP_CONTRACT ON float fp_contract_5(float a, float b, float c) { - // CHECK: _Z13fp_contract_5fff - // CHECK: tail call contract float @llvm.fmuladd +// CHECK: _Z13fp_contract_5fff +// CHECK: tail call float @llvm.fmuladd return a * b + c; } @@ -67,25 +67,25 @@ float fp_contract_6(float a, float b, float c) { // https://llvm.org/bugs/show_bug.cgi?id=25719 float fp_contract_7(float a, float b, float c) { - // CHECK: _Z13fp_contract_7fff - // CHECK: %[[M:.+]] = fmul contract float %b, 2.000000e+00 - // CHECK-NEXT: fsub contract float %[[M]], %c -#pragma STDC FP_CONTRACT ON +// CHECK: _Z13fp_contract_7fff +// CHECK: %[[M:.+]] = fmul float %b, 2.000000e+00 +// CHECK-NEXT: fsub float %[[M]], %c + #pragma STDC FP_CONTRACT ON return (a = 2 * b) - c; } float fp_contract_8(float a, float b, float c) { - // CHECK: _Z13fp_contract_8fff - // CHECK: fneg contract float %c - // CHECK: tail call contract float @llvm.fmuladd -#pragma STDC FP_CONTRACT ON +// CHECK: _Z13fp_contract_8fff +// CHECK: fneg float %c +// CHECK: tail call float @llvm.fmuladd + #pragma STDC FP_CONTRACT ON return a * b - c; } float fp_contract_9(float a, float b, float c) { - // CHECK: _Z13fp_contract_9fff - // CHECK: fneg contract float %a - // CHECK: tail call contract float @llvm.fmuladd -#pragma STDC FP_CONTRACT ON +// CHECK: _Z13fp_contract_9fff +// CHECK: fneg float %a +// CHECK: tail call float @llvm.fmuladd + #pragma STDC FP_CONTRACT ON return c - a * b; } diff --git a/clang/test/CodeGen/fp-floatcontrol-class.cpp b/clang/test/CodeGen/fp-floatcontrol-class.cpp deleted file mode 100644 index ce4e0eb..0000000 --- a/clang/test/CodeGen/fp-floatcontrol-class.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// RUN: %clang_cc1 -ffp-contract=on -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -ffp-contract=on -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -ffp-contract=on -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s -// Verify that float_control does not pertain to initializer expressions - -float y(); -float z(); -#pragma float_control(except, on) -class ON { - float w = 2 + y() * z(); - // CHECK-LABEL: define {{.*}} void @_ZN2ONC2Ev{{.*}} - //CHECK: call contract float {{.*}}llvm.fmuladd -}; -ON on; -#pragma float_control(except, off) -class OFF { - float w = 2 + y() * z(); - // CHECK-LABEL: define {{.*}} void @_ZN3OFFC2Ev{{.*}} - //CHECK: call contract float {{.*}}llvm.fmuladd -}; -OFF off; diff --git a/clang/test/CodeGen/fp-floatcontrol-pragma.cpp b/clang/test/CodeGen/fp-floatcontrol-pragma.cpp deleted file mode 100644 index caaab3c..0000000 --- a/clang/test/CodeGen/fp-floatcontrol-pragma.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s - -float fff(float x, float y) { -// CHECK-LABEL: define float @_Z3fffff{{.*}} -// CHECK: entry -#pragma float_control(except, on) - float z; - z = z * z; - //CHECK: llvm.experimental.constrained.fmul{{.*}} - { - z = x * y; - //CHECK: llvm.experimental.constrained.fmul{{.*}} - } - { -// This pragma has no effect since if there are any fp intrin in the -// function then all the operations need to be fp intrin -#pragma float_control(except, off) - z = z + x * y; - //CHECK: llvm.experimental.constrained.fmul{{.*}} - } - z = z * z; - //CHECK: llvm.experimental.constrained.fmul{{.*}} - return z; -} -float check_precise(float x, float y) { - // CHECK-LABEL: define float @_Z13check_preciseff{{.*}} - float z; - { -#pragma float_control(precise, on) - z = x * y + z; - //CHECK: llvm.fmuladd{{.*}} - } - { -#pragma float_control(precise, off) - z = x * y + z; - //CHECK: fmul fast float - //CHECK: fadd fast float - } - return z; -} -float fma_test1(float a, float b, float c) { -// CHECK-LABEL define float @_Z9fma_test1fff{{.*}} -#pragma float_control(precise, on) - float x = a * b + c; - //CHECK: fmuladd - return x; -} diff --git a/clang/test/CodeGen/fp-floatcontrol-stack.cpp b/clang/test/CodeGen/fp-floatcontrol-stack.cpp deleted file mode 100644 index 18ec0d4..0000000 --- a/clang/test/CodeGen/fp-floatcontrol-stack.cpp +++ /dev/null @@ -1,253 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DDEFAULT=1 -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-DDEFAULT %s -// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DEBSTRICT=1 -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-DEBSTRICT %s -// RUN: %clang_cc1 -triple x86_64-linux-gnu -DFAST=1 -ffast-math -ffp-contract=fast -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-FAST %s -// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DNOHONOR=1 -menable-no-infs -menable-no-nans -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-NOHONOR %s - -#define FUN(n) \ - (float z) { return n * z + n; } - -float fun_default FUN(1) -//CHECK-LABEL: define {{.*}} @_Z11fun_defaultf{{.*}} -#if DEFAULT -//CHECK-DDEFAULT: call contract float @llvm.fmuladd{{.*}} -#endif -#if EBSTRICT -// Note that backend wants constrained intrinsics used -// throughout the function if they are needed anywhere in the function. -// In that case, operations are built with constrained intrinsics operator -// but using default settings for exception behavior and rounding mode. -//CHECK-DEBSTRICT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict -#endif -#if FAST -//CHECK-FAST: fmul fast float -//CHECK-FAST: fadd fast float -#endif - -#pragma float_control(push) -#ifndef FAST -// Rule: precise must be enabled -#pragma float_control(except, on) -#endif - float exc_on FUN(2) -//CHECK-LABEL: define {{.*}} @_Z6exc_onf{{.*}} -#if DEFAULT -//CHECK-DDEFAULT: llvm.experimental.constrained.fmul{{.*}} -#endif -#if EBSTRICT -//CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict -#endif -#if NOHONOR -//CHECK-NOHONOR: nnan ninf contract float {{.*}}llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict -#endif -#if FAST -//Not possible to enable float_control(except) in FAST mode. -//CHECK-FAST: fmul fast float -//CHECK-FAST: fadd fast float -#endif - -#pragma float_control(pop) - float exc_pop FUN(5) -//CHECK-LABEL: define {{.*}} @_Z7exc_popf{{.*}} -#if DEFAULT -//CHECK-DDEFAULT: call contract float @llvm.fmuladd{{.*}} -#endif -#if EBSTRICT -//CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict -#endif -#if NOHONOR -//CHECK-NOHONOR: call nnan ninf contract float @llvm.fmuladd{{.*}} -#endif -#if FAST -//CHECK-FAST: fmul fast float -//CHECK-FAST: fadd fast float -#endif - -#pragma float_control(except, off) - float exc_off FUN(5) -//CHECK-LABEL: define {{.*}} @_Z7exc_offf{{.*}} -#if DEFAULT -//CHECK-DDEFAULT: call contract float @llvm.fmuladd{{.*}} -#endif -#if EBSTRICT -//CHECK-DEBSTRICT: call contract float @llvm.fmuladd{{.*}} -#endif -#if NOHONOR -//CHECK-NOHONOR: call nnan ninf contract float @llvm.fmuladd{{.*}} -#endif -#if FAST -//CHECK-FAST: fmul fast float -//CHECK-FAST: fadd fast float -#endif - -#pragma float_control(precise, on, push) - float precise_on FUN(3) -//CHECK-LABEL: define {{.*}} @_Z10precise_onf{{.*}} -#if DEFAULT -//CHECK-DDEFAULT: contract float {{.*}}llvm.fmuladd{{.*}} -#endif -#if EBSTRICT -//CHECK-DEBSTRICT: contract float {{.*}}llvm.fmuladd{{.*}} -#endif -#if NOHONOR -// If precise is pushed then all fast-math should be off! -//CHECK-NOHONOR: call contract float {{.*}}llvm.fmuladd{{.*}} -#endif -#if FAST -//CHECK-FAST: contract float {{.*}}llvm.fmuladd{{.*}} -#endif - -#pragma float_control(pop) - float precise_pop FUN(3) -//CHECK-LABEL: define {{.*}} @_Z11precise_popf{{.*}} -#if DEFAULT -//CHECK-DDEFAULT: contract float {{.*}}llvm.fmuladd{{.*}} -#endif -#if EBSTRICT -//CHECK-DEBSTRICT: contract float {{.*}}llvm.fmuladd{{.*}} -#endif -#if NOHONOR -//CHECK-NOHONOR: call nnan ninf contract float @llvm.fmuladd{{.*}} -#endif -#if FAST -//CHECK-FAST: fmul fast float -//CHECK-FAST: fadd fast float -#endif -#pragma float_control(precise, off) - float precise_off FUN(4) -//CHECK-LABEL: define {{.*}} @_Z11precise_offf{{.*}} -#if DEFAULT -// Note: precise_off enables fp_contract=fast and the instructions -// generated do not include the contract flag, although it was enabled -// in IRBuilder. -//CHECK-DDEFAULT: fmul fast float -//CHECK-DDEFAULT: fadd fast float -#endif -#if EBSTRICT -//CHECK-DEBSTRICT: fmul fast float -//CHECK-DEBSTRICT: fadd fast float -#endif -#if NOHONOR -// fast math should be enabled, and contract should be fast -//CHECK-NOHONOR: fmul fast float -//CHECK-NOHONOR: fadd fast float -#endif -#if FAST -//CHECK-FAST: fmul fast float -//CHECK-FAST: fadd fast float -#endif - -#pragma float_control(precise, on) - float precise_on2 FUN(3) -//CHECK-LABEL: define {{.*}} @_Z11precise_on2f{{.*}} -#if DEFAULT -//CHECK-DDEFAULT: llvm.fmuladd{{.*}} -#endif -#if EBSTRICT -//CHECK-DEBSTRICT: contract float {{.*}}llvm.fmuladd{{.*}} -#endif -#if NOHONOR -// fast math should be off, and contract should be on -//CHECK-NOHONOR: contract float {{.*}}llvm.fmuladd{{.*}} -#endif -#if FAST -//CHECK-FAST: contract float {{.*}}llvm.fmuladd{{.*}} -#endif - -#pragma float_control(push) - float precise_push FUN(3) -//CHECK-LABEL: define {{.*}} @_Z12precise_pushf{{.*}} -#if DEFAULT -//CHECK-DDEFAULT: llvm.fmuladd{{.*}} -#endif -#if EBSTRICT -//CHECK-DEBSTRICT: contract float {{.*}}llvm.fmuladd{{.*}} -#endif -#if NOHONOR -//CHECK-NOHONOR: contract float {{.*}}llvm.fmuladd{{.*}} -#endif -#if FAST -//CHECK-FAST: contract float {{.*}}llvm.fmuladd{{.*}} -#endif - -#pragma float_control(precise, off) - float precise_off2 FUN(4) -//CHECK-LABEL: define {{.*}} @_Z12precise_off2f{{.*}} -#if DEFAULT -//CHECK-DDEFAULT: fmul fast float -//CHECK-DDEFAULT: fadd fast float -#endif -#if EBSTRICT -//CHECK-DEBSTRICT: fmul fast float -//CHECK-DEBSTRICT: fadd fast float -#endif -#if NOHONOR -// fast math settings since precise is off -//CHECK-NOHONOR: fmul fast float -//CHECK-NOHONOR: fadd fast float -#endif -#if FAST -//CHECK-FAST: fmul fast float -//CHECK-FAST: fadd fast float -#endif - -#pragma float_control(pop) - float precise_pop2 FUN(3) -//CHECK-LABEL: define {{.*}} @_Z12precise_pop2f{{.*}} -#if DEFAULT -//CHECK-DDEFAULT: llvm.fmuladd{{.*}} -#endif -#if EBSTRICT -//CHECK-DEBSTRICT: contract float {{.*}}llvm.fmuladd{{.*}} -#endif -#if NOHONOR -//CHECK-NOHONOR: contract float {{.*}}llvm.fmuladd{{.*}} -#endif -#if FAST -//CHECK-FAST: contract float {{.*}}llvm.fmuladd{{.*}} -#endif - -#ifndef FAST -// Rule: precise must be enabled -#pragma float_control(except, on) -#endif - float y(); -class ON { - // Settings for top level class initializer revert to command line - // source pragma's do not pertain. - float z = 2 + y() * 7; -//CHECK-LABEL: define {{.*}} void @_ZN2ONC2Ev{{.*}} -#if DEFAULT -//CHECK-DDEFAULT: call contract float {{.*}}llvm.fmuladd -#endif -#if EBSTRICT -//Currently, same as default [command line options not considered] -//CHECK-DEBSTRICT: call contract float {{.*}}llvm.fmuladd -#endif -#if NOHONOR -//CHECK-NOHONOR: call nnan ninf contract float @llvm.fmuladd{{.*}} -#endif -#if FAST -//CHECK-FAST: fmul fast float -//CHECK-FAST: fadd fast float -#endif -}; -ON on; -#pragma float_control(except, off) -class OFF { - float w = 2 + y() * 7; -//CHECK-LABEL: define {{.*}} void @_ZN3OFFC2Ev{{.*}} -#if DEFAULT -//CHECK-DDEFAULT: call contract float {{.*}}llvm.fmuladd -#endif -#if EBSTRICT -//CHECK-DEBSTRICT: call contract float {{.*}}llvm.fmuladd -#endif -#if NOHONOR -//CHECK-NOHONOR: call nnan ninf contract float @llvm.fmuladd{{.*}} -#endif -#if FAST -//CHECK-FAST: fmul fast float -//CHECK-FAST: fadd fast float -#endif -}; -OFF off; diff --git a/clang/test/CodeGen/fpconstrained.c b/clang/test/CodeGen/fpconstrained.c index 902d6b5..0a890e2e 100644 --- a/clang/test/CodeGen/fpconstrained.c +++ b/clang/test/CodeGen/fpconstrained.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -ftrapping-math -frounding-math -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s -check-prefix=FPMODELSTRICT // RUN: %clang_cc1 -ffp-contract=fast -emit-llvm -o - %s | FileCheck %s -check-prefix=PRECISE // RUN: %clang_cc1 -ffast-math -ffp-contract=fast -emit-llvm -o - %s | FileCheck %s -check-prefix=FAST -// RUN: %clang_cc1 -ffast-math -emit-llvm -o - %s | FileCheck %s -check-prefix=FASTNOCONTRACT +// RUN: %clang_cc1 -ffast-math -emit-llvm -o - %s | FileCheck %s -check-prefix=FAST // RUN: %clang_cc1 -ffast-math -ffp-contract=fast -ffp-exception-behavior=ignore -emit-llvm -o - %s | FileCheck %s -check-prefix=FAST // RUN: %clang_cc1 -ffast-math -ffp-contract=fast -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s -check-prefix=EXCEPT // RUN: %clang_cc1 -ffast-math -ffp-contract=fast -ffp-exception-behavior=maytrap -emit-llvm -o - %s | FileCheck %s -check-prefix=MAYTRAP @@ -17,7 +17,6 @@ void foo() { // STRICTNOEXCEPT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.dynamic", metadata !"fpexcept.ignore") // PRECISE: fadd contract float %{{.*}}, %{{.*}} // FAST: fadd fast - // FASTNOCONTRACT: fadd reassoc nnan ninf nsz arcp afn float f0 = f1 + f2; // CHECK: ret diff --git a/clang/test/CodeGen/fpconstrained.cpp b/clang/test/CodeGen/fpconstrained.cpp index e914abc..7aa34c9 100644 --- a/clang/test/CodeGen/fpconstrained.cpp +++ b/clang/test/CodeGen/fpconstrained.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -x c++ -ftrapping-math -fexceptions -fcxx-exceptions -frounding-math -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s -check-prefix=FPMODELSTRICT // RUN: %clang_cc1 -x c++ -ffp-contract=fast -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix=PRECISE // RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions -ffp-contract=fast -emit-llvm -o - %s | FileCheck %s -check-prefix=FAST -// RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix=FASTNOCONTRACT +// RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix=FAST // RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions -ffp-contract=fast -ffp-exception-behavior=ignore -emit-llvm -o - %s | FileCheck %s -check-prefix=FAST // RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions -ffp-contract=fast -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck %s -check-prefix=EXCEPT // RUN: %clang_cc1 -x c++ -ffast-math -fexceptions -fcxx-exceptions -ffp-contract=fast -ffp-exception-behavior=maytrap -emit-llvm -o - %s | FileCheck %s -check-prefix=MAYTRAP @@ -20,17 +20,16 @@ float f0, f1, f2; // CHECK-LABEL: define {{.*}}void @_ZN4aaaaIiED2Ev{{.*}} } catch (...) { - // MAYTRAP: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.maytrap") - // EXCEPT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") - // FPMODELSTRICT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") - // STRICTEXCEPT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") - // STRICTNOEXCEPT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.dynamic", metadata !"fpexcept.ignore") - // PRECISE: fadd contract float %{{.*}}, %{{.*}} - // FAST: fadd fast - // FASTNOCONTRACT: fadd reassoc nnan ninf nsz arcp afn float - f0 = f1 + f2; + // MAYTRAP: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.maytrap") + // EXCEPT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") + // FPMODELSTRICT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") + // STRICTEXCEPT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.dynamic", metadata !"fpexcept.strict") + // STRICTNOEXCEPT: llvm.experimental.constrained.fadd.f32(float %{{.*}}, float %{{.*}}, metadata !"round.dynamic", metadata !"fpexcept.ignore") + // PRECISE: fadd contract float %{{.*}}, %{{.*}} + // FAST: fadd fast + f0 = f1 + f2; - // CHECK: ret void + // CHECK: ret void } } diff --git a/clang/test/CodeGenOpenCL/relaxed-fpmath.cl b/clang/test/CodeGenOpenCL/relaxed-fpmath.cl index 757a2f4..7676ee1 100644 --- a/clang/test/CodeGenOpenCL/relaxed-fpmath.cl +++ b/clang/test/CodeGenOpenCL/relaxed-fpmath.cl @@ -8,12 +8,12 @@ float spscalardiv(float a, float b) { // CHECK: @spscalardiv( - // NORMAL: fdiv contract float + // NORMAL: fdiv float // FAST: fdiv fast float - // FINITE: fdiv nnan ninf contract float - // UNSAFE: fdiv nnan nsz contract float - // MAD: fdiv contract float - // NOSIGNED: fdiv nsz contract float + // FINITE: fdiv nnan ninf float + // UNSAFE: fdiv nnan nsz float + // MAD: fdiv float + // NOSIGNED: fdiv nsz float return a / b; } // CHECK: attributes diff --git a/clang/test/CodeGenOpenCL/single-precision-constant.cl b/clang/test/CodeGenOpenCL/single-precision-constant.cl index 061025d..6ff7bd1 100644 --- a/clang/test/CodeGenOpenCL/single-precision-constant.cl +++ b/clang/test/CodeGenOpenCL/single-precision-constant.cl @@ -1,6 +1,6 @@ // RUN: %clang_cc1 %s -cl-single-precision-constant -emit-llvm -o - | FileCheck %s float fn(float f) { - // CHECK: tail call contract float @llvm.fmuladd.f32(float %f, float 2.000000e+00, float 1.000000e+00) + // CHECK: tail call float @llvm.fmuladd.f32(float %f, float 2.000000e+00, float 1.000000e+00) return f*2. + 1.; } diff --git a/clang/test/Headers/nvptx_device_math_sin.c b/clang/test/Headers/nvptx_device_math_sin.c index 83de8b0..75b998d 100644 --- a/clang/test/Headers/nvptx_device_math_sin.c +++ b/clang/test/Headers/nvptx_device_math_sin.c @@ -1,8 +1,8 @@ // REQUIRES: nvptx-registered-target // RUN: %clang_cc1 -x c -internal-isystem %S/Inputs/include -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc // RUN: %clang_cc1 -x c -include __clang_openmp_device_functions.h -internal-isystem %S/../../lib/Headers/openmp_wrappers -internal-isystem %S/Inputs/include -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix=SLOW -// RUN: %clang_cc1 -x c -internal-isystem %S/Inputs/include -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -ffast-math -ffp-contract=fast -// RUN: %clang_cc1 -x c -include __clang_openmp_device_functions.h -internal-isystem %S/../../lib/Headers/openmp_wrappers -internal-isystem %S/Inputs/include -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -ffast-math -ffp-contract=fast | FileCheck %s --check-prefix=FAST +// RUN: %clang_cc1 -x c -internal-isystem %S/Inputs/include -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -ffast-math +// RUN: %clang_cc1 -x c -include __clang_openmp_device_functions.h -internal-isystem %S/../../lib/Headers/openmp_wrappers -internal-isystem %S/Inputs/include -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -ffast-math | FileCheck %s --check-prefix=FAST // expected-no-diagnostics #include diff --git a/clang/test/Headers/nvptx_device_math_sin.cpp b/clang/test/Headers/nvptx_device_math_sin.cpp index ba5f6fc..e4d25b4 100644 --- a/clang/test/Headers/nvptx_device_math_sin.cpp +++ b/clang/test/Headers/nvptx_device_math_sin.cpp @@ -1,8 +1,8 @@ // REQUIRES: nvptx-registered-target // RUN: %clang_cc1 -x c++ -internal-isystem %S/Inputs/include -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc // RUN: %clang_cc1 -x c++ -include __clang_openmp_device_functions.h -internal-isystem %S/../../lib/Headers/openmp_wrappers -internal-isystem %S/Inputs/include -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix=SLOW -// RUN: %clang_cc1 -x c++ -internal-isystem %S/Inputs/include -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -ffast-math -ffp-contract=fast -// RUN: %clang_cc1 -x c++ -include __clang_openmp_device_functions.h -internal-isystem %S/../../lib/Headers/openmp_wrappers -internal-isystem %S/Inputs/include -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -ffast-math -ffp-contract=fast | FileCheck %s --check-prefix=FAST +// RUN: %clang_cc1 -x c++ -internal-isystem %S/Inputs/include -fopenmp -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -ffast-math +// RUN: %clang_cc1 -x c++ -include __clang_openmp_device_functions.h -internal-isystem %S/../../lib/Headers/openmp_wrappers -internal-isystem %S/Inputs/include -fopenmp -triple nvptx64-nvidia-cuda -aux-triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -ffast-math | FileCheck %s --check-prefix=FAST // expected-no-diagnostics #include diff --git a/clang/test/PCH/pragma-floatcontrol.c b/clang/test/PCH/pragma-floatcontrol.c deleted file mode 100644 index a0918dd..0000000 --- a/clang/test/PCH/pragma-floatcontrol.c +++ /dev/null @@ -1,55 +0,0 @@ -// Test this without pch. -// RUN: %clang_cc1 %s -include %s -verify -fsyntax-only -DSET -// RUN: %clang_cc1 %s -include %s -verify -fsyntax-only -DPUSH -// RUN: %clang_cc1 %s -include %s -verify -fsyntax-only -DPUSH_POP - -// Test with pch. -// RUN: %clang_cc1 %s -DSET -emit-pch -o %t -// RUN: %clang_cc1 %s -DSET -include-pch %t -emit-llvm -o - | FileCheck --check-prefix=CHECK-EBSTRICT %s -// RUN: %clang_cc1 %s -DPUSH -emit-pch -o %t -// RUN: %clang_cc1 %s -DPUSH -verify -include-pch %t -// RUN: %clang_cc1 %s -DPUSH_POP -emit-pch -o %t -// RUN: %clang_cc1 %s -DPUSH_POP -verify -include-pch %t - -#ifndef HEADER -#define HEADER - -#ifdef SET -#pragma float_control(except, on) -#endif - -#ifdef PUSH -#pragma float_control(precise, on) -#pragma float_control(push) -#pragma float_control(precise, off) -#endif - -#ifdef PUSH_POP -#pragma float_control(precise, on, push) -#pragma float_control(push) -#pragma float_control(pop) -#endif -#else - -#ifdef SET -float fun(float a, float b) { - // CHECK-LABEL: define float @fun{{.*}} - //CHECK-EBSTRICT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict - //CHECK-EBSTRICT: llvm.experimental.constrained.fadd{{.*}}tonearest{{.*}}strict - return a * b + 2; -} -#pragma float_control(pop) // expected-warning {{#pragma float_control(pop, ...) failed: stack empty}} -#pragma float_control(pop) // expected-warning {{#pragma float_control(pop, ...) failed: stack empty}} -#endif - -#ifdef PUSH -#pragma float_control(pop) -#pragma float_control(pop) // expected-warning {{#pragma float_control(pop, ...) failed: stack empty}} -#endif - -#ifdef PUSH_POP -#pragma float_control(pop) -#pragma float_control(pop) // expected-warning {{#pragma float_control(pop, ...) failed: stack empty}} -#endif - -#endif //ifndef HEADER diff --git a/clang/test/Parser/fp-floatcontrol-syntax.cpp b/clang/test/Parser/fp-floatcontrol-syntax.cpp deleted file mode 100644 index a0e0b02..0000000 --- a/clang/test/Parser/fp-floatcontrol-syntax.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -DCHECK_ERROR %s - -float function_scope(float a) { -#pragma float_control(precise, on) junk // expected-warning {{extra tokens at end of '#pragma float_control' - ignored}} - return a; -} - -#ifdef CHECK_ERROR -#pragma float_control(push) -#pragma float_control(pop) -#pragma float_control(precise, on, push) -void check_stack() { -#pragma float_control(push) // expected-error {{can only appear at file scope}} -#pragma float_control(pop) // expected-error {{can only appear at file scope}} -#pragma float_control(precise, on, push) // expected-error {{can only appear at file scope}} -#pragma float_control(except, on, push) // expected-error {{can only appear at file scope}} -#pragma float_control(except, on, push, junk) // expected-error {{float_control is malformed}} - return; -} -#endif - -// RUN: %clang -c -fsyntax-only %s -DDEFAULT -Xclang -verify -// RUN: %clang -c -fsyntax-only %s -ffp-model=precise -DPRECISE -Xclang -verify -// RUN: %clang -c -fsyntax-only %s -ffp-model=strict -DSTRICT -Xclang -verify -// RUN: %clang -c -fsyntax-only %s -ffp-model=fast -DFAST -Xclang -verify -double a = 0.0; -double b = 1.0; - -//FIXME At some point this warning will be removed, until then -// document the warning -#ifdef FAST -// expected-warning@+1{{pragma STDC FENV_ACCESS ON is not supported, ignoring pragma}} -#pragma STDC FENV_ACCESS ON // expected-error{{'#pragma STDC FENV_ACCESS ON' is illegal when precise is disabled}} -#else -#pragma STDC FENV_ACCESS ON // expected-warning{{pragma STDC FENV_ACCESS ON is not supported, ignoring pragma}} -#endif -#ifdef STRICT -#pragma float_control(precise, off) // expected-error {{'#pragma float_control(precise, off)' is illegal when except is enabled}} -#else -#pragma float_control(precise, off) // expected-error {{'#pragma float_control(precise, off)' is illegal when fenv_access is enabled}} -#endif -//RUN -ffp-model=strict -//error: '#pragma float_control(precise, off)' is illegal when except is enabled -//with default, fast or precise: no errors - -#pragma float_control(precise, on) -#pragma float_control(except, on) // OK -#ifndef STRICT -#pragma float_control(except, on) -#pragma float_control(precise, off) // expected-error {{'#pragma float_control(precise, off)' is illegal when except is enabled}} -#endif -int main() { -#ifdef STRICT -#pragma float_control(precise, off) // expected-error {{'#pragma float_control(precise, off)' is illegal when except is enabled}} -#else -#pragma float_control(precise, off) // expected-error {{'#pragma float_control(precise, off)' is illegal when except is enabled}} -#endif -#pragma float_control(except, on) - // error: '#pragma float_control(except, on)' is illegal when precise is disabled - double x = b / a; // only used for fp flag setting - if (a == a) // only used for fp flag setting - return 0; //(int)x; -} diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index 6e431bc..8a93126 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -244,8 +244,6 @@ public: /// Get the flags to be applied to created floating point ops FastMathFlags getFastMathFlags() const { return FMF; } - FastMathFlags &getFastMathFlags() { return FMF; } - /// Clear the fast-math flags. void clearFastMathFlags() { FMF.clear(); } @@ -334,16 +332,10 @@ public: IRBuilderBase &Builder; FastMathFlags FMF; MDNode *FPMathTag; - bool IsFPConstrained; - fp::ExceptionBehavior DefaultConstrainedExcept; - RoundingMode DefaultConstrainedRounding; public: FastMathFlagGuard(IRBuilderBase &B) - : Builder(B), FMF(B.FMF), FPMathTag(B.DefaultFPMathTag), - IsFPConstrained(B.IsFPConstrained), - DefaultConstrainedExcept(B.DefaultConstrainedExcept), - DefaultConstrainedRounding(B.DefaultConstrainedRounding) {} + : Builder(B), FMF(B.FMF), FPMathTag(B.DefaultFPMathTag) {} FastMathFlagGuard(const FastMathFlagGuard &) = delete; FastMathFlagGuard &operator=(const FastMathFlagGuard &) = delete; @@ -351,9 +343,6 @@ public: ~FastMathFlagGuard() { Builder.FMF = FMF; Builder.DefaultFPMathTag = FPMathTag; - Builder.IsFPConstrained = IsFPConstrained; - Builder.DefaultConstrainedExcept = DefaultConstrainedExcept; - Builder.DefaultConstrainedRounding = DefaultConstrainedRounding; } };