forked from OSchip/llvm-project
Revert "[clang][patch][fpenv] Add builtin __arithmetic_fence and option fprotect-parens"
This reverts commit 4f1238e44d
.
Buildbot fails on predecessor patch
This commit is contained in:
parent
8815ef823c
commit
c27e5a2a8e
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -1424,9 +1424,6 @@ public:
|
|||
/// 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 {
|
||||
|
|
|
@ -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<SetTrue, [], "Assume that overflowing float-to-int casts are undefined (default)">>;
|
||||
|
||||
defm protect_parens : BoolFOption<"protect-parens",
|
||||
LangOpts<"ProtectParens">, DefaultFalse,
|
||||
PosFlag<SetTrue, [CoreOption, CC1Option],
|
||||
"Determines whether the optimizer honors parentheses when "
|
||||
"floating-point expressions are evaluated">,
|
||||
NegFlag<SetFalse>>;
|
||||
|
||||
def ffor_scope : Flag<["-"], "ffor-scope">, Group<f_Group>;
|
||||
def fno_for_scope : Flag<["-"], "fno-for-scope">, Group<f_Group>;
|
||||
|
||||
|
@ -4415,7 +4408,7 @@ defm integer_4_integer_8 : BooleanFFlag<"integer-4-integer-8">, Group<gfortran_G
|
|||
defm max_identifier_length : BooleanFFlag<"max-identifier-length">, Group<gfortran_Group>;
|
||||
defm module_private : BooleanFFlag<"module-private">, Group<gfortran_Group>;
|
||||
defm pack_derived : BooleanFFlag<"pack-derived">, Group<gfortran_Group>;
|
||||
//defm protect_parens : BooleanFFlag<"protect-parens">, Group<gfortran_Group>;
|
||||
defm protect_parens : BooleanFFlag<"protect-parens">, Group<gfortran_Group>;
|
||||
defm range_check : BooleanFFlag<"range-check">, Group<gfortran_Group>;
|
||||
defm real_4_real_10 : BooleanFFlag<"real-4-real-10">, Group<gfortran_Group>;
|
||||
defm real_4_real_16 : BooleanFFlag<"real-4-real-16">, Group<gfortran_Group>;
|
||||
|
|
|
@ -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 @@ public:
|
|||
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 @@ public:
|
|||
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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -362,8 +362,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
bool checkArithmeticFenceSupported() const override { return true; }
|
||||
|
||||
CallingConv getDefaultCallingConv() const override {
|
||||
return CC_C;
|
||||
}
|
||||
|
|
|
@ -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<ComplexType>()->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: {
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -291,6 +291,26 @@ static ExprResult buildOperatorCoawaitCall(Sema &SemaRef, Scope *S,
|
|||
cast<UnresolvedLookupExpr>(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<FunctionDecl>();
|
||||
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<Expr *, 2> DeleteArgs{CoroFree};
|
||||
|
||||
|
|
|
@ -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<FunctionDecl>();
|
||||
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 )
|
||||
|
|
|
@ -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 ()'
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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 <typename T> 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<float>(a, b); // expected-note {{in instantiation of function template specialization 'addT<float>' requested here}}
|
||||
int i = addT<int>(1, 2); // expected-note {{in instantiation of function template specialization 'addT<int>' 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
|
Loading…
Reference in New Issue