[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/
David Blaikie
dblaikie at gmail.com
Tue Oct 2 12:06:22 PDT 2012
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
More information about the cfe-commits
mailing list