зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
c6fb90a724
Коммит
58dee10ed2
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
// Complex Comparison: can only be an equality comparison.
|
||||
ComplexPairTy LHS = EmitComplexExpr(E->getLHS());
|
||||
ComplexPairTy RHS = EmitComplexExpr(E->getRHS());
|
||||
|
||||
// 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()) {
|
||||
Result = Builder.CreateAnd(ResultR, ResultI, "and.ri");
|
||||
} else if (BinaryOperator::NE == E->getOpcode()) {
|
||||
Result = Builder.CreateOr(ResultR, ResultI, "or.ri");
|
||||
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 {
|
||||
assert(0 && "Complex comparison other than == or != ?");
|
||||
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 {
|
||||
assert(E->getOpcode() == BinaryOperator::NE &&
|
||||
"Complex comparison other than == or != ?");
|
||||
Result = Builder.CreateOr(ResultR, ResultI, "or.ri");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ZExt result to int.
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче