diff options
author | Chris Lattner <sabre@nondot.org> | 2007-08-21 16:57:55 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-08-21 16:57:55 +0000 |
commit | 58dee10ed2eee34035f62d1c2d32b3639e9182f8 (patch) | |
tree | 4bdd6185d3c1437d13a0d454f20f256bc07fb820 | |
parent | c6fb90a7246c2d5d3233e70107bf9d8c7c9e535b (diff) |
reimplement support for complex comparisons, add support for integer complex compares.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41231 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | CodeGen/CGComplexExpr.cpp | 8 | ||||
-rw-r--r-- | CodeGen/CGExpr.cpp | 55 | ||||
-rw-r--r-- | CodeGen/CodeGenFunction.h | 3 |
3 files changed, 39 insertions, 27 deletions
diff --git a/CodeGen/CGComplexExpr.cpp b/CodeGen/CGComplexExpr.cpp index 8c93ca3fb5..12be4f7c96 100644 --- a/CodeGen/CGComplexExpr.cpp +++ b/CodeGen/CGComplexExpr.cpp @@ -24,7 +24,7 @@ using namespace CodeGen; // Complex Expression Emitter //===----------------------------------------------------------------------===// -typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy; +typedef CodeGenFunction::ComplexPairTy ComplexPairTy; namespace { class VISIBILITY_HIDDEN ComplexExprEmitter @@ -70,6 +70,8 @@ public: ComplexPairTy VisitBinaryOperator(const BinaryOperator *BO); ComplexPairTy VisitBinMul (const BinaryOperator *E); ComplexPairTy VisitBinAdd (const BinaryOperator *E); + + // No comparisons produce a complex result. ComplexPairTy VisitBinAssign (const BinaryOperator *E); @@ -319,10 +321,10 @@ VisitConditionalOperator(const ConditionalOperator *E) { /// EmitComplexExpr - Emit the computation of the specified expression of /// complex type, ignoring the result. -void CodeGenFunction::EmitComplexExpr(const Expr *E) { +ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E) { assert(E && E->getType()->isComplexType() && "Invalid complex expression to emit"); - ComplexExprEmitter(*this).Visit(const_cast<Expr*>(E)); + return ComplexExprEmitter(*this).Visit(const_cast<Expr*>(E)); } diff --git a/CodeGen/CGExpr.cpp b/CodeGen/CGExpr.cpp index b886c86378..d0c241398b 100644 --- a/CodeGen/CGExpr.cpp +++ b/CodeGen/CGExpr.cpp @@ -1217,15 +1217,16 @@ RValue CodeGenFunction::EmitShr(RValue LHSV, RValue RHSV, QualType ResTy) { RValue CodeGenFunction::EmitBinaryCompare(const BinaryOperator *E, unsigned UICmpOpc, unsigned SICmpOpc, unsigned FCmpOpc) { - RValue LHS = EmitExpr(E->getLHS()); - RValue RHS = EmitExpr(E->getRHS()); - llvm::Value *Result; - if (LHS.isScalar()) { - if (LHS.getVal()->getType()->isFloatingPoint()) { + QualType LHSTy = E->getLHS()->getType(); + if (!LHSTy->isComplexType()) { + RValue LHS = EmitExpr(E->getLHS()); + RValue RHS = EmitExpr(E->getRHS()); + + if (LHSTy->isRealFloatingType()) { Result = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc, LHS.getVal(), RHS.getVal(), "cmp"); - } else if (E->getLHS()->getType()->isUnsignedIntegerType()) { + } else if (LHSTy->isUnsignedIntegerType()) { // FIXME: This check isn't right for "unsigned short < int" where ushort // promotes to int and does a signed compare. Result = Builder.CreateICmp((llvm::ICmpInst::Predicate)UICmpOpc, @@ -1236,26 +1237,34 @@ RValue CodeGenFunction::EmitBinaryCompare(const BinaryOperator *E, LHS.getVal(), RHS.getVal(), "cmp"); } } else { -#if 0 - // Struct/union/complex - llvm::Value *LHSR, *LHSI, *RHSR, *RHSI, *ResultR, *ResultI; - EmitLoadOfComplex(LHS, LHSR, LHSI); - EmitLoadOfComplex(RHS, RHSR, RHSI); - - // FIXME: need to consider _Complex over integers too! - - ResultR = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc, - LHSR, RHSR, "cmp.r"); - ResultI = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc, - LHSI, RHSI, "cmp.i"); - if (BinaryOperator::EQ == E->getOpcode()) { + // Complex Comparison: can only be an equality comparison. + ComplexPairTy LHS = EmitComplexExpr(E->getLHS()); + ComplexPairTy RHS = EmitComplexExpr(E->getRHS()); + + QualType CETy = + cast<ComplexType>(LHSTy.getCanonicalType())->getElementType(); + + llvm::Value *ResultR, *ResultI; + if (CETy->isRealFloatingType()) { + ResultR = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc, + LHS.first, RHS.first, "cmp.r"); + ResultI = Builder.CreateFCmp((llvm::FCmpInst::Predicate)FCmpOpc, + LHS.second, RHS.second, "cmp.i"); + } else { + unsigned Opc = CETy->isUnsignedIntegerType() ? UICmpOpc : SICmpOpc; + ResultR = Builder.CreateICmp((llvm::ICmpInst::Predicate)Opc, + LHS.first, RHS.first, "cmp.r"); + ResultI = Builder.CreateICmp((llvm::ICmpInst::Predicate)Opc, + LHS.second, RHS.second, "cmp.i"); + } + + if (E->getOpcode() == BinaryOperator::EQ) { Result = Builder.CreateAnd(ResultR, ResultI, "and.ri"); - } else if (BinaryOperator::NE == E->getOpcode()) { - Result = Builder.CreateOr(ResultR, ResultI, "or.ri"); } else { - assert(0 && "Complex comparison other than == or != ?"); + assert(E->getOpcode() == BinaryOperator::NE && + "Complex comparison other than == or != ?"); + Result = Builder.CreateOr(ResultR, ResultI, "or.ri"); } -#endif } // ZExt result to int. diff --git a/CodeGen/CodeGenFunction.h b/CodeGen/CodeGenFunction.h index 47bdbacbb8..5ece5cd41b 100644 --- a/CodeGen/CodeGenFunction.h +++ b/CodeGen/CodeGenFunction.h @@ -182,6 +182,7 @@ class CodeGenFunction { CodeGenModule &CGM; // Per-module state. TargetInfo &Target; public: + typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy; llvm::LLVMBuilder Builder; private: @@ -416,7 +417,7 @@ public: /// EmitComplexExpr - Emit the computation of the specified expression of /// complex type, ignoring the result. - void EmitComplexExpr(const Expr *E); + ComplexPairTy EmitComplexExpr(const Expr *E); }; } // end namespace CodeGen } // end namespace clang |