diff options
author | Lang Hames <lhames@gmail.com> | 2012-10-02 04:45:10 +0000 |
---|---|---|
committer | Lang Hames <lhames@gmail.com> | 2012-10-02 04:45:10 +0000 |
commit | be9af1288881110e406b87914162eaa59f1e5918 (patch) | |
tree | d5dad9578b613b3a7d8e5b6612e686b76bb22203 /lib/Sema | |
parent | d13eff6f77216a6fb25e18f600b492db4f0492e8 (diff) |
Add FP_CONTRACT support for clang.
Clang will now honor the FP_CONTRACT pragma and emit LLVM
fmuladd intrinsics for expressions of the form A * B + C (when they occur in a
single statement).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164989 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 30 | ||||
-rw-r--r-- | lib/Sema/SemaPseudoObject.cpp | 10 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 6 |
6 files changed, 34 insertions, 23 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index dccce6ef90..b3836a2602 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -7504,7 +7504,7 @@ BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T, = new (S.Context) BinaryOperator(IterationVarRefRVal, IntegerLiteral::Create(S.Context, Upper, SizeType, Loc), BO_NE, S.Context.BoolTy, - VK_RValue, OK_Ordinary, Loc); + VK_RValue, OK_Ordinary, Loc, false); // Create the pre-increment of the iteration variable. Expr *Increment diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 0570dd38c7..75bc8658c6 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -8416,7 +8416,8 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, if (CompResultTy.isNull()) return Owned(new (Context) BinaryOperator(LHS.take(), RHS.take(), Opc, - ResultTy, VK, OK, OpLoc)); + ResultTy, VK, OK, OpLoc, + FPFeatures.fp_contract)); if (getLangOpts().CPlusPlus && LHS.get()->getObjectKind() != OK_ObjCProperty) { VK = VK_LValue; @@ -8424,7 +8425,8 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, } return Owned(new (Context) CompoundAssignOperator(LHS.take(), RHS.take(), Opc, ResultTy, VK, OK, CompLHSTy, - CompResultTy, OpLoc)); + CompResultTy, OpLoc, + FPFeatures.fp_contract)); } /// DiagnoseBitwisePrecedence - Emit a warning when bitwise and comparison diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 763ef28919..ad4a17f99c 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -4833,7 +4833,8 @@ ExprResult Sema::ActOnDecltypeExpression(Expr *E) { BO_Comma, BO->getType(), BO->getValueKind(), BO->getObjectKind(), - BO->getOperatorLoc())); + BO->getOperatorLoc(), + BO->isFPContractable())); } } diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index e9c2c6c5f6..10b96c9ec3 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -9981,7 +9981,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, llvm::makeArrayRef(Args, NumArgs), Context.DependentTy, VK_RValue, - OpLoc)); + OpLoc, false)); } // Build an empty overload set. @@ -10058,7 +10058,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, CallExpr *TheCall = new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.take(), llvm::makeArrayRef(Args, NumArgs), - ResultTy, VK, OpLoc); + ResultTy, VK, OpLoc, false); if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall, FnDecl)) @@ -10159,7 +10159,8 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, return Owned(new (Context) BinaryOperator(Args[0], Args[1], Opc, Context.DependentTy, VK_RValue, OK_Ordinary, - OpLoc)); + OpLoc, + FPFeatures.fp_contract)); return Owned(new (Context) CompoundAssignOperator(Args[0], Args[1], Opc, Context.DependentTy, @@ -10167,7 +10168,8 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, OK_Ordinary, Context.DependentTy, Context.DependentTy, - OpLoc)); + OpLoc, + FPFeatures.fp_contract)); } // FIXME: save results of ADL from here? @@ -10179,11 +10181,9 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, NestedNameSpecifierLoc(), OpNameInfo, /*ADL*/ true, IsOverloaded(Fns), Fns.begin(), Fns.end()); - return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, - Args, - Context.DependentTy, - VK_RValue, - OpLoc)); + return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, Args, + Context.DependentTy, VK_RValue, + OpLoc, FPFeatures.fp_contract)); } // Always do placeholder-like conversions on the RHS. @@ -10298,7 +10298,8 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, CXXOperatorCallExpr *TheCall = new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.take(), - Args, ResultTy, VK, OpLoc); + Args, ResultTy, VK, OpLoc, + FPFeatures.fp_contract); if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall, FnDecl)) @@ -10430,7 +10431,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, Args, Context.DependentTy, VK_RValue, - RLoc)); + RLoc, false)); } // Handle placeholders on both operands. @@ -10507,7 +10508,8 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, CXXOperatorCallExpr *TheCall = new (Context) CXXOperatorCallExpr(Context, OO_Subscript, FnExpr.take(), Args, - ResultTy, VK, RLoc); + ResultTy, VK, RLoc, + false); if (CheckCallReturnType(FnDecl->getResultType(), LLoc, TheCall, FnDecl)) @@ -11035,7 +11037,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, CXXOperatorCallExpr *TheCall = new (Context) CXXOperatorCallExpr(Context, OO_Call, NewFn.take(), llvm::makeArrayRef(MethodArgs, NumArgs+1), - ResultTy, VK, RParenLoc); + ResultTy, VK, RParenLoc, false); delete [] MethodArgs; if (CheckCallReturnType(Method->getResultType(), LParenLoc, TheCall, @@ -11208,7 +11210,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc) { ResultTy = ResultTy.getNonLValueExprType(Context); CXXOperatorCallExpr *TheCall = new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr.take(), - Base, ResultTy, VK, OpLoc); + Base, ResultTy, VK, OpLoc, false); if (CheckCallReturnType(Method->getResultType(), OpLoc, TheCall, Method)) diff --git a/lib/Sema/SemaPseudoObject.cpp b/lib/Sema/SemaPseudoObject.cpp index 501fa113ce..22a24a947f 100644 --- a/lib/Sema/SemaPseudoObject.cpp +++ b/lib/Sema/SemaPseudoObject.cpp @@ -356,7 +356,7 @@ PseudoOpBuilder::buildAssignmentOperation(Scope *Sc, SourceLocation opcLoc, syntactic = new (S.Context) BinaryOperator(syntacticLHS, capturedRHS, opcode, capturedRHS->getType(), capturedRHS->getValueKind(), - OK_Ordinary, opcLoc); + OK_Ordinary, opcLoc, false); } else { ExprResult opLHS = buildGet(); if (opLHS.isInvalid()) return ExprError(); @@ -375,7 +375,7 @@ PseudoOpBuilder::buildAssignmentOperation(Scope *Sc, SourceLocation opcLoc, OK_Ordinary, opLHS.get()->getType(), result.get()->getType(), - opcLoc); + opcLoc, false); } // The result of the assignment, if not void, is the value set into @@ -1366,7 +1366,7 @@ ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc, // Do nothing if either argument is dependent. if (LHS->isTypeDependent() || RHS->isTypeDependent()) return new (Context) BinaryOperator(LHS, RHS, opcode, Context.DependentTy, - VK_RValue, OK_Ordinary, opcLoc); + VK_RValue, OK_Ordinary, opcLoc, false); // Filter out non-overload placeholder types in the RHS. if (RHS->getType()->isNonOverloadPlaceholderType()) { @@ -1437,14 +1437,14 @@ Expr *Sema::recreateSyntacticForm(PseudoObjectExpr *E) { cop->getObjectKind(), cop->getComputationLHSType(), cop->getComputationResultType(), - cop->getOperatorLoc()); + cop->getOperatorLoc(), false); } else if (BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) { Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, bop->getLHS()); Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr(); return new (Context) BinaryOperator(lhs, rhs, bop->getOpcode(), bop->getType(), bop->getValueKind(), bop->getObjectKind(), - bop->getOperatorLoc()); + bop->getOperatorLoc(), false); } else { assert(syntax->hasPlaceholderType(BuiltinType::PseudoObject)); return stripOpaqueValuesFromPseudoObjectRef(*this, syntax); diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index e0451c4c49..f76c947e31 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -6429,6 +6429,9 @@ TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) { RHS.get() == E->getRHS()) return SemaRef.Owned(E); + Sema::FPContractStateRAII FPContractState(getSema()); + getSema().FPFeatures.fp_contract = E->isFPContractable(); + return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get()); } @@ -6852,6 +6855,9 @@ TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) { (E->getNumArgs() != 2 || Second.get() == E->getArg(1))) return SemaRef.MaybeBindToTemporary(E); + Sema::FPContractStateRAII FPContractState(getSema()); + getSema().FPFeatures.fp_contract = E->isFPContractable(); + return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(), E->getOperatorLoc(), Callee.get(), |