10b57cec5SDimitry Andric //===--- CGExprComplex.cpp - Emit LLVM Code for Complex Exprs -------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This contains code to emit Expr nodes with complex types as LLVM code. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 13480093f4SDimitry Andric #include "CGOpenMPRuntime.h" 140b57cec5SDimitry Andric #include "CodeGenFunction.h" 150b57cec5SDimitry Andric #include "CodeGenModule.h" 165ffd83dbSDimitry Andric #include "ConstantEmitter.h" 170b57cec5SDimitry Andric #include "clang/AST/StmtVisitor.h" 180b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 190b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 200b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 210b57cec5SDimitry Andric #include "llvm/IR/MDBuilder.h" 220b57cec5SDimitry Andric #include "llvm/IR/Metadata.h" 230b57cec5SDimitry Andric #include <algorithm> 240b57cec5SDimitry Andric using namespace clang; 250b57cec5SDimitry Andric using namespace CodeGen; 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 280b57cec5SDimitry Andric // Complex Expression Emitter 290b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric typedef CodeGenFunction::ComplexPairTy ComplexPairTy; 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric /// Return the complex type that we are meant to emit. 340b57cec5SDimitry Andric static const ComplexType *getComplexType(QualType type) { 350b57cec5SDimitry Andric type = type.getCanonicalType(); 360b57cec5SDimitry Andric if (const ComplexType *comp = dyn_cast<ComplexType>(type)) { 370b57cec5SDimitry Andric return comp; 380b57cec5SDimitry Andric } else { 390b57cec5SDimitry Andric return cast<ComplexType>(cast<AtomicType>(type)->getValueType()); 400b57cec5SDimitry Andric } 410b57cec5SDimitry Andric } 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric namespace { 440b57cec5SDimitry Andric class ComplexExprEmitter 450b57cec5SDimitry Andric : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> { 460b57cec5SDimitry Andric CodeGenFunction &CGF; 470b57cec5SDimitry Andric CGBuilderTy &Builder; 480b57cec5SDimitry Andric bool IgnoreReal; 490b57cec5SDimitry Andric bool IgnoreImag; 500b57cec5SDimitry Andric public: 510b57cec5SDimitry Andric ComplexExprEmitter(CodeGenFunction &cgf, bool ir=false, bool ii=false) 520b57cec5SDimitry Andric : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii) { 530b57cec5SDimitry Andric } 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 570b57cec5SDimitry Andric // Utilities 580b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric bool TestAndClearIgnoreReal() { 610b57cec5SDimitry Andric bool I = IgnoreReal; 620b57cec5SDimitry Andric IgnoreReal = false; 630b57cec5SDimitry Andric return I; 640b57cec5SDimitry Andric } 650b57cec5SDimitry Andric bool TestAndClearIgnoreImag() { 660b57cec5SDimitry Andric bool I = IgnoreImag; 670b57cec5SDimitry Andric IgnoreImag = false; 680b57cec5SDimitry Andric return I; 690b57cec5SDimitry Andric } 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric /// EmitLoadOfLValue - Given an expression with complex type that represents a 720b57cec5SDimitry Andric /// value l-value, this method emits the address of the l-value, then loads 730b57cec5SDimitry Andric /// and returns the result. 740b57cec5SDimitry Andric ComplexPairTy EmitLoadOfLValue(const Expr *E) { 750b57cec5SDimitry Andric return EmitLoadOfLValue(CGF.EmitLValue(E), E->getExprLoc()); 760b57cec5SDimitry Andric } 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric ComplexPairTy EmitLoadOfLValue(LValue LV, SourceLocation Loc); 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric /// EmitStoreOfComplex - Store the specified real/imag parts into the 810b57cec5SDimitry Andric /// specified value pointer. 820b57cec5SDimitry Andric void EmitStoreOfComplex(ComplexPairTy Val, LValue LV, bool isInit); 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric /// Emit a cast from complex value Val to DestType. 850b57cec5SDimitry Andric ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType, 860b57cec5SDimitry Andric QualType DestType, SourceLocation Loc); 870b57cec5SDimitry Andric /// Emit a cast from scalar value Val to DestType. 880b57cec5SDimitry Andric ComplexPairTy EmitScalarToComplexCast(llvm::Value *Val, QualType SrcType, 890b57cec5SDimitry Andric QualType DestType, SourceLocation Loc); 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 920b57cec5SDimitry Andric // Visitor Methods 930b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric ComplexPairTy Visit(Expr *E) { 960b57cec5SDimitry Andric ApplyDebugLocation DL(CGF, E); 970b57cec5SDimitry Andric return StmtVisitor<ComplexExprEmitter, ComplexPairTy>::Visit(E); 980b57cec5SDimitry Andric } 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric ComplexPairTy VisitStmt(Stmt *S) { 1015ffd83dbSDimitry Andric S->dump(llvm::errs(), CGF.getContext()); 1020b57cec5SDimitry Andric llvm_unreachable("Stmt can't have complex result type!"); 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric ComplexPairTy VisitExpr(Expr *S); 1050b57cec5SDimitry Andric ComplexPairTy VisitConstantExpr(ConstantExpr *E) { 1065ffd83dbSDimitry Andric if (llvm::Constant *Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) 1075ffd83dbSDimitry Andric return ComplexPairTy(Result->getAggregateElement(0U), 1085ffd83dbSDimitry Andric Result->getAggregateElement(1U)); 1090b57cec5SDimitry Andric return Visit(E->getSubExpr()); 1100b57cec5SDimitry Andric } 1110b57cec5SDimitry Andric ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());} 1120b57cec5SDimitry Andric ComplexPairTy VisitGenericSelectionExpr(GenericSelectionExpr *GE) { 1130b57cec5SDimitry Andric return Visit(GE->getResultExpr()); 1140b57cec5SDimitry Andric } 1150b57cec5SDimitry Andric ComplexPairTy VisitImaginaryLiteral(const ImaginaryLiteral *IL); 1160b57cec5SDimitry Andric ComplexPairTy 1170b57cec5SDimitry Andric VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *PE) { 1180b57cec5SDimitry Andric return Visit(PE->getReplacement()); 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric ComplexPairTy VisitCoawaitExpr(CoawaitExpr *S) { 1210b57cec5SDimitry Andric return CGF.EmitCoawaitExpr(*S).getComplexVal(); 1220b57cec5SDimitry Andric } 1230b57cec5SDimitry Andric ComplexPairTy VisitCoyieldExpr(CoyieldExpr *S) { 1240b57cec5SDimitry Andric return CGF.EmitCoyieldExpr(*S).getComplexVal(); 1250b57cec5SDimitry Andric } 1260b57cec5SDimitry Andric ComplexPairTy VisitUnaryCoawait(const UnaryOperator *E) { 1270b57cec5SDimitry Andric return Visit(E->getSubExpr()); 1280b57cec5SDimitry Andric } 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric ComplexPairTy emitConstant(const CodeGenFunction::ConstantEmission &Constant, 1310b57cec5SDimitry Andric Expr *E) { 1320b57cec5SDimitry Andric assert(Constant && "not a constant"); 1330b57cec5SDimitry Andric if (Constant.isReference()) 1340b57cec5SDimitry Andric return EmitLoadOfLValue(Constant.getReferenceLValue(CGF, E), 1350b57cec5SDimitry Andric E->getExprLoc()); 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric llvm::Constant *pair = Constant.getValue(); 1380b57cec5SDimitry Andric return ComplexPairTy(pair->getAggregateElement(0U), 1390b57cec5SDimitry Andric pair->getAggregateElement(1U)); 1400b57cec5SDimitry Andric } 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric // l-values. 1430b57cec5SDimitry Andric ComplexPairTy VisitDeclRefExpr(DeclRefExpr *E) { 1440b57cec5SDimitry Andric if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E)) 1450b57cec5SDimitry Andric return emitConstant(Constant, E); 1460b57cec5SDimitry Andric return EmitLoadOfLValue(E); 1470b57cec5SDimitry Andric } 1480b57cec5SDimitry Andric ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { 1490b57cec5SDimitry Andric return EmitLoadOfLValue(E); 1500b57cec5SDimitry Andric } 1510b57cec5SDimitry Andric ComplexPairTy VisitObjCMessageExpr(ObjCMessageExpr *E) { 1520b57cec5SDimitry Andric return CGF.EmitObjCMessageExpr(E).getComplexVal(); 1530b57cec5SDimitry Andric } 1540b57cec5SDimitry Andric ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); } 1550b57cec5SDimitry Andric ComplexPairTy VisitMemberExpr(MemberExpr *ME) { 1560b57cec5SDimitry Andric if (CodeGenFunction::ConstantEmission Constant = 1570b57cec5SDimitry Andric CGF.tryEmitAsConstant(ME)) { 1580b57cec5SDimitry Andric CGF.EmitIgnoredExpr(ME->getBase()); 1590b57cec5SDimitry Andric return emitConstant(Constant, ME); 1600b57cec5SDimitry Andric } 1610b57cec5SDimitry Andric return EmitLoadOfLValue(ME); 1620b57cec5SDimitry Andric } 1630b57cec5SDimitry Andric ComplexPairTy VisitOpaqueValueExpr(OpaqueValueExpr *E) { 1640b57cec5SDimitry Andric if (E->isGLValue()) 1650b57cec5SDimitry Andric return EmitLoadOfLValue(CGF.getOrCreateOpaqueLValueMapping(E), 1660b57cec5SDimitry Andric E->getExprLoc()); 1670b57cec5SDimitry Andric return CGF.getOrCreateOpaqueRValueMapping(E).getComplexVal(); 1680b57cec5SDimitry Andric } 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric ComplexPairTy VisitPseudoObjectExpr(PseudoObjectExpr *E) { 1710b57cec5SDimitry Andric return CGF.EmitPseudoObjectRValue(E).getComplexVal(); 1720b57cec5SDimitry Andric } 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric // FIXME: CompoundLiteralExpr 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric ComplexPairTy EmitCast(CastKind CK, Expr *Op, QualType DestTy); 1770b57cec5SDimitry Andric ComplexPairTy VisitImplicitCastExpr(ImplicitCastExpr *E) { 1780b57cec5SDimitry Andric // Unlike for scalars, we don't have to worry about function->ptr demotion 1790b57cec5SDimitry Andric // here. 1800b57cec5SDimitry Andric return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType()); 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric ComplexPairTy VisitCastExpr(CastExpr *E) { 1830b57cec5SDimitry Andric if (const auto *ECE = dyn_cast<ExplicitCastExpr>(E)) 1840b57cec5SDimitry Andric CGF.CGM.EmitExplicitCastExprType(ECE, &CGF); 1850b57cec5SDimitry Andric return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType()); 1860b57cec5SDimitry Andric } 1870b57cec5SDimitry Andric ComplexPairTy VisitCallExpr(const CallExpr *E); 1880b57cec5SDimitry Andric ComplexPairTy VisitStmtExpr(const StmtExpr *E); 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric // Operators. 1910b57cec5SDimitry Andric ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E, 1920b57cec5SDimitry Andric bool isInc, bool isPre) { 1930b57cec5SDimitry Andric LValue LV = CGF.EmitLValue(E->getSubExpr()); 1940b57cec5SDimitry Andric return CGF.EmitComplexPrePostIncDec(E, LV, isInc, isPre); 1950b57cec5SDimitry Andric } 1960b57cec5SDimitry Andric ComplexPairTy VisitUnaryPostDec(const UnaryOperator *E) { 1970b57cec5SDimitry Andric return VisitPrePostIncDec(E, false, false); 1980b57cec5SDimitry Andric } 1990b57cec5SDimitry Andric ComplexPairTy VisitUnaryPostInc(const UnaryOperator *E) { 2000b57cec5SDimitry Andric return VisitPrePostIncDec(E, true, false); 2010b57cec5SDimitry Andric } 2020b57cec5SDimitry Andric ComplexPairTy VisitUnaryPreDec(const UnaryOperator *E) { 2030b57cec5SDimitry Andric return VisitPrePostIncDec(E, false, true); 2040b57cec5SDimitry Andric } 2050b57cec5SDimitry Andric ComplexPairTy VisitUnaryPreInc(const UnaryOperator *E) { 2060b57cec5SDimitry Andric return VisitPrePostIncDec(E, true, true); 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); } 209bdd1243dSDimitry Andric 210bdd1243dSDimitry Andric ComplexPairTy VisitUnaryPlus(const UnaryOperator *E, 211bdd1243dSDimitry Andric QualType PromotionType = QualType()); 212bdd1243dSDimitry Andric ComplexPairTy VisitPlus(const UnaryOperator *E, QualType PromotionType); 213bdd1243dSDimitry Andric ComplexPairTy VisitUnaryMinus(const UnaryOperator *E, 214bdd1243dSDimitry Andric QualType PromotionType = QualType()); 215bdd1243dSDimitry Andric ComplexPairTy VisitMinus(const UnaryOperator *E, QualType PromotionType); 2160b57cec5SDimitry Andric ComplexPairTy VisitUnaryNot (const UnaryOperator *E); 2170b57cec5SDimitry Andric // LNot,Real,Imag never return complex. 2180b57cec5SDimitry Andric ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) { 2190b57cec5SDimitry Andric return Visit(E->getSubExpr()); 2200b57cec5SDimitry Andric } 2210b57cec5SDimitry Andric ComplexPairTy VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) { 2220b57cec5SDimitry Andric CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE); 2230b57cec5SDimitry Andric return Visit(DAE->getExpr()); 2240b57cec5SDimitry Andric } 2250b57cec5SDimitry Andric ComplexPairTy VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) { 2260b57cec5SDimitry Andric CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE); 2270b57cec5SDimitry Andric return Visit(DIE->getExpr()); 2280b57cec5SDimitry Andric } 2290b57cec5SDimitry Andric ComplexPairTy VisitExprWithCleanups(ExprWithCleanups *E) { 2300b57cec5SDimitry Andric CodeGenFunction::RunCleanupsScope Scope(CGF); 2310b57cec5SDimitry Andric ComplexPairTy Vals = Visit(E->getSubExpr()); 2320b57cec5SDimitry Andric // Defend against dominance problems caused by jumps out of expression 2330b57cec5SDimitry Andric // evaluation through the shared cleanup block. 2340b57cec5SDimitry Andric Scope.ForceCleanup({&Vals.first, &Vals.second}); 2350b57cec5SDimitry Andric return Vals; 2360b57cec5SDimitry Andric } 2370b57cec5SDimitry Andric ComplexPairTy VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { 2380b57cec5SDimitry Andric assert(E->getType()->isAnyComplexType() && "Expected complex type!"); 2390b57cec5SDimitry Andric QualType Elem = E->getType()->castAs<ComplexType>()->getElementType(); 2400b57cec5SDimitry Andric llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem)); 2410b57cec5SDimitry Andric return ComplexPairTy(Null, Null); 2420b57cec5SDimitry Andric } 2430b57cec5SDimitry Andric ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) { 2440b57cec5SDimitry Andric assert(E->getType()->isAnyComplexType() && "Expected complex type!"); 2450b57cec5SDimitry Andric QualType Elem = E->getType()->castAs<ComplexType>()->getElementType(); 2460b57cec5SDimitry Andric llvm::Constant *Null = 2470b57cec5SDimitry Andric llvm::Constant::getNullValue(CGF.ConvertType(Elem)); 2480b57cec5SDimitry Andric return ComplexPairTy(Null, Null); 2490b57cec5SDimitry Andric } 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric struct BinOpInfo { 2520b57cec5SDimitry Andric ComplexPairTy LHS; 2530b57cec5SDimitry Andric ComplexPairTy RHS; 2540b57cec5SDimitry Andric QualType Ty; // Computation Type. 255bdd1243dSDimitry Andric FPOptions FPFeatures; 2560b57cec5SDimitry Andric }; 2570b57cec5SDimitry Andric 258bdd1243dSDimitry Andric BinOpInfo EmitBinOps(const BinaryOperator *E, 259bdd1243dSDimitry Andric QualType PromotionTy = QualType()); 260bdd1243dSDimitry Andric ComplexPairTy EmitPromoted(const Expr *E, QualType PromotionTy); 261bdd1243dSDimitry Andric ComplexPairTy EmitPromotedComplexOperand(const Expr *E, QualType PromotionTy); 2620b57cec5SDimitry Andric LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E, 2630b57cec5SDimitry Andric ComplexPairTy (ComplexExprEmitter::*Func) 2640b57cec5SDimitry Andric (const BinOpInfo &), 2650b57cec5SDimitry Andric RValue &Val); 2660b57cec5SDimitry Andric ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E, 2670b57cec5SDimitry Andric ComplexPairTy (ComplexExprEmitter::*Func) 2680b57cec5SDimitry Andric (const BinOpInfo &)); 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric ComplexPairTy EmitBinAdd(const BinOpInfo &Op); 2710b57cec5SDimitry Andric ComplexPairTy EmitBinSub(const BinOpInfo &Op); 2720b57cec5SDimitry Andric ComplexPairTy EmitBinMul(const BinOpInfo &Op); 2730b57cec5SDimitry Andric ComplexPairTy EmitBinDiv(const BinOpInfo &Op); 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric ComplexPairTy EmitComplexBinOpLibCall(StringRef LibCallName, 2760b57cec5SDimitry Andric const BinOpInfo &Op); 2770b57cec5SDimitry Andric 278bdd1243dSDimitry Andric QualType getPromotionType(QualType Ty) { 279bdd1243dSDimitry Andric if (auto *CT = Ty->getAs<ComplexType>()) { 280bdd1243dSDimitry Andric QualType ElementType = CT->getElementType(); 281bdd1243dSDimitry Andric if (ElementType.UseExcessPrecision(CGF.getContext())) 282bdd1243dSDimitry Andric return CGF.getContext().getComplexType(CGF.getContext().FloatTy); 2830b57cec5SDimitry Andric } 284bdd1243dSDimitry Andric if (Ty.UseExcessPrecision(CGF.getContext())) 285bdd1243dSDimitry Andric return CGF.getContext().FloatTy; 286bdd1243dSDimitry Andric return QualType(); 2870b57cec5SDimitry Andric } 288bdd1243dSDimitry Andric 289bdd1243dSDimitry Andric #define HANDLEBINOP(OP) \ 290bdd1243dSDimitry Andric ComplexPairTy VisitBin##OP(const BinaryOperator *E) { \ 291bdd1243dSDimitry Andric QualType promotionTy = getPromotionType(E->getType()); \ 292bdd1243dSDimitry Andric ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy)); \ 293bdd1243dSDimitry Andric if (!promotionTy.isNull()) \ 294bdd1243dSDimitry Andric result = \ 295bdd1243dSDimitry Andric CGF.EmitUnPromotedValue(result, E->getType()); \ 296bdd1243dSDimitry Andric return result; \ 2970b57cec5SDimitry Andric } 298bdd1243dSDimitry Andric 299bdd1243dSDimitry Andric HANDLEBINOP(Mul) 300bdd1243dSDimitry Andric HANDLEBINOP(Div) 301bdd1243dSDimitry Andric HANDLEBINOP(Add) 302bdd1243dSDimitry Andric HANDLEBINOP(Sub) 303bdd1243dSDimitry Andric #undef HANDLEBINOP 3040b57cec5SDimitry Andric 305a7dea167SDimitry Andric ComplexPairTy VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) { 306a7dea167SDimitry Andric return Visit(E->getSemanticForm()); 307a7dea167SDimitry Andric } 308a7dea167SDimitry Andric 3090b57cec5SDimitry Andric // Compound assignments. 3100b57cec5SDimitry Andric ComplexPairTy VisitBinAddAssign(const CompoundAssignOperator *E) { 3110b57cec5SDimitry Andric return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd); 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric ComplexPairTy VisitBinSubAssign(const CompoundAssignOperator *E) { 3140b57cec5SDimitry Andric return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub); 3150b57cec5SDimitry Andric } 3160b57cec5SDimitry Andric ComplexPairTy VisitBinMulAssign(const CompoundAssignOperator *E) { 3170b57cec5SDimitry Andric return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul); 3180b57cec5SDimitry Andric } 3190b57cec5SDimitry Andric ComplexPairTy VisitBinDivAssign(const CompoundAssignOperator *E) { 3200b57cec5SDimitry Andric return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv); 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric // GCC rejects rem/and/or/xor for integer complex. 3240b57cec5SDimitry Andric // Logical and/or always return int, never complex. 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric // No comparisons produce a complex result. 3270b57cec5SDimitry Andric 3280b57cec5SDimitry Andric LValue EmitBinAssignLValue(const BinaryOperator *E, 3290b57cec5SDimitry Andric ComplexPairTy &Val); 3300b57cec5SDimitry Andric ComplexPairTy VisitBinAssign (const BinaryOperator *E); 3310b57cec5SDimitry Andric ComplexPairTy VisitBinComma (const BinaryOperator *E); 3320b57cec5SDimitry Andric 3330b57cec5SDimitry Andric 3340b57cec5SDimitry Andric ComplexPairTy 3350b57cec5SDimitry Andric VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO); 3360b57cec5SDimitry Andric ComplexPairTy VisitChooseExpr(ChooseExpr *CE); 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric ComplexPairTy VisitInitListExpr(InitListExpr *E); 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric ComplexPairTy VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { 3410b57cec5SDimitry Andric return EmitLoadOfLValue(E); 3420b57cec5SDimitry Andric } 3430b57cec5SDimitry Andric 3440b57cec5SDimitry Andric ComplexPairTy VisitVAArgExpr(VAArgExpr *E); 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric ComplexPairTy VisitAtomicExpr(AtomicExpr *E) { 3470b57cec5SDimitry Andric return CGF.EmitAtomicExpr(E).getComplexVal(); 3480b57cec5SDimitry Andric } 3490b57cec5SDimitry Andric }; 3500b57cec5SDimitry Andric } // end anonymous namespace. 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 3530b57cec5SDimitry Andric // Utilities 3540b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric Address CodeGenFunction::emitAddrOfRealComponent(Address addr, 3570b57cec5SDimitry Andric QualType complexType) { 3580b57cec5SDimitry Andric return Builder.CreateStructGEP(addr, 0, addr.getName() + ".realp"); 3590b57cec5SDimitry Andric } 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andric Address CodeGenFunction::emitAddrOfImagComponent(Address addr, 3620b57cec5SDimitry Andric QualType complexType) { 3630b57cec5SDimitry Andric return Builder.CreateStructGEP(addr, 1, addr.getName() + ".imagp"); 3640b57cec5SDimitry Andric } 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andric /// EmitLoadOfLValue - Given an RValue reference for a complex, emit code to 3670b57cec5SDimitry Andric /// load the real and imaginary pieces, returning them as Real/Imag. 3680b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitLoadOfLValue(LValue lvalue, 3690b57cec5SDimitry Andric SourceLocation loc) { 3700b57cec5SDimitry Andric assert(lvalue.isSimple() && "non-simple complex l-value?"); 3710b57cec5SDimitry Andric if (lvalue.getType()->isAtomicType()) 3720b57cec5SDimitry Andric return CGF.EmitAtomicLoad(lvalue, loc).getComplexVal(); 3730b57cec5SDimitry Andric 374480093f4SDimitry Andric Address SrcPtr = lvalue.getAddress(CGF); 3750b57cec5SDimitry Andric bool isVolatile = lvalue.isVolatileQualified(); 3760b57cec5SDimitry Andric 3770b57cec5SDimitry Andric llvm::Value *Real = nullptr, *Imag = nullptr; 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric if (!IgnoreReal || isVolatile) { 3800b57cec5SDimitry Andric Address RealP = CGF.emitAddrOfRealComponent(SrcPtr, lvalue.getType()); 3810b57cec5SDimitry Andric Real = Builder.CreateLoad(RealP, isVolatile, SrcPtr.getName() + ".real"); 3820b57cec5SDimitry Andric } 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andric if (!IgnoreImag || isVolatile) { 3850b57cec5SDimitry Andric Address ImagP = CGF.emitAddrOfImagComponent(SrcPtr, lvalue.getType()); 3860b57cec5SDimitry Andric Imag = Builder.CreateLoad(ImagP, isVolatile, SrcPtr.getName() + ".imag"); 3870b57cec5SDimitry Andric } 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric return ComplexPairTy(Real, Imag); 3900b57cec5SDimitry Andric } 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric /// EmitStoreOfComplex - Store the specified real/imag parts into the 3930b57cec5SDimitry Andric /// specified value pointer. 3940b57cec5SDimitry Andric void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, LValue lvalue, 3950b57cec5SDimitry Andric bool isInit) { 3960b57cec5SDimitry Andric if (lvalue.getType()->isAtomicType() || 3970b57cec5SDimitry Andric (!isInit && CGF.LValueIsSuitableForInlineAtomic(lvalue))) 3980b57cec5SDimitry Andric return CGF.EmitAtomicStore(RValue::getComplex(Val), lvalue, isInit); 3990b57cec5SDimitry Andric 400480093f4SDimitry Andric Address Ptr = lvalue.getAddress(CGF); 4010b57cec5SDimitry Andric Address RealPtr = CGF.emitAddrOfRealComponent(Ptr, lvalue.getType()); 4020b57cec5SDimitry Andric Address ImagPtr = CGF.emitAddrOfImagComponent(Ptr, lvalue.getType()); 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric Builder.CreateStore(Val.first, RealPtr, lvalue.isVolatileQualified()); 4050b57cec5SDimitry Andric Builder.CreateStore(Val.second, ImagPtr, lvalue.isVolatileQualified()); 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 4110b57cec5SDimitry Andric // Visitor Methods 4120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) { 4150b57cec5SDimitry Andric CGF.ErrorUnsupported(E, "complex expression"); 4160b57cec5SDimitry Andric llvm::Type *EltTy = 4170b57cec5SDimitry Andric CGF.ConvertType(getComplexType(E->getType())->getElementType()); 4180b57cec5SDimitry Andric llvm::Value *U = llvm::UndefValue::get(EltTy); 4190b57cec5SDimitry Andric return ComplexPairTy(U, U); 4200b57cec5SDimitry Andric } 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter:: 4230b57cec5SDimitry Andric VisitImaginaryLiteral(const ImaginaryLiteral *IL) { 4240b57cec5SDimitry Andric llvm::Value *Imag = CGF.EmitScalarExpr(IL->getSubExpr()); 4250b57cec5SDimitry Andric return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag); 4260b57cec5SDimitry Andric } 4270b57cec5SDimitry Andric 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) { 4300b57cec5SDimitry Andric if (E->getCallReturnType(CGF.getContext())->isReferenceType()) 4310b57cec5SDimitry Andric return EmitLoadOfLValue(E); 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric return CGF.EmitCallExpr(E).getComplexVal(); 4340b57cec5SDimitry Andric } 4350b57cec5SDimitry Andric 4360b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) { 4370b57cec5SDimitry Andric CodeGenFunction::StmtExprEvaluation eval(CGF); 4380b57cec5SDimitry Andric Address RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(), true); 4390b57cec5SDimitry Andric assert(RetAlloca.isValid() && "Expected complex return value"); 4400b57cec5SDimitry Andric return EmitLoadOfLValue(CGF.MakeAddrLValue(RetAlloca, E->getType()), 4410b57cec5SDimitry Andric E->getExprLoc()); 4420b57cec5SDimitry Andric } 4430b57cec5SDimitry Andric 4440b57cec5SDimitry Andric /// Emit a cast from complex value Val to DestType. 4450b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val, 4460b57cec5SDimitry Andric QualType SrcType, 4470b57cec5SDimitry Andric QualType DestType, 4480b57cec5SDimitry Andric SourceLocation Loc) { 4490b57cec5SDimitry Andric // Get the src/dest element type. 4500b57cec5SDimitry Andric SrcType = SrcType->castAs<ComplexType>()->getElementType(); 4510b57cec5SDimitry Andric DestType = DestType->castAs<ComplexType>()->getElementType(); 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andric // C99 6.3.1.6: When a value of complex type is converted to another 4540b57cec5SDimitry Andric // complex type, both the real and imaginary parts follow the conversion 4550b57cec5SDimitry Andric // rules for the corresponding real types. 4565ffd83dbSDimitry Andric if (Val.first) 4570b57cec5SDimitry Andric Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType, Loc); 4585ffd83dbSDimitry Andric if (Val.second) 4590b57cec5SDimitry Andric Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType, Loc); 4600b57cec5SDimitry Andric return Val; 4610b57cec5SDimitry Andric } 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val, 4640b57cec5SDimitry Andric QualType SrcType, 4650b57cec5SDimitry Andric QualType DestType, 4660b57cec5SDimitry Andric SourceLocation Loc) { 4670b57cec5SDimitry Andric // Convert the input element to the element type of the complex. 4680b57cec5SDimitry Andric DestType = DestType->castAs<ComplexType>()->getElementType(); 4690b57cec5SDimitry Andric Val = CGF.EmitScalarConversion(Val, SrcType, DestType, Loc); 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric // Return (realval, 0). 4720b57cec5SDimitry Andric return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType())); 4730b57cec5SDimitry Andric } 4740b57cec5SDimitry Andric 4750b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op, 4760b57cec5SDimitry Andric QualType DestTy) { 4770b57cec5SDimitry Andric switch (CK) { 4780b57cec5SDimitry Andric case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!"); 4790b57cec5SDimitry Andric 4800b57cec5SDimitry Andric // Atomic to non-atomic casts may be more than a no-op for some platforms and 4810b57cec5SDimitry Andric // for some types. 4820b57cec5SDimitry Andric case CK_AtomicToNonAtomic: 4830b57cec5SDimitry Andric case CK_NonAtomicToAtomic: 4840b57cec5SDimitry Andric case CK_NoOp: 4850b57cec5SDimitry Andric case CK_LValueToRValue: 4860b57cec5SDimitry Andric case CK_UserDefinedConversion: 4870b57cec5SDimitry Andric return Visit(Op); 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric case CK_LValueBitCast: { 4900b57cec5SDimitry Andric LValue origLV = CGF.EmitLValue(Op); 491*fe013be4SDimitry Andric Address V = origLV.getAddress(CGF).withElementType(CGF.ConvertType(DestTy)); 4920b57cec5SDimitry Andric return EmitLoadOfLValue(CGF.MakeAddrLValue(V, DestTy), Op->getExprLoc()); 4930b57cec5SDimitry Andric } 4940b57cec5SDimitry Andric 4950b57cec5SDimitry Andric case CK_LValueToRValueBitCast: { 4960b57cec5SDimitry Andric LValue SourceLVal = CGF.EmitLValue(Op); 497*fe013be4SDimitry Andric Address Addr = SourceLVal.getAddress(CGF).withElementType( 4980b57cec5SDimitry Andric CGF.ConvertTypeForMem(DestTy)); 4990b57cec5SDimitry Andric LValue DestLV = CGF.MakeAddrLValue(Addr, DestTy); 5000b57cec5SDimitry Andric DestLV.setTBAAInfo(TBAAAccessInfo::getMayAliasInfo()); 5010b57cec5SDimitry Andric return EmitLoadOfLValue(DestLV, Op->getExprLoc()); 5020b57cec5SDimitry Andric } 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andric case CK_BitCast: 5050b57cec5SDimitry Andric case CK_BaseToDerived: 5060b57cec5SDimitry Andric case CK_DerivedToBase: 5070b57cec5SDimitry Andric case CK_UncheckedDerivedToBase: 5080b57cec5SDimitry Andric case CK_Dynamic: 5090b57cec5SDimitry Andric case CK_ToUnion: 5100b57cec5SDimitry Andric case CK_ArrayToPointerDecay: 5110b57cec5SDimitry Andric case CK_FunctionToPointerDecay: 5120b57cec5SDimitry Andric case CK_NullToPointer: 5130b57cec5SDimitry Andric case CK_NullToMemberPointer: 5140b57cec5SDimitry Andric case CK_BaseToDerivedMemberPointer: 5150b57cec5SDimitry Andric case CK_DerivedToBaseMemberPointer: 5160b57cec5SDimitry Andric case CK_MemberPointerToBoolean: 5170b57cec5SDimitry Andric case CK_ReinterpretMemberPointer: 5180b57cec5SDimitry Andric case CK_ConstructorConversion: 5190b57cec5SDimitry Andric case CK_IntegralToPointer: 5200b57cec5SDimitry Andric case CK_PointerToIntegral: 5210b57cec5SDimitry Andric case CK_PointerToBoolean: 5220b57cec5SDimitry Andric case CK_ToVoid: 5230b57cec5SDimitry Andric case CK_VectorSplat: 5240b57cec5SDimitry Andric case CK_IntegralCast: 5250b57cec5SDimitry Andric case CK_BooleanToSignedIntegral: 5260b57cec5SDimitry Andric case CK_IntegralToBoolean: 5270b57cec5SDimitry Andric case CK_IntegralToFloating: 5280b57cec5SDimitry Andric case CK_FloatingToIntegral: 5290b57cec5SDimitry Andric case CK_FloatingToBoolean: 5300b57cec5SDimitry Andric case CK_FloatingCast: 5310b57cec5SDimitry Andric case CK_CPointerToObjCPointerCast: 5320b57cec5SDimitry Andric case CK_BlockPointerToObjCPointerCast: 5330b57cec5SDimitry Andric case CK_AnyPointerToBlockPointerCast: 5340b57cec5SDimitry Andric case CK_ObjCObjectLValueCast: 5350b57cec5SDimitry Andric case CK_FloatingComplexToReal: 5360b57cec5SDimitry Andric case CK_FloatingComplexToBoolean: 5370b57cec5SDimitry Andric case CK_IntegralComplexToReal: 5380b57cec5SDimitry Andric case CK_IntegralComplexToBoolean: 5390b57cec5SDimitry Andric case CK_ARCProduceObject: 5400b57cec5SDimitry Andric case CK_ARCConsumeObject: 5410b57cec5SDimitry Andric case CK_ARCReclaimReturnedObject: 5420b57cec5SDimitry Andric case CK_ARCExtendBlockObject: 5430b57cec5SDimitry Andric case CK_CopyAndAutoreleaseBlockObject: 5440b57cec5SDimitry Andric case CK_BuiltinFnToFnPtr: 5450b57cec5SDimitry Andric case CK_ZeroToOCLOpaqueType: 5460b57cec5SDimitry Andric case CK_AddressSpaceConversion: 5470b57cec5SDimitry Andric case CK_IntToOCLSampler: 548e8d8bef9SDimitry Andric case CK_FloatingToFixedPoint: 549e8d8bef9SDimitry Andric case CK_FixedPointToFloating: 5500b57cec5SDimitry Andric case CK_FixedPointCast: 5510b57cec5SDimitry Andric case CK_FixedPointToBoolean: 5520b57cec5SDimitry Andric case CK_FixedPointToIntegral: 5530b57cec5SDimitry Andric case CK_IntegralToFixedPoint: 554fe6060f1SDimitry Andric case CK_MatrixCast: 5550b57cec5SDimitry Andric llvm_unreachable("invalid cast kind for complex value"); 5560b57cec5SDimitry Andric 5570b57cec5SDimitry Andric case CK_FloatingRealToComplex: 558e8d8bef9SDimitry Andric case CK_IntegralRealToComplex: { 559e8d8bef9SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op); 5600b57cec5SDimitry Andric return EmitScalarToComplexCast(CGF.EmitScalarExpr(Op), Op->getType(), 5610b57cec5SDimitry Andric DestTy, Op->getExprLoc()); 562e8d8bef9SDimitry Andric } 5630b57cec5SDimitry Andric 5640b57cec5SDimitry Andric case CK_FloatingComplexCast: 5650b57cec5SDimitry Andric case CK_FloatingComplexToIntegralComplex: 5660b57cec5SDimitry Andric case CK_IntegralComplexCast: 567e8d8bef9SDimitry Andric case CK_IntegralComplexToFloatingComplex: { 568e8d8bef9SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op); 5690b57cec5SDimitry Andric return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy, 5700b57cec5SDimitry Andric Op->getExprLoc()); 5710b57cec5SDimitry Andric } 572e8d8bef9SDimitry Andric } 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric llvm_unreachable("unknown cast resulting in complex value"); 5750b57cec5SDimitry Andric } 5760b57cec5SDimitry Andric 577bdd1243dSDimitry Andric ComplexPairTy ComplexExprEmitter::VisitUnaryPlus(const UnaryOperator *E, 578bdd1243dSDimitry Andric QualType PromotionType) { 579bdd1243dSDimitry Andric QualType promotionTy = PromotionType.isNull() 580bdd1243dSDimitry Andric ? getPromotionType(E->getSubExpr()->getType()) 581bdd1243dSDimitry Andric : PromotionType; 582bdd1243dSDimitry Andric ComplexPairTy result = VisitPlus(E, promotionTy); 583bdd1243dSDimitry Andric if (!promotionTy.isNull()) 584bdd1243dSDimitry Andric return CGF.EmitUnPromotedValue(result, E->getSubExpr()->getType()); 585bdd1243dSDimitry Andric return result; 586bdd1243dSDimitry Andric } 587bdd1243dSDimitry Andric 588bdd1243dSDimitry Andric ComplexPairTy ComplexExprEmitter::VisitPlus(const UnaryOperator *E, 589bdd1243dSDimitry Andric QualType PromotionType) { 5900b57cec5SDimitry Andric TestAndClearIgnoreReal(); 5910b57cec5SDimitry Andric TestAndClearIgnoreImag(); 592bdd1243dSDimitry Andric if (!PromotionType.isNull()) 593bdd1243dSDimitry Andric return CGF.EmitPromotedComplexExpr(E->getSubExpr(), PromotionType); 594bdd1243dSDimitry Andric return Visit(E->getSubExpr()); 595bdd1243dSDimitry Andric } 596bdd1243dSDimitry Andric 597bdd1243dSDimitry Andric ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E, 598bdd1243dSDimitry Andric QualType PromotionType) { 599bdd1243dSDimitry Andric QualType promotionTy = PromotionType.isNull() 600bdd1243dSDimitry Andric ? getPromotionType(E->getSubExpr()->getType()) 601bdd1243dSDimitry Andric : PromotionType; 602bdd1243dSDimitry Andric ComplexPairTy result = VisitMinus(E, promotionTy); 603bdd1243dSDimitry Andric if (!promotionTy.isNull()) 604bdd1243dSDimitry Andric return CGF.EmitUnPromotedValue(result, E->getSubExpr()->getType()); 605bdd1243dSDimitry Andric return result; 606bdd1243dSDimitry Andric } 607bdd1243dSDimitry Andric ComplexPairTy ComplexExprEmitter::VisitMinus(const UnaryOperator *E, 608bdd1243dSDimitry Andric QualType PromotionType) { 609bdd1243dSDimitry Andric TestAndClearIgnoreReal(); 610bdd1243dSDimitry Andric TestAndClearIgnoreImag(); 611bdd1243dSDimitry Andric ComplexPairTy Op; 612bdd1243dSDimitry Andric if (!PromotionType.isNull()) 613bdd1243dSDimitry Andric Op = CGF.EmitPromotedComplexExpr(E->getSubExpr(), PromotionType); 614bdd1243dSDimitry Andric else 615bdd1243dSDimitry Andric Op = Visit(E->getSubExpr()); 6160b57cec5SDimitry Andric 6170b57cec5SDimitry Andric llvm::Value *ResR, *ResI; 6180b57cec5SDimitry Andric if (Op.first->getType()->isFloatingPointTy()) { 6190b57cec5SDimitry Andric ResR = Builder.CreateFNeg(Op.first, "neg.r"); 6200b57cec5SDimitry Andric ResI = Builder.CreateFNeg(Op.second, "neg.i"); 6210b57cec5SDimitry Andric } else { 6220b57cec5SDimitry Andric ResR = Builder.CreateNeg(Op.first, "neg.r"); 6230b57cec5SDimitry Andric ResI = Builder.CreateNeg(Op.second, "neg.i"); 6240b57cec5SDimitry Andric } 6250b57cec5SDimitry Andric return ComplexPairTy(ResR, ResI); 6260b57cec5SDimitry Andric } 6270b57cec5SDimitry Andric 6280b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) { 6290b57cec5SDimitry Andric TestAndClearIgnoreReal(); 6300b57cec5SDimitry Andric TestAndClearIgnoreImag(); 6310b57cec5SDimitry Andric // ~(a+ib) = a + i*-b 6320b57cec5SDimitry Andric ComplexPairTy Op = Visit(E->getSubExpr()); 6330b57cec5SDimitry Andric llvm::Value *ResI; 6340b57cec5SDimitry Andric if (Op.second->getType()->isFloatingPointTy()) 6350b57cec5SDimitry Andric ResI = Builder.CreateFNeg(Op.second, "conj.i"); 6360b57cec5SDimitry Andric else 6370b57cec5SDimitry Andric ResI = Builder.CreateNeg(Op.second, "conj.i"); 6380b57cec5SDimitry Andric 6390b57cec5SDimitry Andric return ComplexPairTy(Op.first, ResI); 6400b57cec5SDimitry Andric } 6410b57cec5SDimitry Andric 6420b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitBinAdd(const BinOpInfo &Op) { 6430b57cec5SDimitry Andric llvm::Value *ResR, *ResI; 6440b57cec5SDimitry Andric 6450b57cec5SDimitry Andric if (Op.LHS.first->getType()->isFloatingPointTy()) { 646bdd1243dSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures); 6470b57cec5SDimitry Andric ResR = Builder.CreateFAdd(Op.LHS.first, Op.RHS.first, "add.r"); 6480b57cec5SDimitry Andric if (Op.LHS.second && Op.RHS.second) 6490b57cec5SDimitry Andric ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second, "add.i"); 6500b57cec5SDimitry Andric else 6510b57cec5SDimitry Andric ResI = Op.LHS.second ? Op.LHS.second : Op.RHS.second; 6520b57cec5SDimitry Andric assert(ResI && "Only one operand may be real!"); 6530b57cec5SDimitry Andric } else { 6540b57cec5SDimitry Andric ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first, "add.r"); 6550b57cec5SDimitry Andric assert(Op.LHS.second && Op.RHS.second && 6560b57cec5SDimitry Andric "Both operands of integer complex operators must be complex!"); 6570b57cec5SDimitry Andric ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second, "add.i"); 6580b57cec5SDimitry Andric } 6590b57cec5SDimitry Andric return ComplexPairTy(ResR, ResI); 6600b57cec5SDimitry Andric } 6610b57cec5SDimitry Andric 6620b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitBinSub(const BinOpInfo &Op) { 6630b57cec5SDimitry Andric llvm::Value *ResR, *ResI; 6640b57cec5SDimitry Andric if (Op.LHS.first->getType()->isFloatingPointTy()) { 665bdd1243dSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures); 6660b57cec5SDimitry Andric ResR = Builder.CreateFSub(Op.LHS.first, Op.RHS.first, "sub.r"); 6670b57cec5SDimitry Andric if (Op.LHS.second && Op.RHS.second) 6680b57cec5SDimitry Andric ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second, "sub.i"); 6690b57cec5SDimitry Andric else 6700b57cec5SDimitry Andric ResI = Op.LHS.second ? Op.LHS.second 6710b57cec5SDimitry Andric : Builder.CreateFNeg(Op.RHS.second, "sub.i"); 6720b57cec5SDimitry Andric assert(ResI && "Only one operand may be real!"); 6730b57cec5SDimitry Andric } else { 6740b57cec5SDimitry Andric ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first, "sub.r"); 6750b57cec5SDimitry Andric assert(Op.LHS.second && Op.RHS.second && 6760b57cec5SDimitry Andric "Both operands of integer complex operators must be complex!"); 6770b57cec5SDimitry Andric ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second, "sub.i"); 6780b57cec5SDimitry Andric } 6790b57cec5SDimitry Andric return ComplexPairTy(ResR, ResI); 6800b57cec5SDimitry Andric } 6810b57cec5SDimitry Andric 6820b57cec5SDimitry Andric /// Emit a libcall for a binary operation on complex types. 6830b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName, 6840b57cec5SDimitry Andric const BinOpInfo &Op) { 6850b57cec5SDimitry Andric CallArgList Args; 6860b57cec5SDimitry Andric Args.add(RValue::get(Op.LHS.first), 6870b57cec5SDimitry Andric Op.Ty->castAs<ComplexType>()->getElementType()); 6880b57cec5SDimitry Andric Args.add(RValue::get(Op.LHS.second), 6890b57cec5SDimitry Andric Op.Ty->castAs<ComplexType>()->getElementType()); 6900b57cec5SDimitry Andric Args.add(RValue::get(Op.RHS.first), 6910b57cec5SDimitry Andric Op.Ty->castAs<ComplexType>()->getElementType()); 6920b57cec5SDimitry Andric Args.add(RValue::get(Op.RHS.second), 6930b57cec5SDimitry Andric Op.Ty->castAs<ComplexType>()->getElementType()); 6940b57cec5SDimitry Andric 6950b57cec5SDimitry Andric // We *must* use the full CG function call building logic here because the 6960b57cec5SDimitry Andric // complex type has special ABI handling. We also should not forget about 6970b57cec5SDimitry Andric // special calling convention which may be used for compiler builtins. 6980b57cec5SDimitry Andric 6990b57cec5SDimitry Andric // We create a function qualified type to state that this call does not have 7000b57cec5SDimitry Andric // any exceptions. 7010b57cec5SDimitry Andric FunctionProtoType::ExtProtoInfo EPI; 7020b57cec5SDimitry Andric EPI = EPI.withExceptionSpec( 7030b57cec5SDimitry Andric FunctionProtoType::ExceptionSpecInfo(EST_BasicNoexcept)); 7040b57cec5SDimitry Andric SmallVector<QualType, 4> ArgsQTys( 7050b57cec5SDimitry Andric 4, Op.Ty->castAs<ComplexType>()->getElementType()); 7060b57cec5SDimitry Andric QualType FQTy = CGF.getContext().getFunctionType(Op.Ty, ArgsQTys, EPI); 7070b57cec5SDimitry Andric const CGFunctionInfo &FuncInfo = CGF.CGM.getTypes().arrangeFreeFunctionCall( 7080b57cec5SDimitry Andric Args, cast<FunctionType>(FQTy.getTypePtr()), false); 7090b57cec5SDimitry Andric 7100b57cec5SDimitry Andric llvm::FunctionType *FTy = CGF.CGM.getTypes().GetFunctionType(FuncInfo); 7110b57cec5SDimitry Andric llvm::FunctionCallee Func = CGF.CGM.CreateRuntimeFunction( 7120b57cec5SDimitry Andric FTy, LibCallName, llvm::AttributeList(), true); 7130b57cec5SDimitry Andric CGCallee Callee = CGCallee::forDirect(Func, FQTy->getAs<FunctionProtoType>()); 7140b57cec5SDimitry Andric 7150b57cec5SDimitry Andric llvm::CallBase *Call; 7160b57cec5SDimitry Andric RValue Res = CGF.EmitCall(FuncInfo, Callee, ReturnValueSlot(), Args, &Call); 7170b57cec5SDimitry Andric Call->setCallingConv(CGF.CGM.getRuntimeCC()); 7180b57cec5SDimitry Andric return Res.getComplexVal(); 7190b57cec5SDimitry Andric } 7200b57cec5SDimitry Andric 7210b57cec5SDimitry Andric /// Lookup the libcall name for a given floating point type complex 7220b57cec5SDimitry Andric /// multiply. 7230b57cec5SDimitry Andric static StringRef getComplexMultiplyLibCallName(llvm::Type *Ty) { 7240b57cec5SDimitry Andric switch (Ty->getTypeID()) { 7250b57cec5SDimitry Andric default: 7260b57cec5SDimitry Andric llvm_unreachable("Unsupported floating point type!"); 7270b57cec5SDimitry Andric case llvm::Type::HalfTyID: 7280b57cec5SDimitry Andric return "__mulhc3"; 7290b57cec5SDimitry Andric case llvm::Type::FloatTyID: 7300b57cec5SDimitry Andric return "__mulsc3"; 7310b57cec5SDimitry Andric case llvm::Type::DoubleTyID: 7320b57cec5SDimitry Andric return "__muldc3"; 7330b57cec5SDimitry Andric case llvm::Type::PPC_FP128TyID: 7340b57cec5SDimitry Andric return "__multc3"; 7350b57cec5SDimitry Andric case llvm::Type::X86_FP80TyID: 7360b57cec5SDimitry Andric return "__mulxc3"; 7370b57cec5SDimitry Andric case llvm::Type::FP128TyID: 7380b57cec5SDimitry Andric return "__multc3"; 7390b57cec5SDimitry Andric } 7400b57cec5SDimitry Andric } 7410b57cec5SDimitry Andric 7420b57cec5SDimitry Andric // See C11 Annex G.5.1 for the semantics of multiplicative operators on complex 7430b57cec5SDimitry Andric // typed values. 7440b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) { 7450b57cec5SDimitry Andric using llvm::Value; 7460b57cec5SDimitry Andric Value *ResR, *ResI; 7470b57cec5SDimitry Andric llvm::MDBuilder MDHelper(CGF.getLLVMContext()); 7480b57cec5SDimitry Andric 7490b57cec5SDimitry Andric if (Op.LHS.first->getType()->isFloatingPointTy()) { 7500b57cec5SDimitry Andric // The general formulation is: 7510b57cec5SDimitry Andric // (a + ib) * (c + id) = (a * c - b * d) + i(a * d + b * c) 7520b57cec5SDimitry Andric // 7530b57cec5SDimitry Andric // But we can fold away components which would be zero due to a real 7540b57cec5SDimitry Andric // operand according to C11 Annex G.5.1p2. 7550b57cec5SDimitry Andric // FIXME: C11 also provides for imaginary types which would allow folding 7560b57cec5SDimitry Andric // still more of this within the type system. 7570b57cec5SDimitry Andric 758bdd1243dSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures); 7590b57cec5SDimitry Andric if (Op.LHS.second && Op.RHS.second) { 7600b57cec5SDimitry Andric // If both operands are complex, emit the core math directly, and then 7610b57cec5SDimitry Andric // test for NaNs. If we find NaNs in the result, we delegate to a libcall 7620b57cec5SDimitry Andric // to carefully re-compute the correct infinity representation if 7630b57cec5SDimitry Andric // possible. The expectation is that the presence of NaNs here is 7640b57cec5SDimitry Andric // *extremely* rare, and so the cost of the libcall is almost irrelevant. 7650b57cec5SDimitry Andric // This is good, because the libcall re-computes the core multiplication 7660b57cec5SDimitry Andric // exactly the same as we do here and re-tests for NaNs in order to be 7670b57cec5SDimitry Andric // a generic complex*complex libcall. 7680b57cec5SDimitry Andric 7690b57cec5SDimitry Andric // First compute the four products. 7700b57cec5SDimitry Andric Value *AC = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul_ac"); 7710b57cec5SDimitry Andric Value *BD = Builder.CreateFMul(Op.LHS.second, Op.RHS.second, "mul_bd"); 7720b57cec5SDimitry Andric Value *AD = Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul_ad"); 7730b57cec5SDimitry Andric Value *BC = Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul_bc"); 7740b57cec5SDimitry Andric 7750b57cec5SDimitry Andric // The real part is the difference of the first two, the imaginary part is 7760b57cec5SDimitry Andric // the sum of the second. 7770b57cec5SDimitry Andric ResR = Builder.CreateFSub(AC, BD, "mul_r"); 7780b57cec5SDimitry Andric ResI = Builder.CreateFAdd(AD, BC, "mul_i"); 7790b57cec5SDimitry Andric 7800b57cec5SDimitry Andric // Emit the test for the real part becoming NaN and create a branch to 7810b57cec5SDimitry Andric // handle it. We test for NaN by comparing the number to itself. 7820b57cec5SDimitry Andric Value *IsRNaN = Builder.CreateFCmpUNO(ResR, ResR, "isnan_cmp"); 7830b57cec5SDimitry Andric llvm::BasicBlock *ContBB = CGF.createBasicBlock("complex_mul_cont"); 7840b57cec5SDimitry Andric llvm::BasicBlock *INaNBB = CGF.createBasicBlock("complex_mul_imag_nan"); 7850b57cec5SDimitry Andric llvm::Instruction *Branch = Builder.CreateCondBr(IsRNaN, INaNBB, ContBB); 7860b57cec5SDimitry Andric llvm::BasicBlock *OrigBB = Branch->getParent(); 7870b57cec5SDimitry Andric 7880b57cec5SDimitry Andric // Give hint that we very much don't expect to see NaNs. 7890b57cec5SDimitry Andric // Value chosen to match UR_NONTAKEN_WEIGHT, see BranchProbabilityInfo.cpp 7900b57cec5SDimitry Andric llvm::MDNode *BrWeight = MDHelper.createBranchWeights(1, (1U << 20) - 1); 7910b57cec5SDimitry Andric Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight); 7920b57cec5SDimitry Andric 7930b57cec5SDimitry Andric // Now test the imaginary part and create its branch. 7940b57cec5SDimitry Andric CGF.EmitBlock(INaNBB); 7950b57cec5SDimitry Andric Value *IsINaN = Builder.CreateFCmpUNO(ResI, ResI, "isnan_cmp"); 7960b57cec5SDimitry Andric llvm::BasicBlock *LibCallBB = CGF.createBasicBlock("complex_mul_libcall"); 7970b57cec5SDimitry Andric Branch = Builder.CreateCondBr(IsINaN, LibCallBB, ContBB); 7980b57cec5SDimitry Andric Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight); 7990b57cec5SDimitry Andric 8000b57cec5SDimitry Andric // Now emit the libcall on this slowest of the slow paths. 8010b57cec5SDimitry Andric CGF.EmitBlock(LibCallBB); 8020b57cec5SDimitry Andric Value *LibCallR, *LibCallI; 8030b57cec5SDimitry Andric std::tie(LibCallR, LibCallI) = EmitComplexBinOpLibCall( 8040b57cec5SDimitry Andric getComplexMultiplyLibCallName(Op.LHS.first->getType()), Op); 8050b57cec5SDimitry Andric Builder.CreateBr(ContBB); 8060b57cec5SDimitry Andric 8070b57cec5SDimitry Andric // Finally continue execution by phi-ing together the different 8080b57cec5SDimitry Andric // computation paths. 8090b57cec5SDimitry Andric CGF.EmitBlock(ContBB); 8100b57cec5SDimitry Andric llvm::PHINode *RealPHI = Builder.CreatePHI(ResR->getType(), 3, "real_mul_phi"); 8110b57cec5SDimitry Andric RealPHI->addIncoming(ResR, OrigBB); 8120b57cec5SDimitry Andric RealPHI->addIncoming(ResR, INaNBB); 8130b57cec5SDimitry Andric RealPHI->addIncoming(LibCallR, LibCallBB); 8140b57cec5SDimitry Andric llvm::PHINode *ImagPHI = Builder.CreatePHI(ResI->getType(), 3, "imag_mul_phi"); 8150b57cec5SDimitry Andric ImagPHI->addIncoming(ResI, OrigBB); 8160b57cec5SDimitry Andric ImagPHI->addIncoming(ResI, INaNBB); 8170b57cec5SDimitry Andric ImagPHI->addIncoming(LibCallI, LibCallBB); 8180b57cec5SDimitry Andric return ComplexPairTy(RealPHI, ImagPHI); 8190b57cec5SDimitry Andric } 8200b57cec5SDimitry Andric assert((Op.LHS.second || Op.RHS.second) && 8210b57cec5SDimitry Andric "At least one operand must be complex!"); 8220b57cec5SDimitry Andric 8230b57cec5SDimitry Andric // If either of the operands is a real rather than a complex, the 8240b57cec5SDimitry Andric // imaginary component is ignored when computing the real component of the 8250b57cec5SDimitry Andric // result. 8260b57cec5SDimitry Andric ResR = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul.rl"); 8270b57cec5SDimitry Andric 8280b57cec5SDimitry Andric ResI = Op.LHS.second 8290b57cec5SDimitry Andric ? Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul.il") 8300b57cec5SDimitry Andric : Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul.ir"); 8310b57cec5SDimitry Andric } else { 8320b57cec5SDimitry Andric assert(Op.LHS.second && Op.RHS.second && 8330b57cec5SDimitry Andric "Both operands of integer complex operators must be complex!"); 8340b57cec5SDimitry Andric Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first, "mul.rl"); 8350b57cec5SDimitry Andric Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second, "mul.rr"); 8360b57cec5SDimitry Andric ResR = Builder.CreateSub(ResRl, ResRr, "mul.r"); 8370b57cec5SDimitry Andric 8380b57cec5SDimitry Andric Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first, "mul.il"); 8390b57cec5SDimitry Andric Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second, "mul.ir"); 8400b57cec5SDimitry Andric ResI = Builder.CreateAdd(ResIl, ResIr, "mul.i"); 8410b57cec5SDimitry Andric } 8420b57cec5SDimitry Andric return ComplexPairTy(ResR, ResI); 8430b57cec5SDimitry Andric } 8440b57cec5SDimitry Andric 8450b57cec5SDimitry Andric // See C11 Annex G.5.1 for the semantics of multiplicative operators on complex 8460b57cec5SDimitry Andric // typed values. 8470b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { 8480b57cec5SDimitry Andric llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second; 8490b57cec5SDimitry Andric llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second; 8500b57cec5SDimitry Andric 8510b57cec5SDimitry Andric llvm::Value *DSTr, *DSTi; 8520b57cec5SDimitry Andric if (LHSr->getType()->isFloatingPointTy()) { 8530b57cec5SDimitry Andric // If we have a complex operand on the RHS and FastMath is not allowed, we 8540b57cec5SDimitry Andric // delegate to a libcall to handle all of the complexities and minimize 8550b57cec5SDimitry Andric // underflow/overflow cases. When FastMath is allowed we construct the 8560b57cec5SDimitry Andric // divide inline using the same algorithm as for integer operands. 8570b57cec5SDimitry Andric // 8580b57cec5SDimitry Andric // FIXME: We would be able to avoid the libcall in many places if we 8590b57cec5SDimitry Andric // supported imaginary types in addition to complex types. 860bdd1243dSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures); 8610b57cec5SDimitry Andric if (RHSi && !CGF.getLangOpts().FastMath) { 8620b57cec5SDimitry Andric BinOpInfo LibCallOp = Op; 8630b57cec5SDimitry Andric // If LHS was a real, supply a null imaginary part. 8640b57cec5SDimitry Andric if (!LHSi) 8650b57cec5SDimitry Andric LibCallOp.LHS.second = llvm::Constant::getNullValue(LHSr->getType()); 8660b57cec5SDimitry Andric 8670b57cec5SDimitry Andric switch (LHSr->getType()->getTypeID()) { 8680b57cec5SDimitry Andric default: 8690b57cec5SDimitry Andric llvm_unreachable("Unsupported floating point type!"); 8700b57cec5SDimitry Andric case llvm::Type::HalfTyID: 8710b57cec5SDimitry Andric return EmitComplexBinOpLibCall("__divhc3", LibCallOp); 8720b57cec5SDimitry Andric case llvm::Type::FloatTyID: 8730b57cec5SDimitry Andric return EmitComplexBinOpLibCall("__divsc3", LibCallOp); 8740b57cec5SDimitry Andric case llvm::Type::DoubleTyID: 8750b57cec5SDimitry Andric return EmitComplexBinOpLibCall("__divdc3", LibCallOp); 8760b57cec5SDimitry Andric case llvm::Type::PPC_FP128TyID: 8770b57cec5SDimitry Andric return EmitComplexBinOpLibCall("__divtc3", LibCallOp); 8780b57cec5SDimitry Andric case llvm::Type::X86_FP80TyID: 8790b57cec5SDimitry Andric return EmitComplexBinOpLibCall("__divxc3", LibCallOp); 8800b57cec5SDimitry Andric case llvm::Type::FP128TyID: 8810b57cec5SDimitry Andric return EmitComplexBinOpLibCall("__divtc3", LibCallOp); 8820b57cec5SDimitry Andric } 8830b57cec5SDimitry Andric } else if (RHSi) { 8840b57cec5SDimitry Andric if (!LHSi) 8850b57cec5SDimitry Andric LHSi = llvm::Constant::getNullValue(RHSi->getType()); 8860b57cec5SDimitry Andric 8870b57cec5SDimitry Andric // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) 8880b57cec5SDimitry Andric llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr); // a*c 8890b57cec5SDimitry Andric llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi); // b*d 8900b57cec5SDimitry Andric llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD); // ac+bd 8910b57cec5SDimitry Andric 8920b57cec5SDimitry Andric llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr); // c*c 8930b57cec5SDimitry Andric llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi); // d*d 8940b57cec5SDimitry Andric llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD); // cc+dd 8950b57cec5SDimitry Andric 8960b57cec5SDimitry Andric llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr); // b*c 8970b57cec5SDimitry Andric llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi); // a*d 8980b57cec5SDimitry Andric llvm::Value *BCmAD = Builder.CreateFSub(BC, AD); // bc-ad 8990b57cec5SDimitry Andric 9000b57cec5SDimitry Andric DSTr = Builder.CreateFDiv(ACpBD, CCpDD); 9010b57cec5SDimitry Andric DSTi = Builder.CreateFDiv(BCmAD, CCpDD); 9020b57cec5SDimitry Andric } else { 9030b57cec5SDimitry Andric assert(LHSi && "Can have at most one non-complex operand!"); 9040b57cec5SDimitry Andric 9050b57cec5SDimitry Andric DSTr = Builder.CreateFDiv(LHSr, RHSr); 9060b57cec5SDimitry Andric DSTi = Builder.CreateFDiv(LHSi, RHSr); 9070b57cec5SDimitry Andric } 9080b57cec5SDimitry Andric } else { 9090b57cec5SDimitry Andric assert(Op.LHS.second && Op.RHS.second && 9100b57cec5SDimitry Andric "Both operands of integer complex operators must be complex!"); 9110b57cec5SDimitry Andric // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) 9120b57cec5SDimitry Andric llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr); // a*c 9130b57cec5SDimitry Andric llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi); // b*d 9140b57cec5SDimitry Andric llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2); // ac+bd 9150b57cec5SDimitry Andric 9160b57cec5SDimitry Andric llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr); // c*c 9170b57cec5SDimitry Andric llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi); // d*d 9180b57cec5SDimitry Andric llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5); // cc+dd 9190b57cec5SDimitry Andric 9200b57cec5SDimitry Andric llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr); // b*c 9210b57cec5SDimitry Andric llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi); // a*d 9220b57cec5SDimitry Andric llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8); // bc-ad 9230b57cec5SDimitry Andric 9240b57cec5SDimitry Andric if (Op.Ty->castAs<ComplexType>()->getElementType()->isUnsignedIntegerType()) { 9250b57cec5SDimitry Andric DSTr = Builder.CreateUDiv(Tmp3, Tmp6); 9260b57cec5SDimitry Andric DSTi = Builder.CreateUDiv(Tmp9, Tmp6); 9270b57cec5SDimitry Andric } else { 9280b57cec5SDimitry Andric DSTr = Builder.CreateSDiv(Tmp3, Tmp6); 9290b57cec5SDimitry Andric DSTi = Builder.CreateSDiv(Tmp9, Tmp6); 9300b57cec5SDimitry Andric } 9310b57cec5SDimitry Andric } 9320b57cec5SDimitry Andric 9330b57cec5SDimitry Andric return ComplexPairTy(DSTr, DSTi); 9340b57cec5SDimitry Andric } 9350b57cec5SDimitry Andric 936bdd1243dSDimitry Andric ComplexPairTy CodeGenFunction::EmitUnPromotedValue(ComplexPairTy result, 937bdd1243dSDimitry Andric QualType UnPromotionType) { 938bdd1243dSDimitry Andric llvm::Type *ComplexElementTy = 939bdd1243dSDimitry Andric ConvertType(UnPromotionType->castAs<ComplexType>()->getElementType()); 940bdd1243dSDimitry Andric if (result.first) 941bdd1243dSDimitry Andric result.first = 942bdd1243dSDimitry Andric Builder.CreateFPTrunc(result.first, ComplexElementTy, "unpromotion"); 943bdd1243dSDimitry Andric if (result.second) 944bdd1243dSDimitry Andric result.second = 945bdd1243dSDimitry Andric Builder.CreateFPTrunc(result.second, ComplexElementTy, "unpromotion"); 946bdd1243dSDimitry Andric return result; 947bdd1243dSDimitry Andric } 948bdd1243dSDimitry Andric 949bdd1243dSDimitry Andric ComplexPairTy CodeGenFunction::EmitPromotedValue(ComplexPairTy result, 950bdd1243dSDimitry Andric QualType PromotionType) { 951bdd1243dSDimitry Andric llvm::Type *ComplexElementTy = 952bdd1243dSDimitry Andric ConvertType(PromotionType->castAs<ComplexType>()->getElementType()); 953bdd1243dSDimitry Andric if (result.first) 954bdd1243dSDimitry Andric result.first = Builder.CreateFPExt(result.first, ComplexElementTy, "ext"); 955bdd1243dSDimitry Andric if (result.second) 956bdd1243dSDimitry Andric result.second = Builder.CreateFPExt(result.second, ComplexElementTy, "ext"); 957bdd1243dSDimitry Andric 958bdd1243dSDimitry Andric return result; 959bdd1243dSDimitry Andric } 960bdd1243dSDimitry Andric 961bdd1243dSDimitry Andric ComplexPairTy ComplexExprEmitter::EmitPromoted(const Expr *E, 962bdd1243dSDimitry Andric QualType PromotionType) { 963bdd1243dSDimitry Andric E = E->IgnoreParens(); 964bdd1243dSDimitry Andric if (auto BO = dyn_cast<BinaryOperator>(E)) { 965bdd1243dSDimitry Andric switch (BO->getOpcode()) { 966bdd1243dSDimitry Andric #define HANDLE_BINOP(OP) \ 967bdd1243dSDimitry Andric case BO_##OP: \ 968bdd1243dSDimitry Andric return EmitBin##OP(EmitBinOps(BO, PromotionType)); 969bdd1243dSDimitry Andric HANDLE_BINOP(Add) 970bdd1243dSDimitry Andric HANDLE_BINOP(Sub) 971bdd1243dSDimitry Andric HANDLE_BINOP(Mul) 972bdd1243dSDimitry Andric HANDLE_BINOP(Div) 973bdd1243dSDimitry Andric #undef HANDLE_BINOP 974bdd1243dSDimitry Andric default: 975bdd1243dSDimitry Andric break; 976bdd1243dSDimitry Andric } 977bdd1243dSDimitry Andric } else if (auto UO = dyn_cast<UnaryOperator>(E)) { 978bdd1243dSDimitry Andric switch (UO->getOpcode()) { 979bdd1243dSDimitry Andric case UO_Minus: 980bdd1243dSDimitry Andric return VisitMinus(UO, PromotionType); 981bdd1243dSDimitry Andric case UO_Plus: 982bdd1243dSDimitry Andric return VisitPlus(UO, PromotionType); 983bdd1243dSDimitry Andric default: 984bdd1243dSDimitry Andric break; 985bdd1243dSDimitry Andric } 986bdd1243dSDimitry Andric } 987bdd1243dSDimitry Andric auto result = Visit(const_cast<Expr *>(E)); 988bdd1243dSDimitry Andric if (!PromotionType.isNull()) 989bdd1243dSDimitry Andric return CGF.EmitPromotedValue(result, PromotionType); 990bdd1243dSDimitry Andric else 991bdd1243dSDimitry Andric return result; 992bdd1243dSDimitry Andric } 993bdd1243dSDimitry Andric 994bdd1243dSDimitry Andric ComplexPairTy CodeGenFunction::EmitPromotedComplexExpr(const Expr *E, 995bdd1243dSDimitry Andric QualType DstTy) { 996bdd1243dSDimitry Andric return ComplexExprEmitter(*this).EmitPromoted(E, DstTy); 997bdd1243dSDimitry Andric } 998bdd1243dSDimitry Andric 999bdd1243dSDimitry Andric ComplexPairTy 1000bdd1243dSDimitry Andric ComplexExprEmitter::EmitPromotedComplexOperand(const Expr *E, 1001bdd1243dSDimitry Andric QualType OverallPromotionType) { 1002bdd1243dSDimitry Andric if (E->getType()->isAnyComplexType()) { 1003bdd1243dSDimitry Andric if (!OverallPromotionType.isNull()) 1004bdd1243dSDimitry Andric return CGF.EmitPromotedComplexExpr(E, OverallPromotionType); 1005bdd1243dSDimitry Andric else 1006bdd1243dSDimitry Andric return Visit(const_cast<Expr *>(E)); 1007bdd1243dSDimitry Andric } else { 1008bdd1243dSDimitry Andric if (!OverallPromotionType.isNull()) { 1009bdd1243dSDimitry Andric QualType ComplexElementTy = 1010bdd1243dSDimitry Andric OverallPromotionType->castAs<ComplexType>()->getElementType(); 1011bdd1243dSDimitry Andric return ComplexPairTy(CGF.EmitPromotedScalarExpr(E, ComplexElementTy), 1012bdd1243dSDimitry Andric nullptr); 1013bdd1243dSDimitry Andric } else { 1014bdd1243dSDimitry Andric return ComplexPairTy(CGF.EmitScalarExpr(E), nullptr); 1015bdd1243dSDimitry Andric } 1016bdd1243dSDimitry Andric } 1017bdd1243dSDimitry Andric } 1018bdd1243dSDimitry Andric 10190b57cec5SDimitry Andric ComplexExprEmitter::BinOpInfo 1020bdd1243dSDimitry Andric ComplexExprEmitter::EmitBinOps(const BinaryOperator *E, 1021bdd1243dSDimitry Andric QualType PromotionType) { 10220b57cec5SDimitry Andric TestAndClearIgnoreReal(); 10230b57cec5SDimitry Andric TestAndClearIgnoreImag(); 10240b57cec5SDimitry Andric BinOpInfo Ops; 10250b57cec5SDimitry Andric 1026bdd1243dSDimitry Andric Ops.LHS = EmitPromotedComplexOperand(E->getLHS(), PromotionType); 1027bdd1243dSDimitry Andric Ops.RHS = EmitPromotedComplexOperand(E->getRHS(), PromotionType); 1028bdd1243dSDimitry Andric if (!PromotionType.isNull()) 1029bdd1243dSDimitry Andric Ops.Ty = PromotionType; 1030bdd1243dSDimitry Andric else 10310b57cec5SDimitry Andric Ops.Ty = E->getType(); 1032bdd1243dSDimitry Andric Ops.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts()); 10330b57cec5SDimitry Andric return Ops; 10340b57cec5SDimitry Andric } 10350b57cec5SDimitry Andric 10360b57cec5SDimitry Andric 10370b57cec5SDimitry Andric LValue ComplexExprEmitter:: 10380b57cec5SDimitry Andric EmitCompoundAssignLValue(const CompoundAssignOperator *E, 10390b57cec5SDimitry Andric ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&), 10400b57cec5SDimitry Andric RValue &Val) { 10410b57cec5SDimitry Andric TestAndClearIgnoreReal(); 10420b57cec5SDimitry Andric TestAndClearIgnoreImag(); 10430b57cec5SDimitry Andric QualType LHSTy = E->getLHS()->getType(); 10440b57cec5SDimitry Andric if (const AtomicType *AT = LHSTy->getAs<AtomicType>()) 10450b57cec5SDimitry Andric LHSTy = AT->getValueType(); 10460b57cec5SDimitry Andric 10470b57cec5SDimitry Andric BinOpInfo OpInfo; 1048bdd1243dSDimitry Andric OpInfo.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts()); 1049bdd1243dSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures); 10500b57cec5SDimitry Andric 10510b57cec5SDimitry Andric // Load the RHS and LHS operands. 10520b57cec5SDimitry Andric // __block variables need to have the rhs evaluated first, plus this should 10530b57cec5SDimitry Andric // improve codegen a little. 1054bdd1243dSDimitry Andric QualType PromotionTypeCR; 1055bdd1243dSDimitry Andric PromotionTypeCR = getPromotionType(E->getComputationResultType()); 1056bdd1243dSDimitry Andric if (PromotionTypeCR.isNull()) 1057bdd1243dSDimitry Andric PromotionTypeCR = E->getComputationResultType(); 1058bdd1243dSDimitry Andric OpInfo.Ty = PromotionTypeCR; 1059bdd1243dSDimitry Andric QualType ComplexElementTy = 1060bdd1243dSDimitry Andric OpInfo.Ty->castAs<ComplexType>()->getElementType(); 1061bdd1243dSDimitry Andric QualType PromotionTypeRHS = getPromotionType(E->getRHS()->getType()); 10620b57cec5SDimitry Andric 10630b57cec5SDimitry Andric // The RHS should have been converted to the computation type. 10640b57cec5SDimitry Andric if (E->getRHS()->getType()->isRealFloatingType()) { 1065bdd1243dSDimitry Andric if (!PromotionTypeRHS.isNull()) 1066bdd1243dSDimitry Andric OpInfo.RHS = ComplexPairTy( 1067bdd1243dSDimitry Andric CGF.EmitPromotedScalarExpr(E->getRHS(), PromotionTypeRHS), nullptr); 1068bdd1243dSDimitry Andric else { 1069bdd1243dSDimitry Andric assert(CGF.getContext().hasSameUnqualifiedType(ComplexElementTy, 1070bdd1243dSDimitry Andric E->getRHS()->getType())); 1071bdd1243dSDimitry Andric 10720b57cec5SDimitry Andric OpInfo.RHS = ComplexPairTy(CGF.EmitScalarExpr(E->getRHS()), nullptr); 1073bdd1243dSDimitry Andric } 10740b57cec5SDimitry Andric } else { 1075bdd1243dSDimitry Andric if (!PromotionTypeRHS.isNull()) { 1076bdd1243dSDimitry Andric OpInfo.RHS = ComplexPairTy( 1077bdd1243dSDimitry Andric CGF.EmitPromotedComplexExpr(E->getRHS(), PromotionTypeRHS)); 1078bdd1243dSDimitry Andric } else { 1079bdd1243dSDimitry Andric assert(CGF.getContext().hasSameUnqualifiedType(OpInfo.Ty, 1080bdd1243dSDimitry Andric E->getRHS()->getType())); 10810b57cec5SDimitry Andric OpInfo.RHS = Visit(E->getRHS()); 10820b57cec5SDimitry Andric } 1083bdd1243dSDimitry Andric } 10840b57cec5SDimitry Andric 10850b57cec5SDimitry Andric LValue LHS = CGF.EmitLValue(E->getLHS()); 10860b57cec5SDimitry Andric 10870b57cec5SDimitry Andric // Load from the l-value and convert it. 10880b57cec5SDimitry Andric SourceLocation Loc = E->getExprLoc(); 1089bdd1243dSDimitry Andric QualType PromotionTypeLHS = getPromotionType(E->getComputationLHSType()); 10900b57cec5SDimitry Andric if (LHSTy->isAnyComplexType()) { 10910b57cec5SDimitry Andric ComplexPairTy LHSVal = EmitLoadOfLValue(LHS, Loc); 1092bdd1243dSDimitry Andric if (!PromotionTypeLHS.isNull()) 1093bdd1243dSDimitry Andric OpInfo.LHS = 1094bdd1243dSDimitry Andric EmitComplexToComplexCast(LHSVal, LHSTy, PromotionTypeLHS, Loc); 1095bdd1243dSDimitry Andric else 10960b57cec5SDimitry Andric OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc); 10970b57cec5SDimitry Andric } else { 10980b57cec5SDimitry Andric llvm::Value *LHSVal = CGF.EmitLoadOfScalar(LHS, Loc); 10990b57cec5SDimitry Andric // For floating point real operands we can directly pass the scalar form 11000b57cec5SDimitry Andric // to the binary operator emission and potentially get more efficient code. 11010b57cec5SDimitry Andric if (LHSTy->isRealFloatingType()) { 1102bdd1243dSDimitry Andric QualType PromotedComplexElementTy; 1103bdd1243dSDimitry Andric if (!PromotionTypeLHS.isNull()) { 1104bdd1243dSDimitry Andric PromotedComplexElementTy = 1105bdd1243dSDimitry Andric cast<ComplexType>(PromotionTypeLHS)->getElementType(); 1106bdd1243dSDimitry Andric if (!CGF.getContext().hasSameUnqualifiedType(PromotedComplexElementTy, 1107bdd1243dSDimitry Andric PromotionTypeLHS)) 1108bdd1243dSDimitry Andric LHSVal = CGF.EmitScalarConversion(LHSVal, LHSTy, 1109bdd1243dSDimitry Andric PromotedComplexElementTy, Loc); 1110bdd1243dSDimitry Andric } else { 11110b57cec5SDimitry Andric if (!CGF.getContext().hasSameUnqualifiedType(ComplexElementTy, LHSTy)) 1112bdd1243dSDimitry Andric LHSVal = 1113bdd1243dSDimitry Andric CGF.EmitScalarConversion(LHSVal, LHSTy, ComplexElementTy, Loc); 1114bdd1243dSDimitry Andric } 11150b57cec5SDimitry Andric OpInfo.LHS = ComplexPairTy(LHSVal, nullptr); 11160b57cec5SDimitry Andric } else { 11170b57cec5SDimitry Andric OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc); 11180b57cec5SDimitry Andric } 11190b57cec5SDimitry Andric } 11200b57cec5SDimitry Andric 11210b57cec5SDimitry Andric // Expand the binary operator. 11220b57cec5SDimitry Andric ComplexPairTy Result = (this->*Func)(OpInfo); 11230b57cec5SDimitry Andric 11240b57cec5SDimitry Andric // Truncate the result and store it into the LHS lvalue. 11250b57cec5SDimitry Andric if (LHSTy->isAnyComplexType()) { 11260b57cec5SDimitry Andric ComplexPairTy ResVal = 11270b57cec5SDimitry Andric EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy, Loc); 11280b57cec5SDimitry Andric EmitStoreOfComplex(ResVal, LHS, /*isInit*/ false); 11290b57cec5SDimitry Andric Val = RValue::getComplex(ResVal); 11300b57cec5SDimitry Andric } else { 11310b57cec5SDimitry Andric llvm::Value *ResVal = 11320b57cec5SDimitry Andric CGF.EmitComplexToScalarConversion(Result, OpInfo.Ty, LHSTy, Loc); 11330b57cec5SDimitry Andric CGF.EmitStoreOfScalar(ResVal, LHS, /*isInit*/ false); 11340b57cec5SDimitry Andric Val = RValue::get(ResVal); 11350b57cec5SDimitry Andric } 11360b57cec5SDimitry Andric 11370b57cec5SDimitry Andric return LHS; 11380b57cec5SDimitry Andric } 11390b57cec5SDimitry Andric 11400b57cec5SDimitry Andric // Compound assignments. 11410b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter:: 11420b57cec5SDimitry Andric EmitCompoundAssign(const CompoundAssignOperator *E, 11430b57cec5SDimitry Andric ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){ 11440b57cec5SDimitry Andric RValue Val; 11450b57cec5SDimitry Andric LValue LV = EmitCompoundAssignLValue(E, Func, Val); 11460b57cec5SDimitry Andric 11470b57cec5SDimitry Andric // The result of an assignment in C is the assigned r-value. 11480b57cec5SDimitry Andric if (!CGF.getLangOpts().CPlusPlus) 11490b57cec5SDimitry Andric return Val.getComplexVal(); 11500b57cec5SDimitry Andric 11510b57cec5SDimitry Andric // If the lvalue is non-volatile, return the computed value of the assignment. 11520b57cec5SDimitry Andric if (!LV.isVolatileQualified()) 11530b57cec5SDimitry Andric return Val.getComplexVal(); 11540b57cec5SDimitry Andric 11550b57cec5SDimitry Andric return EmitLoadOfLValue(LV, E->getExprLoc()); 11560b57cec5SDimitry Andric } 11570b57cec5SDimitry Andric 11580b57cec5SDimitry Andric LValue ComplexExprEmitter::EmitBinAssignLValue(const BinaryOperator *E, 11590b57cec5SDimitry Andric ComplexPairTy &Val) { 11600b57cec5SDimitry Andric assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(), 11610b57cec5SDimitry Andric E->getRHS()->getType()) && 11620b57cec5SDimitry Andric "Invalid assignment"); 11630b57cec5SDimitry Andric TestAndClearIgnoreReal(); 11640b57cec5SDimitry Andric TestAndClearIgnoreImag(); 11650b57cec5SDimitry Andric 11660b57cec5SDimitry Andric // Emit the RHS. __block variables need the RHS evaluated first. 11670b57cec5SDimitry Andric Val = Visit(E->getRHS()); 11680b57cec5SDimitry Andric 11690b57cec5SDimitry Andric // Compute the address to store into. 11700b57cec5SDimitry Andric LValue LHS = CGF.EmitLValue(E->getLHS()); 11710b57cec5SDimitry Andric 11720b57cec5SDimitry Andric // Store the result value into the LHS lvalue. 11730b57cec5SDimitry Andric EmitStoreOfComplex(Val, LHS, /*isInit*/ false); 11740b57cec5SDimitry Andric 11750b57cec5SDimitry Andric return LHS; 11760b57cec5SDimitry Andric } 11770b57cec5SDimitry Andric 11780b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) { 11790b57cec5SDimitry Andric ComplexPairTy Val; 11800b57cec5SDimitry Andric LValue LV = EmitBinAssignLValue(E, Val); 11810b57cec5SDimitry Andric 11820b57cec5SDimitry Andric // The result of an assignment in C is the assigned r-value. 11830b57cec5SDimitry Andric if (!CGF.getLangOpts().CPlusPlus) 11840b57cec5SDimitry Andric return Val; 11850b57cec5SDimitry Andric 11860b57cec5SDimitry Andric // If the lvalue is non-volatile, return the computed value of the assignment. 11870b57cec5SDimitry Andric if (!LV.isVolatileQualified()) 11880b57cec5SDimitry Andric return Val; 11890b57cec5SDimitry Andric 11900b57cec5SDimitry Andric return EmitLoadOfLValue(LV, E->getExprLoc()); 11910b57cec5SDimitry Andric } 11920b57cec5SDimitry Andric 11930b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) { 11940b57cec5SDimitry Andric CGF.EmitIgnoredExpr(E->getLHS()); 11950b57cec5SDimitry Andric return Visit(E->getRHS()); 11960b57cec5SDimitry Andric } 11970b57cec5SDimitry Andric 11980b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter:: 11990b57cec5SDimitry Andric VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { 12000b57cec5SDimitry Andric TestAndClearIgnoreReal(); 12010b57cec5SDimitry Andric TestAndClearIgnoreImag(); 12020b57cec5SDimitry Andric llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true"); 12030b57cec5SDimitry Andric llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false"); 12040b57cec5SDimitry Andric llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end"); 12050b57cec5SDimitry Andric 12060b57cec5SDimitry Andric // Bind the common expression if necessary. 12070b57cec5SDimitry Andric CodeGenFunction::OpaqueValueMapping binding(CGF, E); 12080b57cec5SDimitry Andric 12090b57cec5SDimitry Andric 12100b57cec5SDimitry Andric CodeGenFunction::ConditionalEvaluation eval(CGF); 12110b57cec5SDimitry Andric CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock, 12120b57cec5SDimitry Andric CGF.getProfileCount(E)); 12130b57cec5SDimitry Andric 12140b57cec5SDimitry Andric eval.begin(CGF); 12150b57cec5SDimitry Andric CGF.EmitBlock(LHSBlock); 12160b57cec5SDimitry Andric CGF.incrementProfileCounter(E); 12170b57cec5SDimitry Andric ComplexPairTy LHS = Visit(E->getTrueExpr()); 12180b57cec5SDimitry Andric LHSBlock = Builder.GetInsertBlock(); 12190b57cec5SDimitry Andric CGF.EmitBranch(ContBlock); 12200b57cec5SDimitry Andric eval.end(CGF); 12210b57cec5SDimitry Andric 12220b57cec5SDimitry Andric eval.begin(CGF); 12230b57cec5SDimitry Andric CGF.EmitBlock(RHSBlock); 12240b57cec5SDimitry Andric ComplexPairTy RHS = Visit(E->getFalseExpr()); 12250b57cec5SDimitry Andric RHSBlock = Builder.GetInsertBlock(); 12260b57cec5SDimitry Andric CGF.EmitBlock(ContBlock); 12270b57cec5SDimitry Andric eval.end(CGF); 12280b57cec5SDimitry Andric 12290b57cec5SDimitry Andric // Create a PHI node for the real part. 12300b57cec5SDimitry Andric llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), 2, "cond.r"); 12310b57cec5SDimitry Andric RealPN->addIncoming(LHS.first, LHSBlock); 12320b57cec5SDimitry Andric RealPN->addIncoming(RHS.first, RHSBlock); 12330b57cec5SDimitry Andric 12340b57cec5SDimitry Andric // Create a PHI node for the imaginary part. 12350b57cec5SDimitry Andric llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), 2, "cond.i"); 12360b57cec5SDimitry Andric ImagPN->addIncoming(LHS.second, LHSBlock); 12370b57cec5SDimitry Andric ImagPN->addIncoming(RHS.second, RHSBlock); 12380b57cec5SDimitry Andric 12390b57cec5SDimitry Andric return ComplexPairTy(RealPN, ImagPN); 12400b57cec5SDimitry Andric } 12410b57cec5SDimitry Andric 12420b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) { 12430b57cec5SDimitry Andric return Visit(E->getChosenSubExpr()); 12440b57cec5SDimitry Andric } 12450b57cec5SDimitry Andric 12460b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) { 12470b57cec5SDimitry Andric bool Ignore = TestAndClearIgnoreReal(); 12480b57cec5SDimitry Andric (void)Ignore; 12490b57cec5SDimitry Andric assert (Ignore == false && "init list ignored"); 12500b57cec5SDimitry Andric Ignore = TestAndClearIgnoreImag(); 12510b57cec5SDimitry Andric (void)Ignore; 12520b57cec5SDimitry Andric assert (Ignore == false && "init list ignored"); 12530b57cec5SDimitry Andric 12540b57cec5SDimitry Andric if (E->getNumInits() == 2) { 12550b57cec5SDimitry Andric llvm::Value *Real = CGF.EmitScalarExpr(E->getInit(0)); 12560b57cec5SDimitry Andric llvm::Value *Imag = CGF.EmitScalarExpr(E->getInit(1)); 12570b57cec5SDimitry Andric return ComplexPairTy(Real, Imag); 12580b57cec5SDimitry Andric } else if (E->getNumInits() == 1) { 12590b57cec5SDimitry Andric return Visit(E->getInit(0)); 12600b57cec5SDimitry Andric } 12610b57cec5SDimitry Andric 12620b57cec5SDimitry Andric // Empty init list initializes to null 12630b57cec5SDimitry Andric assert(E->getNumInits() == 0 && "Unexpected number of inits"); 12640b57cec5SDimitry Andric QualType Ty = E->getType()->castAs<ComplexType>()->getElementType(); 12650b57cec5SDimitry Andric llvm::Type* LTy = CGF.ConvertType(Ty); 12660b57cec5SDimitry Andric llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy); 12670b57cec5SDimitry Andric return ComplexPairTy(zeroConstant, zeroConstant); 12680b57cec5SDimitry Andric } 12690b57cec5SDimitry Andric 12700b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) { 12710b57cec5SDimitry Andric Address ArgValue = Address::invalid(); 12720b57cec5SDimitry Andric Address ArgPtr = CGF.EmitVAArg(E, ArgValue); 12730b57cec5SDimitry Andric 12740b57cec5SDimitry Andric if (!ArgPtr.isValid()) { 12750b57cec5SDimitry Andric CGF.ErrorUnsupported(E, "complex va_arg expression"); 12760b57cec5SDimitry Andric llvm::Type *EltTy = 12770b57cec5SDimitry Andric CGF.ConvertType(E->getType()->castAs<ComplexType>()->getElementType()); 12780b57cec5SDimitry Andric llvm::Value *U = llvm::UndefValue::get(EltTy); 12790b57cec5SDimitry Andric return ComplexPairTy(U, U); 12800b57cec5SDimitry Andric } 12810b57cec5SDimitry Andric 12820b57cec5SDimitry Andric return EmitLoadOfLValue(CGF.MakeAddrLValue(ArgPtr, E->getType()), 12830b57cec5SDimitry Andric E->getExprLoc()); 12840b57cec5SDimitry Andric } 12850b57cec5SDimitry Andric 12860b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12870b57cec5SDimitry Andric // Entry Point into this File 12880b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12890b57cec5SDimitry Andric 12900b57cec5SDimitry Andric /// EmitComplexExpr - Emit the computation of the specified expression of 12910b57cec5SDimitry Andric /// complex type, ignoring the result. 12920b57cec5SDimitry Andric ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E, bool IgnoreReal, 12930b57cec5SDimitry Andric bool IgnoreImag) { 12940b57cec5SDimitry Andric assert(E && getComplexType(E->getType()) && 12950b57cec5SDimitry Andric "Invalid complex expression to emit"); 12960b57cec5SDimitry Andric 12970b57cec5SDimitry Andric return ComplexExprEmitter(*this, IgnoreReal, IgnoreImag) 12980b57cec5SDimitry Andric .Visit(const_cast<Expr *>(E)); 12990b57cec5SDimitry Andric } 13000b57cec5SDimitry Andric 13010b57cec5SDimitry Andric void CodeGenFunction::EmitComplexExprIntoLValue(const Expr *E, LValue dest, 13020b57cec5SDimitry Andric bool isInit) { 13030b57cec5SDimitry Andric assert(E && getComplexType(E->getType()) && 13040b57cec5SDimitry Andric "Invalid complex expression to emit"); 13050b57cec5SDimitry Andric ComplexExprEmitter Emitter(*this); 13060b57cec5SDimitry Andric ComplexPairTy Val = Emitter.Visit(const_cast<Expr*>(E)); 13070b57cec5SDimitry Andric Emitter.EmitStoreOfComplex(Val, dest, isInit); 13080b57cec5SDimitry Andric } 13090b57cec5SDimitry Andric 13100b57cec5SDimitry Andric /// EmitStoreOfComplex - Store a complex number into the specified l-value. 13110b57cec5SDimitry Andric void CodeGenFunction::EmitStoreOfComplex(ComplexPairTy V, LValue dest, 13120b57cec5SDimitry Andric bool isInit) { 13130b57cec5SDimitry Andric ComplexExprEmitter(*this).EmitStoreOfComplex(V, dest, isInit); 13140b57cec5SDimitry Andric } 13150b57cec5SDimitry Andric 13160b57cec5SDimitry Andric /// EmitLoadOfComplex - Load a complex number from the specified address. 13170b57cec5SDimitry Andric ComplexPairTy CodeGenFunction::EmitLoadOfComplex(LValue src, 13180b57cec5SDimitry Andric SourceLocation loc) { 13190b57cec5SDimitry Andric return ComplexExprEmitter(*this).EmitLoadOfLValue(src, loc); 13200b57cec5SDimitry Andric } 13210b57cec5SDimitry Andric 13220b57cec5SDimitry Andric LValue CodeGenFunction::EmitComplexAssignmentLValue(const BinaryOperator *E) { 13230b57cec5SDimitry Andric assert(E->getOpcode() == BO_Assign); 13240b57cec5SDimitry Andric ComplexPairTy Val; // ignored 1325480093f4SDimitry Andric LValue LVal = ComplexExprEmitter(*this).EmitBinAssignLValue(E, Val); 1326480093f4SDimitry Andric if (getLangOpts().OpenMP) 1327480093f4SDimitry Andric CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(*this, 1328480093f4SDimitry Andric E->getLHS()); 1329480093f4SDimitry Andric return LVal; 13300b57cec5SDimitry Andric } 13310b57cec5SDimitry Andric 13320b57cec5SDimitry Andric typedef ComplexPairTy (ComplexExprEmitter::*CompoundFunc)( 13330b57cec5SDimitry Andric const ComplexExprEmitter::BinOpInfo &); 13340b57cec5SDimitry Andric 13350b57cec5SDimitry Andric static CompoundFunc getComplexOp(BinaryOperatorKind Op) { 13360b57cec5SDimitry Andric switch (Op) { 13370b57cec5SDimitry Andric case BO_MulAssign: return &ComplexExprEmitter::EmitBinMul; 13380b57cec5SDimitry Andric case BO_DivAssign: return &ComplexExprEmitter::EmitBinDiv; 13390b57cec5SDimitry Andric case BO_SubAssign: return &ComplexExprEmitter::EmitBinSub; 13400b57cec5SDimitry Andric case BO_AddAssign: return &ComplexExprEmitter::EmitBinAdd; 13410b57cec5SDimitry Andric default: 13420b57cec5SDimitry Andric llvm_unreachable("unexpected complex compound assignment"); 13430b57cec5SDimitry Andric } 13440b57cec5SDimitry Andric } 13450b57cec5SDimitry Andric 13460b57cec5SDimitry Andric LValue CodeGenFunction:: 13470b57cec5SDimitry Andric EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E) { 13480b57cec5SDimitry Andric CompoundFunc Op = getComplexOp(E->getOpcode()); 13490b57cec5SDimitry Andric RValue Val; 13500b57cec5SDimitry Andric return ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val); 13510b57cec5SDimitry Andric } 13520b57cec5SDimitry Andric 13530b57cec5SDimitry Andric LValue CodeGenFunction:: 13540b57cec5SDimitry Andric EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, 13550b57cec5SDimitry Andric llvm::Value *&Result) { 13560b57cec5SDimitry Andric CompoundFunc Op = getComplexOp(E->getOpcode()); 13570b57cec5SDimitry Andric RValue Val; 13580b57cec5SDimitry Andric LValue Ret = ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val); 13590b57cec5SDimitry Andric Result = Val.getScalarVal(); 13600b57cec5SDimitry Andric return Ret; 13610b57cec5SDimitry Andric } 1362