diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 9e8bac635337ea..244212a1336dbc 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -1478,26 +1478,6 @@ Note that floating-point operations performed as part of constant initialization * ``maytrap`` The compiler avoids transformations that may raise exceptions that would not have been raised by the original code. Constant folding performed by the compiler is exempt from this option. * ``strict`` The compiler ensures that all transformations strictly preserve the floating point exception semantics of the original code. -.. option:: -f[no-]protect-parens: - - This option pertains to floating-point types, complex types with - floating-point components, and vectors of these types. Some arithmetic - expression transformations that are mathematically correct and permissible - according to the C and C++ language standards may be incorrect when dealing - with floating-point types, such as reassociation and distribution. Further, - the optimizer may ignore parentheses when computing arithmetic expressions - in circumstances where the parenthesized and unparenthesized expression - express the same mathematical value. For example (a+b)+c is the same - mathematical value as a+(b+c), but the optimizer is free to evaluate the - additions in any order regardless of the parentheses. When enabled, this - option forces the optimizer to honor the order of operations with respect - to parentheses in all circumstances. - - Note that floating-point contraction (option `-ffp-contract=`) is disabled - when `-fprotect-parens` is enabled. Also note that in safe floating-point - modes, such as `-ffp-model=precise` or `-ffp-model=strict`, this option - has no effect because the optimizer is prohibited from making unsafe - transformations. .. _fp-constant-eval: diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def index 33d3e6dc4e7db4..5a9d0a0018292a 100644 --- a/clang/include/clang/Basic/Builtins.def +++ b/clang/include/clang/Basic/Builtins.def @@ -1657,9 +1657,6 @@ BUILTIN(__builtin_ms_va_start, "vc*&.", "nt") BUILTIN(__builtin_ms_va_end, "vc*&", "n") BUILTIN(__builtin_ms_va_copy, "vc*&c*&", "n") -// Arithmetic Fence: to prevent FP reordering and reassociation optimizations -LANGBUILTIN(__arithmetic_fence, "v.", "t", ALL_LANGUAGES) - #undef BUILTIN #undef LIBBUILTIN #undef LANGBUILTIN diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 22c2a1a39ea13b..70a22fd2506a31 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -8530,9 +8530,6 @@ def err_typecheck_expect_scalar_operand : Error< "operand of type %0 where arithmetic or pointer type is required">; def err_typecheck_cond_incompatible_operands : Error< "incompatible operand types%diff{ ($ and $)|}0,1">; -def err_typecheck_expect_flt_or_vector : Error< - "invalid operand of type %0 where floating, complex or " - "a vector of such types is required">; def err_cast_selector_expr : Error< "cannot type cast @selector expression">; def ext_typecheck_cond_incompatible_pointers : ExtWarn< diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index b18e957a58f4c1..465bad8d7d1121 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -199,8 +199,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(ProtectParens , 1, 0, "optimizer honors parentheses " - "when floating-point expressions are evaluated") BENIGN_LANGOPT(AllowFPReassoc , 1, 0, "Permit Floating Point reassociation") BENIGN_LANGOPT(NoHonorNaNs , 1, 0, "Permit Floating Point optimization without regard to NaN") BENIGN_LANGOPT(NoHonorInfs , 1, 0, "Permit Floating Point optimization without regard to infinities") diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 0e984eb29b8150..d59bad30e74288 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -1424,9 +1424,6 @@ class TargetInfo : public virtual TransferrableTargetInfo, /// Whether the option -fextend-arguments={32,64} is supported on the target. virtual bool supportsExtendIntArgs() const { return false; } - /// Controls if __arithmetic_fence is supported in the targeted backend. - virtual bool checkArithmeticFenceSupported() const { return false; } - /// Gets the default calling convention for the given target and /// declaration context. virtual CallingConv getDefaultCallingConv() const { diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 0b9596c68f5fb8..f1455f5461990a 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1762,13 +1762,6 @@ defm strict_float_cast_overflow : BoolFOption<"strict-float-cast-overflow", " of the target's native float-to-int conversion instructions">, PosFlag>; -defm protect_parens : BoolFOption<"protect-parens", - LangOpts<"ProtectParens">, DefaultFalse, - PosFlag, - NegFlag>; - def ffor_scope : Flag<["-"], "ffor-scope">, Group; def fno_for_scope : Flag<["-"], "fno-for-scope">, Group; @@ -4415,7 +4408,7 @@ defm integer_4_integer_8 : BooleanFFlag<"integer-4-integer-8">, Group, Group; defm module_private : BooleanFFlag<"module-private">, Group; defm pack_derived : BooleanFFlag<"pack-derived">, Group; -//defm protect_parens : BooleanFFlag<"protect-parens">, Group; +defm protect_parens : BooleanFFlag<"protect-parens">, Group; defm range_check : BooleanFFlag<"range-check">, Group; defm real_4_real_10 : BooleanFFlag<"real-4-real-10">, Group; defm real_4_real_16 : BooleanFFlag<"real-4-real-16">, Group; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 3f7db9bc5be8b5..4c3a7035bcc949 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -36,7 +36,6 @@ #include "clang/AST/TypeLoc.h" #include "clang/AST/TypeOrdering.h" #include "clang/Basic/BitmaskEnum.h" -#include "clang/Basic/Builtins.h" #include "clang/Basic/ExpressionTraits.h" #include "clang/Basic/Module.h" #include "clang/Basic/OpenCLOptions.h" @@ -5425,8 +5424,6 @@ class Sema final { Expr *ExecConfig = nullptr, bool IsExecConfig = false, bool AllowRecovery = false); - Expr *BuildBuiltinCallExpr(SourceLocation Loc, Builtin::ID Id, - MultiExprArg CallArgs); enum class AtomicArgumentOrder { API, AST }; ExprResult BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, @@ -12586,7 +12583,6 @@ class Sema final { private: bool SemaBuiltinPrefetch(CallExpr *TheCall); bool SemaBuiltinAllocaWithAlign(CallExpr *TheCall); - bool SemaBuiltinArithmeticFence(CallExpr *TheCall); bool SemaBuiltinAssume(CallExpr *TheCall); bool SemaBuiltinAssumeAligned(CallExpr *TheCall); bool SemaBuiltinLongjmp(CallExpr *TheCall); diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 01c0168d61a401..a4d8fec09748d8 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -13692,9 +13692,6 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) { Result.changeSign(); return true; - case Builtin::BI__arithmetic_fence: - return EvaluateFloat(E->getArg(0), Result, Info); - // FIXME: Builtin::BI__builtin_powi // FIXME: Builtin::BI__builtin_powif // FIXME: Builtin::BI__builtin_powil diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index ffd88dc75dba11..e73b4a3a40c746 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -430,11 +430,6 @@ void TargetInfo::adjust(LangOptions &Opts) { // its corresponding signed type. PaddingOnUnsignedFixedPoint |= Opts.PaddingOnUnsignedFixedPoint; CheckFixedPointBits(); - - if (Opts.ProtectParens && !checkArithmeticFenceSupported()) { - Diags.Report(diag::err_opt_not_valid_on_target) << "-fprotect-parens"; - Opts.ProtectParens = false; - } } bool TargetInfo::initFeatureMap( diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index e798962617a306..7639ea835ebc7c 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -362,8 +362,6 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { } } - bool checkArithmeticFenceSupported() const override { return true; } - CallingConv getDefaultCallingConv() const override { return CC_C; } diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 6702181e7b7660..2e9454921ffa8e 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -2833,36 +2833,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Function *FnAssume = CGM.getIntrinsic(Intrinsic::assume); return RValue::get(Builder.CreateCall(FnAssume, ArgValue)); } - case Builtin::BI__arithmetic_fence: { - // Create the builtin call if FastMath is selected, and the target - // supports the builtin, otherwise just return the argument. - CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E); - llvm::FastMathFlags FMF = Builder.getFastMathFlags(); - bool isArithmeticFenceEnabled = - FMF.allowReassoc() && - getContext().getTargetInfo().checkArithmeticFenceSupported(); - QualType ArgType = E->getArg(0)->getType(); - if (ArgType->isComplexType()) { - if (isArithmeticFenceEnabled) { - QualType ElementType = ArgType->castAs()->getElementType(); - ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); - Value *Real = Builder.CreateArithmeticFence(ComplexVal.first, - ConvertType(ElementType)); - Value *Imag = Builder.CreateArithmeticFence(ComplexVal.second, - ConvertType(ElementType)); - return RValue::getComplex(std::make_pair(Real, Imag)); - } - ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); - Value *Real = ComplexVal.first; - Value *Imag = ComplexVal.second; - return RValue::getComplex(std::make_pair(Real, Imag)); - } - Value *ArgValue = EmitScalarExpr(E->getArg(0)); - if (isArithmeticFenceEnabled) - return RValue::get( - Builder.CreateArithmeticFence(ArgValue, ConvertType(ArgType))); - return RValue::get(ArgValue); - } case Builtin::BI__builtin_bswap16: case Builtin::BI__builtin_bswap32: case Builtin::BI__builtin_bswap64: { diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index fd26d04e39bcce..c265e1c4e53cb7 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4975,11 +4975,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, false)) CmdArgs.push_back("-fsplit-stack"); - // -fprotect-parens=0 is default. - if (Args.hasFlag(options::OPT_fprotect_parens, - options::OPT_fno_protect_parens, false)) - CmdArgs.push_back("-fprotect-parens"); - RenderFloatingPointOptions(TC, D, OFastEnabled, Args, CmdArgs, JA); if (Arg *A = Args.getLastArg(options::OPT_fextend_args_EQ)) { diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 4d04f3017a2eff..17eeebb0c67991 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1554,10 +1554,6 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, Diag(TheCall->getBeginLoc(), diag::warn_alloca) << TheCall->getDirectCallee(); break; - case Builtin::BI__arithmetic_fence: - if (SemaBuiltinArithmeticFence(TheCall)) - return ExprError(); - break; case Builtin::BI__assume: case Builtin::BI__builtin_assume: if (SemaBuiltinAssume(TheCall)) @@ -6553,29 +6549,6 @@ bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) { return false; } -/// SemaBuiltinArithmeticFence - Handle __arithmetic_fence. -bool Sema::SemaBuiltinArithmeticFence(CallExpr *TheCall) { - if (!Context.getTargetInfo().checkArithmeticFenceSupported()) - return Diag(TheCall->getBeginLoc(), diag::err_builtin_target_unsupported) - << SourceRange(TheCall->getBeginLoc(), TheCall->getEndLoc()); - if (checkArgCount(*this, TheCall, 1)) - return true; - Expr *Arg = TheCall->getArg(0); - if (Arg->isInstantiationDependent()) - return false; - - QualType ArgTy = Arg->getType(); - if (!ArgTy->hasFloatingRepresentation()) - return Diag(TheCall->getEndLoc(), diag::err_typecheck_expect_flt_or_vector) - << ArgTy; - if (Arg->isLValue()) { - ExprResult FirstArg = DefaultLvalueConversion(Arg); - TheCall->setArg(0, FirstArg.get()); - } - TheCall->setType(TheCall->getArg(0)->getType()); - return false; -} - /// SemaBuiltinAssume - Handle __assume (MS Extension). // __assume does not evaluate its arguments, and should warn if its argument // has side effects. diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp index 31a4092b5b6045..cec80436d575e9 100644 --- a/clang/lib/Sema/SemaCoroutine.cpp +++ b/clang/lib/Sema/SemaCoroutine.cpp @@ -291,6 +291,26 @@ static ExprResult buildOperatorCoawaitCall(Sema &SemaRef, Scope *S, cast(R.get())); } +static Expr *buildBuiltinCall(Sema &S, SourceLocation Loc, Builtin::ID Id, + MultiExprArg CallArgs) { + StringRef Name = S.Context.BuiltinInfo.getName(Id); + LookupResult R(S, &S.Context.Idents.get(Name), Loc, Sema::LookupOrdinaryName); + S.LookupName(R, S.TUScope, /*AllowBuiltinCreation=*/true); + + auto *BuiltInDecl = R.getAsSingle(); + assert(BuiltInDecl && "failed to find builtin declaration"); + + ExprResult DeclRef = + S.BuildDeclRefExpr(BuiltInDecl, BuiltInDecl->getType(), VK_LValue, Loc); + assert(DeclRef.isUsable() && "Builtin reference cannot fail"); + + ExprResult Call = + S.BuildCallExpr(/*Scope=*/nullptr, DeclRef.get(), Loc, CallArgs, Loc); + + assert(!Call.isInvalid() && "Call to builtin cannot fail!"); + return Call.get(); +} + static ExprResult buildCoroutineHandle(Sema &S, QualType PromiseType, SourceLocation Loc) { QualType CoroHandleType = lookupCoroutineHandleType(S, PromiseType, Loc); @@ -307,7 +327,7 @@ static ExprResult buildCoroutineHandle(Sema &S, QualType PromiseType, } Expr *FramePtr = - S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_frame, {}); + buildBuiltinCall(S, Loc, Builtin::BI__builtin_coro_frame, {}); CXXScopeSpec SS; ExprResult FromAddr = @@ -384,8 +404,8 @@ static Expr *maybeTailCall(Sema &S, QualType RetType, Expr *E, // the resume call and return instruction, which would interfere with the // musttail call contract. JustAddress = S.MaybeCreateExprWithCleanups(JustAddress); - return S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_resume, - JustAddress); + return buildBuiltinCall(S, Loc, Builtin::BI__builtin_coro_resume, + JustAddress); } /// Build calls to await_ready, await_suspend, and await_resume for a co_await @@ -1337,10 +1357,10 @@ bool CoroutineStmtBuilder::makeNewAndDeleteExpr() { return false; Expr *FramePtr = - S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_frame, {}); + buildBuiltinCall(S, Loc, Builtin::BI__builtin_coro_frame, {}); Expr *FrameSize = - S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_size, {}); + buildBuiltinCall(S, Loc, Builtin::BI__builtin_coro_size, {}); // Make new call. @@ -1369,7 +1389,7 @@ bool CoroutineStmtBuilder::makeNewAndDeleteExpr() { return false; Expr *CoroFree = - S.BuildBuiltinCallExpr(Loc, Builtin::BI__builtin_coro_free, {FramePtr}); + buildBuiltinCall(S, Loc, Builtin::BI__builtin_coro_free, {FramePtr}); SmallVector DeleteArgs{CoroFree}; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 3df74b5ea9dbc4..6031dff6733515 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4054,10 +4054,6 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { ExprResult Sema::ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E) { assert(E && "ActOnParenExpr() missing expr"); - QualType ExprTy = E->getType(); - if (getLangOpts().ProtectParens && CurFPFeatures.getAllowFPReassociate() && - !E->isLValue() && ExprTy->hasFloatingRepresentation()) - return BuildBuiltinCallExpr(R, Builtin::BI__arithmetic_fence, E); return new (Context) ParenExpr(L, R, E); } @@ -6564,29 +6560,6 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc, ExecConfig, IsExecConfig); } -/// BuildBuiltinCallExpr - Create a call to a builtin function specified by Id -// with the specified CallArgs -Expr *Sema::BuildBuiltinCallExpr(SourceLocation Loc, Builtin::ID Id, - MultiExprArg CallArgs) { - StringRef Name = Context.BuiltinInfo.getName(Id); - LookupResult R(*this, &Context.Idents.get(Name), Loc, - Sema::LookupOrdinaryName); - LookupName(R, TUScope, /*AllowBuiltinCreation=*/true); - - auto *BuiltInDecl = R.getAsSingle(); - assert(BuiltInDecl && "failed to find builtin declaration"); - - ExprResult DeclRef = - BuildDeclRefExpr(BuiltInDecl, BuiltInDecl->getType(), VK_LValue, Loc); - assert(DeclRef.isUsable() && "Builtin reference cannot fail"); - - ExprResult Call = - BuildCallExpr(/*Scope=*/nullptr, DeclRef.get(), Loc, CallArgs, Loc); - - assert(!Call.isInvalid() && "Call to builtin cannot fail!"); - return Call.get(); -} - /// Parse a __builtin_astype expression. /// /// __builtin_astype( value, dst type ) diff --git a/clang/test/AST/arithmetic-fence-builtin.c b/clang/test/AST/arithmetic-fence-builtin.c deleted file mode 100644 index 46666b3c8bed55..00000000000000 --- a/clang/test/AST/arithmetic-fence-builtin.c +++ /dev/null @@ -1,46 +0,0 @@ -// Tests without serialization: -// RUN: %clang_cc1 -ast-dump -triple i386-pc-linux-gnu %s \ -// RUN: | FileCheck %s --strict-whitespace --check-prefixes=CHECK,CHECK1 -// -// RUN: %clang_cc1 -ast-dump -triple i386-pc-linux-gnu -DFAST -mreassociate %s \ -// RUN: | FileCheck %s --strict-whitespace --check-prefixes=CHECK,CHECK1 -// -// RUN: %clang_cc1 -ast-dump -triple i386-pc-linux-gnu -DFAST -mreassociate %s \ -// RUN: -fprotect-parens \ -// RUN: | FileCheck %s --strict-whitespace --check-prefixes=CHECK,CHECK2 -// -// Tests with serialization: -// RUN: %clang_cc1 -ast-dump -triple i386-pc-linux-gnu -emit-pch -o %t %s -// RUN: %clang_cc1 -triple i386-pc-linux-gnu -include-pch %t -ast-dump-all /dev/null \ -// RUN: | FileCheck %s --strict-whitespace -// -// RUN: %clang_cc1 -ast-dump -triple i386-pc-linux-gnu -DFAST -mreassociate %s \ -// RUN: -emit-pch -o %t -// RUN: %clang_cc1 -triple i386-pc-linux-gnu -include-pch %t -ast-dump-all /dev/null \ -// RUN: | FileCheck %s --strict-whitespace --check-prefixes=CHECK,CHECK1 -// -// RUN: %clang_cc1 -ast-dump -triple i386-pc-linux-gnu -DFAST -mreassociate %s \ -// RUN: -fprotect-parens \ -// RUN: -emit-pch -o %t -// RUN: %clang_cc1 -triple i386-pc-linux-gnu -include-pch %t -ast-dump-all /dev/null -fprotect-parens\ -// RUN: | FileCheck %s --strict-whitespace --check-prefixes=CHECK,CHECK2 - -// -int v; -int addit(float a, float b) { - - v = __arithmetic_fence(a + b); - - v = (a + b); - - return 0; -} -//CHECK:| `-CompoundStmt {{.*}} -//CHECK-NEXT:| |-BinaryOperator {{.*}} 'int' '=' -//CHECK-NEXT:| | |-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'v' 'int' -//CHECK-NEXT:| | `-ImplicitCastExpr {{.*}} -//CHECK-NEXT:| | `-CallExpr {{.*}} 'float' -//CHECK-NEXT:| | |-ImplicitCastExpr {{.*}} -//CHECK-NEXT:| | | `-DeclRefExpr {{.*}}' Function {{.*}} '__arithmetic_fence'{{.*}} -//CHECK1-NOT:| | | `-DeclRefExpr {{.*}}' Function{{.*}} '__arithmetic_fence' 'void ()' -//CHECK2:| | | `-DeclRefExpr {{.*}} Function{{.*}} '__arithmetic_fence' 'void ()' diff --git a/clang/test/CodeGen/arithmetic-fence-builtin.c b/clang/test/CodeGen/arithmetic-fence-builtin.c deleted file mode 100644 index 6b5b5b4b9cefa8..00000000000000 --- a/clang/test/CodeGen/arithmetic-fence-builtin.c +++ /dev/null @@ -1,74 +0,0 @@ -// Test with fast math -// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -DFAST \ -// RUN: -mreassociate \ -// RUN: -o - %s | FileCheck --check-prefixes CHECK,CHECKFAST,CHECKNP %s -// -// Test with fast math and fprotect-parens -// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -DFAST \ -// RUN: -mreassociate -fprotect-parens -ffp-contract=on\ -// RUN: -o - %s | FileCheck --check-prefixes CHECK,CHECKFAST,CHECKPP %s -// -// Test without fast math: llvm intrinsic not created -// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -fprotect-parens\ -// RUN: -o - %s | FileCheck --implicit-check-not="llvm.arithmetic.fence" %s -// -int v; -int addit(float a, float b) { - // CHECK: define {{.*}}@addit(float %a, float %b) #0 { - _Complex double cd, cd1; - cd = __arithmetic_fence(cd1); - // CHECKFAST: call{{.*}} double @llvm.arithmetic.fence.f64({{.*}}real) - // CHECKFAST: call{{.*}} double @llvm.arithmetic.fence.f64({{.*}}imag) - // Vector should be supported. - typedef float __v2f32 __attribute__((__vector_size__(8))); - __v2f32 vec1, vec2; - vec1 = __arithmetic_fence(vec2); - // CHECKFAST: call{{.*}} <2 x float> @llvm.arithmetic.fence.v2f32 - vec2 = (vec2 + vec1); - // CHECKPP: call{{.*}} <2 x float> @llvm.arithmetic.fence.v2f32 - - v = __arithmetic_fence(a + b); - // CHECKFAST: call{{.*}} float @llvm.arithmetic.fence.f32(float %add{{.*}}) - - v = (a + b); - // CHECKPP: call{{.*}} float @llvm.arithmetic.fence.f32(float %add{{.*}}) - v = a + (b*b); - // CHECKPP: fmul reassoc - // CHECKPP-NEXT: call{{.*}} float @llvm.arithmetic.fence.f32(float %mul) - // CHECKNP: fmul - // CHECKNP: fadd - v = b + a*a; - // CHECKPP: call{{.*}} float @llvm.fmuladd.f32 - // CHECKNP: fmul - // CHECKNP: fadd - v = b + __arithmetic_fence(a*a); // Fence blocks recognition of FMA - // CHECKPP: fmul - // CHECKNP: fmul - - b = (a); - (a) = b; - // CHECK-NEXT fptosi - // CHECK-NEXT store i32 - // CHECK-NEXT load float - // CHECK-NEXT store float - // CHECK-NEXT load float - // CHECK-NEXT store float - return 0; - // CHECK-NEXT ret i32 0 -} -int addit1(int a, int b) { - // CHECK: define {{.*}}@addit1(i32 %a, i32 %b{{.*}} - v = (a + b); - // CHECK-NOT: call{{.*}} float @llvm.arithmetic.fence.int(float %add) - return 0; -} -#ifdef FAST -#pragma float_control(precise, on) -int subit(float a, float b, float *fp) { - // CHECKFAST: define {{.*}}@subit(float %a, float %b{{.*}} - *fp = __arithmetic_fence(a - b); - *fp = (a + b); - // CHECK-NOT: call{{.*}} float @llvm.arithmetic.fence.f32(float %add) - return 0; -} -#endif diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c index d729378403f3f4..a255f68713aec0 100644 --- a/clang/test/Driver/clang_f_opts.c +++ b/clang/test/Driver/clang_f_opts.c @@ -1,14 +1,13 @@ // REQUIRES: clang-driver // RUN: %clang -### -S -fasm -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-blocks -fno-builtin -fmath-errno -fno-common -fno-pascal-strings -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings -fsplit-stack %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS1 %s -// RUN: %clang -### -S -fasm -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-asm -fno-blocks -fno-builtin -fmath-errno -fno-common -fno-pascal-strings -fno-show-source-location -fshort-enums -fprotect-parens %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS2 %s +// RUN: %clang -### -S -fasm -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-asm -fno-blocks -fno-builtin -fmath-errno -fno-common -fno-pascal-strings -fno-show-source-location -fshort-enums %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS2 %s // CHECK-OPTIONS1: -fsplit-stack // CHECK-OPTIONS1: -fgnu-keywords // CHECK-OPTIONS1: -fblocks // CHECK-OPTIONS1: -fpascal-strings -// CHECK-OPTIONS2: -fprotect-parens // CHECK-OPTIONS2: -fmath-errno // CHECK-OPTIONS2: -fno-gnu-keywords // CHECK-OPTIONS2: -fno-builtin diff --git a/clang/test/Sema/arithmetic-fence-builtin.c b/clang/test/Sema/arithmetic-fence-builtin.c deleted file mode 100644 index 4f4f0a02cde9ec..00000000000000 --- a/clang/test/Sema/arithmetic-fence-builtin.c +++ /dev/null @@ -1,48 +0,0 @@ -// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -o - -verify -x c++ %s -// RUN: %clang_cc1 -triple ppc64le -DPPC -emit-llvm -o - -verify -x c++ %s -// RUN: not %clang_cc1 -triple ppc64le -DPPC -emit-llvm -o - -x c++ %s \ -// RUN: -fprotect-parens 2>&1 | FileCheck -check-prefix=PPC %s -#ifndef PPC -int v; -template T addT(T a, T b) { - T *q = __arithmetic_fence(&a); - // expected-error@-1 {{invalid operand of type 'float *' where floating, complex or a vector of such types is required}} - // expected-error@-2 {{invalid operand of type 'int *' where floating, complex or a vector of such types is required}} - return __arithmetic_fence(a + b); - // expected-error@-1 {{invalid operand of type 'int' where floating, complex or a vector of such types is required}} -} -int addit(int a, int b) { - float x, y; - typedef struct { - int a, b; - } stype; - stype s; - s = __arithmetic_fence(s); // expected-error {{invalid operand of type 'stype' where floating, complex or a vector of such types is required}} - x = __arithmetic_fence(); // expected-error {{too few arguments to function call, expected 1, have 0}} - x = __arithmetic_fence(x, y); // expected-error {{too many arguments to function call, expected 1, have 2}} - // Complex is supported. - _Complex double cd, cd1; - cd = __arithmetic_fence(cd1); - // Vector is supported. - typedef float __v4hi __attribute__((__vector_size__(8))); - __v4hi vec1, vec2; - vec1 = __arithmetic_fence(vec2); - - v = __arithmetic_fence(a + b); // expected-error {{invalid operand of type 'int' where floating, complex or a vector of such types is required}} - float f = addT(a, b); // expected-note {{in instantiation of function template specialization 'addT' requested here}} - int i = addT(1, 2); // expected-note {{in instantiation of function template specialization 'addT' requested here}} - constexpr float d = 1.0 + 2.0; - constexpr float c = __arithmetic_fence(1.0 + 2.0); - constexpr float e = __arithmetic_fence(d); - return 0; -} -bool func(float f1, float f2, float f3) { - return (f1 == f2 && f1 == f3) || f2 == f3; // Should not warn here -} -static_assert( __arithmetic_fence(1.0 + 2.0), "message" ); -#else -float addit(float a, float b) { - return __arithmetic_fence(a+b); // expected-error {{builtin is not supported on this target}} -} -#endif -//PPC: error: option '-fprotect-parens' cannot be specified on this target