[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