From: Daniel Dunbar Date: Thu, 29 Jan 2009 01:32:56 +0000 (+0000) Subject: Add folding for complex mul and fix some major bugs in complex float X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3f2798757c9ee353e207e18115e2e966432a4bee;p=clang Add folding for complex mul and fix some major bugs in complex float evaluation (alternate part of real/imag init was being set to 3 not 0 because the wrong APFloat constructor was being called). - Test cases coming once some more support is in. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63264 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index af50de6f94..c444a199f6 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -1257,7 +1257,7 @@ public: if (!EvaluateFloat(SubExpr, Result, Info)) return APValue(); - return APValue(APFloat(Result.getSemantics(), APFloat::fcZero), + return APValue(APFloat(Result.getSemantics(), APFloat::fcZero, false), Result); } else { assert(SubExpr->getType()->isIntegerType() && @@ -1283,7 +1283,7 @@ public: return APValue(); return APValue(Result, - APFloat(Result.getSemantics(), APFloat::fcZero)); + APFloat(Result.getSemantics(), APFloat::fcZero, false)); } else if (SubExpr->getType()->isIntegerType()) { APSInt Result; @@ -1324,6 +1324,8 @@ APValue ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) if (!EvaluateComplex(E->getRHS(), RHS, Info)) return APValue(); + assert(Result.isComplexFloat() == RHS.isComplexFloat() && + "Invalid operands to binary operator."); switch (E->getOpcode()) { default: return APValue(); case BinaryOperator::Add: @@ -1336,6 +1338,7 @@ APValue ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) Result.getComplexIntReal() += RHS.getComplexIntReal(); Result.getComplexIntImag() += RHS.getComplexIntImag(); } + break; case BinaryOperator::Sub: if (Result.isComplexFloat()) { Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(), @@ -1346,6 +1349,38 @@ APValue ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) Result.getComplexIntReal() -= RHS.getComplexIntReal(); Result.getComplexIntImag() -= RHS.getComplexIntImag(); } + break; + case BinaryOperator::Mul: + if (Result.isComplexFloat()) { + APValue LHS = Result; + APFloat &LHS_r = LHS.getComplexFloatReal(); + APFloat &LHS_i = LHS.getComplexFloatImag(); + APFloat &RHS_r = RHS.getComplexFloatReal(); + APFloat &RHS_i = RHS.getComplexFloatImag(); + + APFloat Tmp = LHS_r; + Tmp.multiply(RHS_r, APFloat::rmNearestTiesToEven); + Result.getComplexFloatReal() = Tmp; + Tmp = LHS_i; + Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven); + Result.getComplexFloatReal().subtract(Tmp, APFloat::rmNearestTiesToEven); + + Tmp = LHS_r; + Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven); + Result.getComplexFloatImag() = Tmp; + Tmp = LHS_i; + Tmp.multiply(RHS_r, APFloat::rmNearestTiesToEven); + Result.getComplexFloatImag().add(Tmp, APFloat::rmNearestTiesToEven); + } else { + APValue LHS = Result; + Result.getComplexIntReal() = + (LHS.getComplexIntReal() * RHS.getComplexIntReal() - + LHS.getComplexIntImag() * RHS.getComplexIntImag()); + Result.getComplexIntImag() = + (LHS.getComplexIntReal() * RHS.getComplexIntImag() + + LHS.getComplexIntImag() * RHS.getComplexIntReal()); + } + break; } return Result;