[cfe-commits] r164989 - in /cfe/trunk: include/clang/AST/ include/clang/Sema/ lib/AST/ lib/Analysis/ lib/CodeGen/ lib/Parse/ lib/Rewrite/Frontend/ lib/Sema/ lib/Serialization/ test/CodeGen/ test/CodeGenOpenCL/
Lang Hames
lhames at gmail.com
Tue Oct 2 13:13:50 PDT 2012
I tested that locally, but forgot to add a test case to Clang. I'll add
that in soon.
Thanks for catching this!
- Lang.
On Tue, Oct 2, 2012 at 12:06 PM, David Blaikie <dblaikie at gmail.com> wrote:
> On Mon, Oct 1, 2012 at 9:45 PM, Lang Hames <lhames at gmail.com> wrote:
> > Author: lhames
> > Date: Mon Oct 1 23:45:10 2012
> > New Revision: 164989
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=164989&view=rev
> > Log:
> > 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).
>
> Hooray \o/
>
> I think you were telling me that the pragma can be applied at the file
> scope. Is that tested somewhere?
>
> - David
>
> >
> >
> > Added:
> > cfe/trunk/test/CodeGen/ffp-contract-option.c
> > - copied unchanged from r164952,
> cfe/trunk/test/CodeGen/fp-contract.c
> > cfe/trunk/test/CodeGen/fp-contract-pragma.cpp
> > Removed:
> > cfe/trunk/test/CodeGen/fp-contract.c
> > Modified:
> > cfe/trunk/include/clang/AST/Expr.h
> > cfe/trunk/include/clang/AST/ExprCXX.h
> > cfe/trunk/include/clang/Sema/Sema.h
> > cfe/trunk/lib/AST/ASTImporter.cpp
> > cfe/trunk/lib/Analysis/BodyFarm.cpp
> > cfe/trunk/lib/CodeGen/CGExprScalar.cpp
> > cfe/trunk/lib/CodeGen/CGObjC.cpp
> > cfe/trunk/lib/Parse/ParseStmt.cpp
> > cfe/trunk/lib/Rewrite/Frontend/RewriteModernObjC.cpp
> > cfe/trunk/lib/Rewrite/Frontend/RewriteObjC.cpp
> > cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> > cfe/trunk/lib/Sema/SemaExpr.cpp
> > cfe/trunk/lib/Sema/SemaExprCXX.cpp
> > cfe/trunk/lib/Sema/SemaOverload.cpp
> > cfe/trunk/lib/Sema/SemaPseudoObject.cpp
> > cfe/trunk/lib/Sema/TreeTransform.h
> > cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
> > cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
> > cfe/trunk/test/CodeGenOpenCL/single-precision-constant.cl
> >
> > Modified: cfe/trunk/include/clang/AST/Expr.h
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=164989&r1=164988&r2=164989&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/include/clang/AST/Expr.h (original)
> > +++ cfe/trunk/include/clang/AST/Expr.h Mon Oct 1 23:45:10 2012
> > @@ -2785,6 +2785,12 @@
> >
> > private:
> > unsigned Opc : 6;
> > +
> > + // Records the FP_CONTRACT pragma status at the point that this binary
> > + // operator was parsed. This bit is only meaningful for operations on
> > + // floating point types. For all other types it should default to
> > + // false.
> > + unsigned FPContractable : 1;
> > SourceLocation OpLoc;
> >
> > enum { LHS, RHS, END_EXPR };
> > @@ -2793,7 +2799,7 @@
> >
> > BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
> > ExprValueKind VK, ExprObjectKind OK,
> > - SourceLocation opLoc)
> > + SourceLocation opLoc, bool fpContractable)
> > : Expr(BinaryOperatorClass, ResTy, VK, OK,
> > lhs->isTypeDependent() || rhs->isTypeDependent(),
> > lhs->isValueDependent() || rhs->isValueDependent(),
> > @@ -2801,7 +2807,7 @@
> > rhs->isInstantiationDependent()),
> > (lhs->containsUnexpandedParameterPack() ||
> > rhs->containsUnexpandedParameterPack())),
> > - Opc(opc), OpLoc(opLoc) {
> > + Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) {
> > SubExprs[LHS] = lhs;
> > SubExprs[RHS] = rhs;
> > assert(!isCompoundAssignmentOp() &&
> > @@ -2902,10 +2908,18 @@
> > return child_range(&SubExprs[0], &SubExprs[0]+END_EXPR);
> > }
> >
> > + // Set the FP contractability status of this operator. Only
> meaningful for
> > + // operations on floating point types.
> > + void setFPContractable(bool FPC) { FPContractable = FPC; }
> > +
> > + // Get the FP contractability status of this operator. Only
> meaningful for
> > + // operations on floating point types.
> > + bool isFPContractable() const { return FPContractable; }
> > +
> > protected:
> > BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
> > ExprValueKind VK, ExprObjectKind OK,
> > - SourceLocation opLoc, bool dead)
> > + SourceLocation opLoc, bool fpContractable, bool dead2)
> > : Expr(CompoundAssignOperatorClass, ResTy, VK, OK,
> > lhs->isTypeDependent() || rhs->isTypeDependent(),
> > lhs->isValueDependent() || rhs->isValueDependent(),
> > @@ -2913,7 +2927,7 @@
> > rhs->isInstantiationDependent()),
> > (lhs->containsUnexpandedParameterPack() ||
> > rhs->containsUnexpandedParameterPack())),
> > - Opc(opc), OpLoc(opLoc) {
> > + Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) {
> > SubExprs[LHS] = lhs;
> > SubExprs[RHS] = rhs;
> > }
> > @@ -2935,8 +2949,9 @@
> > CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType
> ResType,
> > ExprValueKind VK, ExprObjectKind OK,
> > QualType CompLHSType, QualType CompResultType,
> > - SourceLocation OpLoc)
> > - : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, true),
> > + SourceLocation OpLoc, bool fpContractable)
> > + : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc,
> fpContractable,
> > + true),
> > ComputationLHSType(CompLHSType),
> > ComputationResultType(CompResultType) {
> > assert(isCompoundAssignmentOp() &&
> >
> > Modified: cfe/trunk/include/clang/AST/ExprCXX.h
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=164989&r1=164988&r2=164989&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/include/clang/AST/ExprCXX.h (original)
> > +++ cfe/trunk/include/clang/AST/ExprCXX.h Mon Oct 1 23:45:10 2012
> > @@ -53,14 +53,19 @@
> > OverloadedOperatorKind Operator;
> > SourceRange Range;
> >
> > + // Record the FP_CONTRACT state that applies to this operator call.
> Only
> > + // meaningful for floating point types. For other types this value
> can be
> > + // set to false.
> > + unsigned FPContractable : 1;
> > +
> > SourceRange getSourceRangeImpl() const LLVM_READONLY;
> > public:
> > CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr
> *fn,
> > ArrayRef<Expr*> args, QualType t, ExprValueKind
> VK,
> > - SourceLocation operatorloc)
> > + SourceLocation operatorloc, bool fpContractable)
> > : CallExpr(C, CXXOperatorCallExprClass, fn, 0, args, t, VK,
> > operatorloc),
> > - Operator(Op) {
> > + Operator(Op), FPContractable(fpContractable) {
> > Range = getSourceRangeImpl();
> > }
> > explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty) :
> > @@ -85,6 +90,14 @@
> > }
> > static bool classof(const CXXOperatorCallExpr *) { return true; }
> >
> > + // Set the FP contractability status of this operator. Only
> meaningful for
> > + // operations on floating point types.
> > + void setFPContractable(bool FPC) { FPContractable = FPC; }
> > +
> > + // Get the FP contractability status of this operator. Only
> meaningful for
> > + // operations on floating point types.
> > + bool isFPContractable() const { return FPContractable; }
> > +
> > friend class ASTStmtReader;
> > friend class ASTStmtWriter;
> > };
> >
> > Modified: cfe/trunk/include/clang/Sema/Sema.h
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=164989&r1=164988&r2=164989&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/include/clang/Sema/Sema.h (original)
> > +++ cfe/trunk/include/clang/Sema/Sema.h Mon Oct 1 23:45:10 2012
> > @@ -735,6 +735,20 @@
> > /// should not be used elsewhere.
> > void EmitCurrentDiagnostic(unsigned DiagID);
> >
> > + /// Records and restores the FP_CONTRACT state on entry/exit of
> compound
> > + /// statements.
> > + class FPContractStateRAII {
> > + public:
> > + FPContractStateRAII(Sema& S)
> > + : S(S), OldFPContractState(S.FPFeatures.fp_contract) {}
> > + ~FPContractStateRAII() {
> > + S.FPFeatures.fp_contract = OldFPContractState;
> > + }
> > + private:
> > + Sema& S;
> > + bool OldFPContractState : 1;
> > + };
> > +
> > public:
> > Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
> > TranslationUnitKind TUKind = TU_Complete,
> >
> > Modified: cfe/trunk/lib/AST/ASTImporter.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=164989&r1=164988&r2=164989&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/AST/ASTImporter.cpp (original)
> > +++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Oct 1 23:45:10 2012
> > @@ -4082,7 +4082,8 @@
> > return new (Importer.getToContext()) BinaryOperator(LHS, RHS,
> E->getOpcode(),
> > T,
> E->getValueKind(),
> >
> E->getObjectKind(),
> > -
> Importer.Import(E->getOperatorLoc()));
> > +
> Importer.Import(E->getOperatorLoc()),
> > +
> E->isFPContractable());
> > }
> >
> > Expr
> *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
> > @@ -4111,7 +4112,8 @@
> > T, E->getValueKind(),
> > E->getObjectKind(),
> > CompLHSType,
> CompResultType,
> > -
> Importer.Import(E->getOperatorLoc()));
> > +
> Importer.Import(E->getOperatorLoc()),
> > + E->isFPContractable());
> > }
> >
> > static bool ImportCastPath(CastExpr *E, CXXCastPath &Path) {
> >
> > Modified: cfe/trunk/lib/Analysis/BodyFarm.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BodyFarm.cpp?rev=164989&r1=164988&r2=164989&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Analysis/BodyFarm.cpp (original)
> > +++ cfe/trunk/lib/Analysis/BodyFarm.cpp Mon Oct 1 23:45:10 2012
> > @@ -70,7 +70,7 @@
> > QualType Ty) {
> > return new (C) BinaryOperator(const_cast<Expr*>(LHS),
> const_cast<Expr*>(RHS),
> > BO_Assign, Ty, VK_RValue,
> > - OK_Ordinary, SourceLocation());
> > + OK_Ordinary, SourceLocation(), false);
> > }
> >
> > DeclRefExpr *ASTMaker::makeDeclRefExpr(const VarDecl *D) {
> >
> > Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=164989&r1=164988&r2=164989&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Mon Oct 1 23:45:10 2012
> > @@ -45,6 +45,7 @@
> > Value *RHS;
> > QualType Ty; // Computation Type.
> > BinaryOperator::Opcode Opcode; // Opcode of BinOp to perform
> > + bool FPContractable;
> > const Expr *E; // Entire expr, for error unsupported. May not
> be binop.
> > };
> >
> > @@ -1654,6 +1655,7 @@
> > Result.RHS = Visit(E->getRHS());
> > Result.Ty = E->getType();
> > Result.Opcode = E->getOpcode();
> > + Result.FPContractable = E->isFPContractable();
> > Result.E = E;
> > return Result;
> > }
> > @@ -1982,6 +1984,77 @@
> > return CGF.Builder.CreateInBoundsGEP(pointer, index, "add.ptr");
> > }
> >
> > +// Construct an fmuladd intrinsic to represent a fused mul-add of MulOp
> and
> > +// Addend. Use negMul and negAdd to negate the first operand of the Mul
> or
> > +// the add operand respectively. This allows fmuladd to represent
> a*b-c, or
> > +// c-a*b. Patterns in LLVM should catch the negated forms and translate
> them to
> > +// efficient operations.
> > +static Value* buildFMulAdd(llvm::BinaryOperator *MulOp, Value *Addend,
> > + const CodeGenFunction &CGF, CGBuilderTy
> &Builder,
> > + bool negMul, bool negAdd) {
> > + assert(!(negMul && negAdd) && "Only one of negMul and negAdd should
> be set.");
> > +
> > + Value *MulOp0 = MulOp->getOperand(0);
> > + Value *MulOp1 = MulOp->getOperand(1);
> > + if (negMul) {
> > + MulOp0 =
> > + Builder.CreateFSub(
> > + llvm::ConstantFP::getZeroValueForNegation(MulOp0->getType()),
> MulOp0,
> > + "neg");
> > + } else if (negAdd) {
> > + Addend =
> > + Builder.CreateFSub(
> > + llvm::ConstantFP::getZeroValueForNegation(Addend->getType()),
> Addend,
> > + "neg");
> > + }
> > +
> > + Value *FMulAdd =
> > + Builder.CreateCall3(
> > + CGF.CGM.getIntrinsic(llvm::Intrinsic::fmuladd, Addend->getType()),
> > + MulOp0, MulOp1, Addend);
> > + MulOp->eraseFromParent();
> > +
> > + return FMulAdd;
> > +}
> > +
> > +// Check whether it would be legal to emit an fmuladd intrinsic call to
> > +// represent op and if so, build the fmuladd.
> > +//
> > +// Checks that (a) the operation is fusable, and (b) -ffp-contract=on.
> > +// Does NOT check the type of the operation - it's assumed that this
> function
> > +// will be called from contexts where it's known that the type is
> contractable.
> > +static Value* tryEmitFMulAdd(const BinOpInfo &op,
> > + const CodeGenFunction &CGF, CGBuilderTy
> &Builder,
> > + bool isSub=false) {
> > +
> > + assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
> > + op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
> > + "Only fadd/fsub can be the root of an fmuladd.");
> > +
> > + // Check whether this op is marked as fusable.
> > + if (!op.FPContractable)
> > + return 0;
> > +
> > + // Check whether -ffp-contract=on. (If -ffp-contract=off/fast, fusing
> is
> > + // either disabled, or handled entirely by the LLVM backend).
> > + if (CGF.getContext().getLangOpts().getFPContractMode() !=
> LangOptions::FPC_On)
> > + return 0;
> > +
> > + // We have a potentially fusable op. Look for a mul on one of the
> operands.
> > + if (llvm::BinaryOperator* LHSBinOp =
> dyn_cast<llvm::BinaryOperator>(op.LHS)) {
> > + if (LHSBinOp->getOpcode() == llvm::Instruction::FMul) {
> > + return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, false, isSub);
> > + }
> > + } else if (llvm::BinaryOperator* RHSBinOp =
> > + dyn_cast<llvm::BinaryOperator>(op.RHS)) {
> > + if (RHSBinOp->getOpcode() == llvm::Instruction::FMul) {
> > + return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub, false);
> > + }
> > + }
> > +
> > + return 0;
> > +}
> > +
> > Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &op) {
> > if (op.LHS->getType()->isPointerTy() ||
> > op.RHS->getType()->isPointerTy())
> > @@ -2000,8 +2073,13 @@
> > }
> > }
> >
> > - if (op.LHS->getType()->isFPOrFPVectorTy())
> > + if (op.LHS->getType()->isFPOrFPVectorTy()) {
> > + // Try to form an fmuladd.
> > + if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder))
> > + return FMulAdd;
> > +
> > return Builder.CreateFAdd(op.LHS, op.RHS, "add");
> > + }
> >
> > return Builder.CreateAdd(op.LHS, op.RHS, "add");
> > }
> > @@ -2022,8 +2100,12 @@
> > }
> > }
> >
> > - if (op.LHS->getType()->isFPOrFPVectorTy())
> > + if (op.LHS->getType()->isFPOrFPVectorTy()) {
> > + // Try to form an fmuladd.
> > + if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder, true))
> > + return FMulAdd;
> > return Builder.CreateFSub(op.LHS, op.RHS, "sub");
> > + }
> >
> > return Builder.CreateSub(op.LHS, op.RHS, "sub");
> > }
> >
> > Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=164989&r1=164988&r2=164989&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
> > +++ cfe/trunk/lib/CodeGen/CGObjC.cpp Mon Oct 1 23:45:10 2012
> > @@ -1213,7 +1213,7 @@
> >
> > BinaryOperator assign(&ivarRef, finalArg, BO_Assign,
> > ivarRef.getType(), VK_RValue, OK_Ordinary,
> > - SourceLocation());
> > + SourceLocation(), false);
> > EmitStmt(&assign);
> > }
> >
> > @@ -2850,7 +2850,7 @@
> > CallExpr *CalleeExp = cast<CallExpr>(PID->getSetterCXXAssignment());
> > CXXOperatorCallExpr TheCall(C, OO_Equal, CalleeExp->getCallee(),
> > Args, DestTy->getPointeeType(),
> > - VK_LValue, SourceLocation());
> > + VK_LValue, SourceLocation(), false);
> >
> > EmitStmt(&TheCall);
> >
> >
> > Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=164989&r1=164988&r2=164989&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
> > +++ cfe/trunk/lib/Parse/ParseStmt.cpp Mon Oct 1 23:45:10 2012
> > @@ -679,6 +679,11 @@
> > PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),
> > Tok.getLocation(),
> > "in compound statement ('{}')");
> > +
> > + // Record the state of the FP_CONTRACT pragma, restore on leaving the
> > + // compound statement.
> > + Sema::FPContractStateRAII SaveFPContractState(Actions);
> > +
> > InMessageExpressionRAIIObject InMessage(*this, false);
> > BalancedDelimiterTracker T(*this, tok::l_brace);
> > if (T.consumeOpen())
> >
> > Modified: cfe/trunk/lib/Rewrite/Frontend/RewriteModernObjC.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/Frontend/RewriteModernObjC.cpp?rev=164989&r1=164988&r2=164989&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Rewrite/Frontend/RewriteModernObjC.cpp (original)
> > +++ cfe/trunk/lib/Rewrite/Frontend/RewriteModernObjC.cpp Mon Oct 1
> 23:45:10 2012
> > @@ -3576,7 +3576,8 @@
> > SourceLocation());
> > BinaryOperator *lessThanExpr =
> > new (Context) BinaryOperator(sizeofExpr, limit, BO_LE,
> Context->IntTy,
> > - VK_RValue, OK_Ordinary,
> SourceLocation());
> > + VK_RValue, OK_Ordinary,
> SourceLocation(),
> > + false);
> > // (sizeof(returnType) <= 8 ? objc_msgSend(...) :
> objc_msgSend_stret(...))
> > ConditionalOperator *CondExpr =
> > new (Context) ConditionalOperator(lessThanExpr,
> > @@ -7473,7 +7474,7 @@
> > BinaryOperator *addExpr =
> > new (Context) BinaryOperator(castExpr, DRE, BO_Add,
> >
> Context->getPointerType(Context->CharTy),
> > - VK_RValue, OK_Ordinary,
> SourceLocation());
> > + VK_RValue, OK_Ordinary,
> SourceLocation(), false);
> > // Don't forget the parens to enforce the proper binding.
> > ParenExpr *PE = new (Context) ParenExpr(SourceLocation(),
> > SourceLocation(),
> >
> > Modified: cfe/trunk/lib/Rewrite/Frontend/RewriteObjC.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/Frontend/RewriteObjC.cpp?rev=164989&r1=164988&r2=164989&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Rewrite/Frontend/RewriteObjC.cpp (original)
> > +++ cfe/trunk/lib/Rewrite/Frontend/RewriteObjC.cpp Mon Oct 1 23:45:10
> 2012
> > @@ -3078,7 +3078,8 @@
> > SourceLocation());
> > BinaryOperator *lessThanExpr =
> > new (Context) BinaryOperator(sizeofExpr, limit, BO_LE,
> Context->IntTy,
> > - VK_RValue, OK_Ordinary,
> SourceLocation());
> > + VK_RValue, OK_Ordinary,
> SourceLocation(),
> > + false);
> > // (sizeof(returnType) <= 8 ? objc_msgSend(...) :
> objc_msgSend_stret(...))
> > ConditionalOperator *CondExpr =
> > new (Context) ConditionalOperator(lessThanExpr,
> >
> > Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=164989&r1=164988&r2=164989&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
> > +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Oct 1 23:45:10 2012
> > @@ -7504,7 +7504,7 @@
> > = 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
> >
> > Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=164989&r1=164988&r2=164989&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> > +++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Oct 1 23:45:10 2012
> > @@ -8416,7 +8416,8 @@
> >
> > 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 @@
> > }
> > 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
> >
> > Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=164989&r1=164988&r2=164989&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
> > +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Oct 1 23:45:10 2012
> > @@ -4833,7 +4833,8 @@
> > BO_Comma, BO->getType(),
> > BO->getValueKind(),
> > BO->getObjectKind(),
> > - BO->getOperatorLoc()));
> > + BO->getOperatorLoc(),
> > +
> BO->isFPContractable()));
> > }
> > }
> >
> >
> > Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=164989&r1=164988&r2=164989&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
> > +++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Oct 1 23:45:10 2012
> > @@ -9981,7 +9981,7 @@
> > llvm::makeArrayRef(Args,
> NumArgs),
> > Context.DependentTy,
> > VK_RValue,
> > - OpLoc));
> > + OpLoc, false));
> > }
> >
> > // Build an empty overload set.
> > @@ -10058,7 +10058,7 @@
> > 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 @@
> > 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 @@
> > OK_Ordinary,
> >
> Context.DependentTy,
> >
> Context.DependentTy,
> > - OpLoc));
> > + OpLoc,
> > +
> FPFeatures.fp_contract));
> > }
> >
> > // FIXME: save results of ADL from here?
> > @@ -10179,11 +10181,9 @@
> > 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 @@
> >
> > 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 @@
> > Args,
> > Context.DependentTy,
> > VK_RValue,
> > - RLoc));
> > + RLoc, false));
> > }
> >
> > // Handle placeholders on both operands.
> > @@ -10507,7 +10508,8 @@
> > 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 @@
> > 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 @@
> > 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))
> >
> > Modified: cfe/trunk/lib/Sema/SemaPseudoObject.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaPseudoObject.cpp?rev=164989&r1=164988&r2=164989&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Sema/SemaPseudoObject.cpp (original)
> > +++ cfe/trunk/lib/Sema/SemaPseudoObject.cpp Mon Oct 1 23:45:10 2012
> > @@ -356,7 +356,7 @@
> > 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 @@
> > 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 @@
> > // 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 @@
> > 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);
> >
> > Modified: cfe/trunk/lib/Sema/TreeTransform.h
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=164989&r1=164988&r2=164989&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Sema/TreeTransform.h (original)
> > +++ cfe/trunk/lib/Sema/TreeTransform.h Mon Oct 1 23:45:10 2012
> > @@ -6429,6 +6429,9 @@
> > 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 @@
> > (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(),
> >
> > Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=164989&r1=164988&r2=164989&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
> > +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Mon Oct 1 23:45:10
> 2012
> > @@ -565,6 +565,7 @@
> > E->setRHS(Reader.ReadSubExpr());
> > E->setOpcode((BinaryOperator::Opcode)Record[Idx++]);
> > E->setOperatorLoc(ReadSourceLocation(Record, Idx));
> > + E->setFPContractable((bool)Record[Idx++]);
> > }
> >
> > void ASTStmtReader::VisitCompoundAssignOperator(CompoundAssignOperator
> *E) {
> > @@ -1086,6 +1087,7 @@
> > VisitCallExpr(E);
> > E->Operator = (OverloadedOperatorKind)Record[Idx++];
> > E->Range = Reader.ReadSourceRange(F, Record, Idx);
> > + E->setFPContractable((bool)Record[Idx++]);
> > }
> >
> > void ASTStmtReader::VisitCXXConstructExpr(CXXConstructExpr *E) {
> >
> > Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=164989&r1=164988&r2=164989&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
> > +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Mon Oct 1 23:45:10
> 2012
> > @@ -536,6 +536,7 @@
> > Writer.AddStmt(E->getRHS());
> > Record.push_back(E->getOpcode()); // FIXME: stable encoding
> > Writer.AddSourceLocation(E->getOperatorLoc(), Record);
> > + Record.push_back(E->isFPContractable());
> > Code = serialization::EXPR_BINARY_OPERATOR;
> > }
> >
> > @@ -1055,6 +1056,7 @@
> > VisitCallExpr(E);
> > Record.push_back(E->getOperator());
> > Writer.AddSourceRange(E->Range, Record);
> > + Record.push_back(E->isFPContractable());
> > Code = serialization::EXPR_CXX_OPERATOR_CALL;
> > }
> >
> >
> > Added: cfe/trunk/test/CodeGen/fp-contract-pragma.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/fp-contract-pragma.cpp?rev=164989&view=auto
> >
> ==============================================================================
> > --- cfe/trunk/test/CodeGen/fp-contract-pragma.cpp (added)
> > +++ cfe/trunk/test/CodeGen/fp-contract-pragma.cpp Mon Oct 1 23:45:10
> 2012
> > @@ -0,0 +1,39 @@
> > +// RUN: %clang_cc1 -O3 -emit-llvm -o - %s | FileCheck %s
> > +
> > +// Is FP_CONTRACT is honored in a simple case?
> > +float fp_contract_1(float a, float b, float c) {
> > +// CHECK: _Z13fp_contract_1fff
> > +// CHECK-NEXT: entry
> > +// CHECK-NEXT: %0 = tail call float @llvm.fmuladd
> > + #pragma STDC FP_CONTRACT ON
> > + return a * b + c;
> > +}
> > +
> > +// Is FP_CONTRACT state cleared on exiting compound statements?
> > +float fp_contract_2(float a, float b, float c) {
> > +// CHECK: _Z13fp_contract_2fff
> > +// CHECK-NEXT: entry
> > +// CHECK-NEXT: %mul = fmul float %a, %b
> > +// CHECK-NEXT: %add = fadd float %mul, %c
> > + {
> > + #pragma STDC FP_CONTRACT ON
> > + }
> > + return a * b + c;
> > +}
> > +
> > +// Does FP_CONTRACT survive template instatiation?
> > +class Foo {};
> > +Foo operator+(Foo, Foo);
> > +
> > +template <typename T>
> > +T template_muladd(T a, T b, T c) {
> > + #pragma STDC FP_CONTRACT ON
> > + return a * b + c;
> > +}
> > +
> > +float fp_contract_3(float a, float b, float c) {
> > +// CHECK: _Z13fp_contract_3fff
> > +// CHECK-NEXT: entry
> > +// CHECK-NEXT: %0 = tail call float @llvm.fmuladd
> > + return template_muladd<float>(a, b, c);
> > +}
> >
> > Removed: cfe/trunk/test/CodeGen/fp-contract.c
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/fp-contract.c?rev=164988&view=auto
> >
> ==============================================================================
> > --- cfe/trunk/test/CodeGen/fp-contract.c (original)
> > +++ cfe/trunk/test/CodeGen/fp-contract.c (removed)
> > @@ -1,9 +0,0 @@
> > -// RUN: %clang_cc1 -O3 -ffp-contract=fast
> -triple=powerpc-apple-darwin10 -S -o - %s | FileCheck %s
> > -// REQUIRES: ppc32-registered-target
> > -
> > -float fma_test1(float a, float b, float c) {
> > -// CHECK: fmadds
> > - float x = a * b;
> > - float y = x + c;
> > - return y;
> > -}
> >
> > Modified: cfe/trunk/test/CodeGenOpenCL/single-precision-constant.cl
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenOpenCL/single-precision-constant.cl?rev=164989&r1=164988&r2=164989&view=diff
> >
> ==============================================================================
> > --- cfe/trunk/test/CodeGenOpenCL/single-precision-constant.cl (original)
> > +++ cfe/trunk/test/CodeGenOpenCL/single-precision-constant.cl Mon Oct
> 1 23:45:10 2012
> > @@ -1,7 +1,6 @@
> > // RUN: %clang_cc1 %s -cl-single-precision-constant -emit-llvm -o - |
> FileCheck %s
> >
> > float fn(float f) {
> > - // CHECK: fmul float
> > - // CHECK: fadd float
> > + // CHECK: %0 = tail call float @llvm.fmuladd.f32(float %f, float
> 2.000000e+00, float 1.000000e+00)
> > return f*2. + 1.;
> > }
> >
> >
> > _______________________________________________
> > cfe-commits mailing list
> > cfe-commits at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20121002/023f8e71/attachment.html>
More information about the cfe-commits
mailing list