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 31*0fca6ea1SDimitry Andric namespace llvm { 32*0fca6ea1SDimitry Andric extern cl::opt<bool> EnableSingleByteCoverage; 33*0fca6ea1SDimitry Andric } // namespace llvm 34*0fca6ea1SDimitry Andric 350b57cec5SDimitry Andric typedef CodeGenFunction::ComplexPairTy ComplexPairTy; 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric /// Return the complex type that we are meant to emit. 380b57cec5SDimitry Andric static const ComplexType *getComplexType(QualType type) { 390b57cec5SDimitry Andric type = type.getCanonicalType(); 400b57cec5SDimitry Andric if (const ComplexType *comp = dyn_cast<ComplexType>(type)) { 410b57cec5SDimitry Andric return comp; 420b57cec5SDimitry Andric } else { 430b57cec5SDimitry Andric return cast<ComplexType>(cast<AtomicType>(type)->getValueType()); 440b57cec5SDimitry Andric } 450b57cec5SDimitry Andric } 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric namespace { 480b57cec5SDimitry Andric class ComplexExprEmitter 490b57cec5SDimitry Andric : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> { 500b57cec5SDimitry Andric CodeGenFunction &CGF; 510b57cec5SDimitry Andric CGBuilderTy &Builder; 520b57cec5SDimitry Andric bool IgnoreReal; 530b57cec5SDimitry Andric bool IgnoreImag; 54*0fca6ea1SDimitry Andric bool FPHasBeenPromoted; 55*0fca6ea1SDimitry Andric 560b57cec5SDimitry Andric public: 570b57cec5SDimitry Andric ComplexExprEmitter(CodeGenFunction &cgf, bool ir = false, bool ii = false) 58*0fca6ea1SDimitry Andric : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii), 59*0fca6ea1SDimitry Andric FPHasBeenPromoted(false) {} 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 620b57cec5SDimitry Andric // Utilities 630b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric bool TestAndClearIgnoreReal() { 660b57cec5SDimitry Andric bool I = IgnoreReal; 670b57cec5SDimitry Andric IgnoreReal = false; 680b57cec5SDimitry Andric return I; 690b57cec5SDimitry Andric } 700b57cec5SDimitry Andric bool TestAndClearIgnoreImag() { 710b57cec5SDimitry Andric bool I = IgnoreImag; 720b57cec5SDimitry Andric IgnoreImag = false; 730b57cec5SDimitry Andric return I; 740b57cec5SDimitry Andric } 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric /// EmitLoadOfLValue - Given an expression with complex type that represents a 770b57cec5SDimitry Andric /// value l-value, this method emits the address of the l-value, then loads 780b57cec5SDimitry Andric /// and returns the result. 790b57cec5SDimitry Andric ComplexPairTy EmitLoadOfLValue(const Expr *E) { 800b57cec5SDimitry Andric return EmitLoadOfLValue(CGF.EmitLValue(E), E->getExprLoc()); 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric ComplexPairTy EmitLoadOfLValue(LValue LV, SourceLocation Loc); 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric /// EmitStoreOfComplex - Store the specified real/imag parts into the 860b57cec5SDimitry Andric /// specified value pointer. 870b57cec5SDimitry Andric void EmitStoreOfComplex(ComplexPairTy Val, LValue LV, bool isInit); 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric /// Emit a cast from complex value Val to DestType. 900b57cec5SDimitry Andric ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType, 910b57cec5SDimitry Andric QualType DestType, SourceLocation Loc); 920b57cec5SDimitry Andric /// Emit a cast from scalar value Val to DestType. 930b57cec5SDimitry Andric ComplexPairTy EmitScalarToComplexCast(llvm::Value *Val, QualType SrcType, 940b57cec5SDimitry Andric QualType DestType, SourceLocation Loc); 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 970b57cec5SDimitry Andric // Visitor Methods 980b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric ComplexPairTy Visit(Expr *E) { 1010b57cec5SDimitry Andric ApplyDebugLocation DL(CGF, E); 1020b57cec5SDimitry Andric return StmtVisitor<ComplexExprEmitter, ComplexPairTy>::Visit(E); 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric ComplexPairTy VisitStmt(Stmt *S) { 1065ffd83dbSDimitry Andric S->dump(llvm::errs(), CGF.getContext()); 1070b57cec5SDimitry Andric llvm_unreachable("Stmt can't have complex result type!"); 1080b57cec5SDimitry Andric } 1090b57cec5SDimitry Andric ComplexPairTy VisitExpr(Expr *S); 1100b57cec5SDimitry Andric ComplexPairTy VisitConstantExpr(ConstantExpr *E) { 1115ffd83dbSDimitry Andric if (llvm::Constant *Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) 1125ffd83dbSDimitry Andric return ComplexPairTy(Result->getAggregateElement(0U), 1135ffd83dbSDimitry Andric Result->getAggregateElement(1U)); 1140b57cec5SDimitry Andric return Visit(E->getSubExpr()); 1150b57cec5SDimitry Andric } 1160b57cec5SDimitry Andric ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());} 1170b57cec5SDimitry Andric ComplexPairTy VisitGenericSelectionExpr(GenericSelectionExpr *GE) { 1180b57cec5SDimitry Andric return Visit(GE->getResultExpr()); 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric ComplexPairTy VisitImaginaryLiteral(const ImaginaryLiteral *IL); 1210b57cec5SDimitry Andric ComplexPairTy 1220b57cec5SDimitry Andric VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *PE) { 1230b57cec5SDimitry Andric return Visit(PE->getReplacement()); 1240b57cec5SDimitry Andric } 1250b57cec5SDimitry Andric ComplexPairTy VisitCoawaitExpr(CoawaitExpr *S) { 1260b57cec5SDimitry Andric return CGF.EmitCoawaitExpr(*S).getComplexVal(); 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric ComplexPairTy VisitCoyieldExpr(CoyieldExpr *S) { 1290b57cec5SDimitry Andric return CGF.EmitCoyieldExpr(*S).getComplexVal(); 1300b57cec5SDimitry Andric } 1310b57cec5SDimitry Andric ComplexPairTy VisitUnaryCoawait(const UnaryOperator *E) { 1320b57cec5SDimitry Andric return Visit(E->getSubExpr()); 1330b57cec5SDimitry Andric } 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric ComplexPairTy emitConstant(const CodeGenFunction::ConstantEmission &Constant, 1360b57cec5SDimitry Andric Expr *E) { 1370b57cec5SDimitry Andric assert(Constant && "not a constant"); 1380b57cec5SDimitry Andric if (Constant.isReference()) 1390b57cec5SDimitry Andric return EmitLoadOfLValue(Constant.getReferenceLValue(CGF, E), 1400b57cec5SDimitry Andric E->getExprLoc()); 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric llvm::Constant *pair = Constant.getValue(); 1430b57cec5SDimitry Andric return ComplexPairTy(pair->getAggregateElement(0U), 1440b57cec5SDimitry Andric pair->getAggregateElement(1U)); 1450b57cec5SDimitry Andric } 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric // l-values. 1480b57cec5SDimitry Andric ComplexPairTy VisitDeclRefExpr(DeclRefExpr *E) { 1490b57cec5SDimitry Andric if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E)) 1500b57cec5SDimitry Andric return emitConstant(Constant, E); 1510b57cec5SDimitry Andric return EmitLoadOfLValue(E); 1520b57cec5SDimitry Andric } 1530b57cec5SDimitry Andric ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { 1540b57cec5SDimitry Andric return EmitLoadOfLValue(E); 1550b57cec5SDimitry Andric } 1560b57cec5SDimitry Andric ComplexPairTy VisitObjCMessageExpr(ObjCMessageExpr *E) { 1570b57cec5SDimitry Andric return CGF.EmitObjCMessageExpr(E).getComplexVal(); 1580b57cec5SDimitry Andric } 1590b57cec5SDimitry Andric ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); } 1600b57cec5SDimitry Andric ComplexPairTy VisitMemberExpr(MemberExpr *ME) { 1610b57cec5SDimitry Andric if (CodeGenFunction::ConstantEmission Constant = 1620b57cec5SDimitry Andric CGF.tryEmitAsConstant(ME)) { 1630b57cec5SDimitry Andric CGF.EmitIgnoredExpr(ME->getBase()); 1640b57cec5SDimitry Andric return emitConstant(Constant, ME); 1650b57cec5SDimitry Andric } 1660b57cec5SDimitry Andric return EmitLoadOfLValue(ME); 1670b57cec5SDimitry Andric } 1680b57cec5SDimitry Andric ComplexPairTy VisitOpaqueValueExpr(OpaqueValueExpr *E) { 1690b57cec5SDimitry Andric if (E->isGLValue()) 1700b57cec5SDimitry Andric return EmitLoadOfLValue(CGF.getOrCreateOpaqueLValueMapping(E), 1710b57cec5SDimitry Andric E->getExprLoc()); 1720b57cec5SDimitry Andric return CGF.getOrCreateOpaqueRValueMapping(E).getComplexVal(); 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric ComplexPairTy VisitPseudoObjectExpr(PseudoObjectExpr *E) { 1760b57cec5SDimitry Andric return CGF.EmitPseudoObjectRValue(E).getComplexVal(); 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric // FIXME: CompoundLiteralExpr 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric ComplexPairTy EmitCast(CastKind CK, Expr *Op, QualType DestTy); 1820b57cec5SDimitry Andric ComplexPairTy VisitImplicitCastExpr(ImplicitCastExpr *E) { 1830b57cec5SDimitry Andric // Unlike for scalars, we don't have to worry about function->ptr demotion 1840b57cec5SDimitry Andric // here. 1855f757f3fSDimitry Andric if (E->changesVolatileQualification()) 1865f757f3fSDimitry Andric return EmitLoadOfLValue(E); 1870b57cec5SDimitry Andric return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType()); 1880b57cec5SDimitry Andric } 1890b57cec5SDimitry Andric ComplexPairTy VisitCastExpr(CastExpr *E) { 1900b57cec5SDimitry Andric if (const auto *ECE = dyn_cast<ExplicitCastExpr>(E)) 1910b57cec5SDimitry Andric CGF.CGM.EmitExplicitCastExprType(ECE, &CGF); 1925f757f3fSDimitry Andric if (E->changesVolatileQualification()) 1935f757f3fSDimitry Andric return EmitLoadOfLValue(E); 1940b57cec5SDimitry Andric return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType()); 1950b57cec5SDimitry Andric } 1960b57cec5SDimitry Andric ComplexPairTy VisitCallExpr(const CallExpr *E); 1970b57cec5SDimitry Andric ComplexPairTy VisitStmtExpr(const StmtExpr *E); 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andric // Operators. 2000b57cec5SDimitry Andric ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E, 2010b57cec5SDimitry Andric bool isInc, bool isPre) { 2020b57cec5SDimitry Andric LValue LV = CGF.EmitLValue(E->getSubExpr()); 2030b57cec5SDimitry Andric return CGF.EmitComplexPrePostIncDec(E, LV, isInc, isPre); 2040b57cec5SDimitry Andric } 2050b57cec5SDimitry Andric ComplexPairTy VisitUnaryPostDec(const UnaryOperator *E) { 2060b57cec5SDimitry Andric return VisitPrePostIncDec(E, false, false); 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric ComplexPairTy VisitUnaryPostInc(const UnaryOperator *E) { 2090b57cec5SDimitry Andric return VisitPrePostIncDec(E, true, false); 2100b57cec5SDimitry Andric } 2110b57cec5SDimitry Andric ComplexPairTy VisitUnaryPreDec(const UnaryOperator *E) { 2120b57cec5SDimitry Andric return VisitPrePostIncDec(E, false, true); 2130b57cec5SDimitry Andric } 2140b57cec5SDimitry Andric ComplexPairTy VisitUnaryPreInc(const UnaryOperator *E) { 2150b57cec5SDimitry Andric return VisitPrePostIncDec(E, true, true); 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); } 218bdd1243dSDimitry Andric 219bdd1243dSDimitry Andric ComplexPairTy VisitUnaryPlus(const UnaryOperator *E, 220bdd1243dSDimitry Andric QualType PromotionType = QualType()); 221bdd1243dSDimitry Andric ComplexPairTy VisitPlus(const UnaryOperator *E, QualType PromotionType); 222bdd1243dSDimitry Andric ComplexPairTy VisitUnaryMinus(const UnaryOperator *E, 223bdd1243dSDimitry Andric QualType PromotionType = QualType()); 224bdd1243dSDimitry Andric ComplexPairTy VisitMinus(const UnaryOperator *E, QualType PromotionType); 2250b57cec5SDimitry Andric ComplexPairTy VisitUnaryNot (const UnaryOperator *E); 2260b57cec5SDimitry Andric // LNot,Real,Imag never return complex. 2270b57cec5SDimitry Andric ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) { 2280b57cec5SDimitry Andric return Visit(E->getSubExpr()); 2290b57cec5SDimitry Andric } 2300b57cec5SDimitry Andric ComplexPairTy VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) { 2310b57cec5SDimitry Andric CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE); 2320b57cec5SDimitry Andric return Visit(DAE->getExpr()); 2330b57cec5SDimitry Andric } 2340b57cec5SDimitry Andric ComplexPairTy VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) { 2350b57cec5SDimitry Andric CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE); 2360b57cec5SDimitry Andric return Visit(DIE->getExpr()); 2370b57cec5SDimitry Andric } 2380b57cec5SDimitry Andric ComplexPairTy VisitExprWithCleanups(ExprWithCleanups *E) { 2390b57cec5SDimitry Andric CodeGenFunction::RunCleanupsScope Scope(CGF); 2400b57cec5SDimitry Andric ComplexPairTy Vals = Visit(E->getSubExpr()); 2410b57cec5SDimitry Andric // Defend against dominance problems caused by jumps out of expression 2420b57cec5SDimitry Andric // evaluation through the shared cleanup block. 2430b57cec5SDimitry Andric Scope.ForceCleanup({&Vals.first, &Vals.second}); 2440b57cec5SDimitry Andric return Vals; 2450b57cec5SDimitry Andric } 2460b57cec5SDimitry Andric ComplexPairTy VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { 2470b57cec5SDimitry Andric assert(E->getType()->isAnyComplexType() && "Expected complex type!"); 2480b57cec5SDimitry Andric QualType Elem = E->getType()->castAs<ComplexType>()->getElementType(); 2490b57cec5SDimitry Andric llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem)); 2500b57cec5SDimitry Andric return ComplexPairTy(Null, Null); 2510b57cec5SDimitry Andric } 2520b57cec5SDimitry Andric ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) { 2530b57cec5SDimitry Andric assert(E->getType()->isAnyComplexType() && "Expected complex type!"); 2540b57cec5SDimitry Andric QualType Elem = E->getType()->castAs<ComplexType>()->getElementType(); 2550b57cec5SDimitry Andric llvm::Constant *Null = 2560b57cec5SDimitry Andric llvm::Constant::getNullValue(CGF.ConvertType(Elem)); 2570b57cec5SDimitry Andric return ComplexPairTy(Null, Null); 2580b57cec5SDimitry Andric } 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric struct BinOpInfo { 2610b57cec5SDimitry Andric ComplexPairTy LHS; 2620b57cec5SDimitry Andric ComplexPairTy RHS; 2630b57cec5SDimitry Andric QualType Ty; // Computation Type. 264bdd1243dSDimitry Andric FPOptions FPFeatures; 2650b57cec5SDimitry Andric }; 2660b57cec5SDimitry Andric 267bdd1243dSDimitry Andric BinOpInfo EmitBinOps(const BinaryOperator *E, 268bdd1243dSDimitry Andric QualType PromotionTy = QualType()); 269bdd1243dSDimitry Andric ComplexPairTy EmitPromoted(const Expr *E, QualType PromotionTy); 270bdd1243dSDimitry Andric ComplexPairTy EmitPromotedComplexOperand(const Expr *E, QualType PromotionTy); 2710b57cec5SDimitry Andric LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E, 2720b57cec5SDimitry Andric ComplexPairTy (ComplexExprEmitter::*Func) 2730b57cec5SDimitry Andric (const BinOpInfo &), 2740b57cec5SDimitry Andric RValue &Val); 2750b57cec5SDimitry Andric ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E, 2760b57cec5SDimitry Andric ComplexPairTy (ComplexExprEmitter::*Func) 2770b57cec5SDimitry Andric (const BinOpInfo &)); 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andric ComplexPairTy EmitBinAdd(const BinOpInfo &Op); 2800b57cec5SDimitry Andric ComplexPairTy EmitBinSub(const BinOpInfo &Op); 2810b57cec5SDimitry Andric ComplexPairTy EmitBinMul(const BinOpInfo &Op); 2820b57cec5SDimitry Andric ComplexPairTy EmitBinDiv(const BinOpInfo &Op); 2835f757f3fSDimitry Andric ComplexPairTy EmitAlgebraicDiv(llvm::Value *A, llvm::Value *B, llvm::Value *C, 2845f757f3fSDimitry Andric llvm::Value *D); 2855f757f3fSDimitry Andric ComplexPairTy EmitRangeReductionDiv(llvm::Value *A, llvm::Value *B, 2865f757f3fSDimitry Andric llvm::Value *C, llvm::Value *D); 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric ComplexPairTy EmitComplexBinOpLibCall(StringRef LibCallName, 2890b57cec5SDimitry Andric const BinOpInfo &Op); 2900b57cec5SDimitry Andric 291*0fca6ea1SDimitry Andric QualType GetHigherPrecisionFPType(QualType ElementType) { 292*0fca6ea1SDimitry Andric const auto *CurrentBT = cast<BuiltinType>(ElementType); 293*0fca6ea1SDimitry Andric switch (CurrentBT->getKind()) { 294*0fca6ea1SDimitry Andric case BuiltinType::Kind::Float16: 295*0fca6ea1SDimitry Andric return CGF.getContext().FloatTy; 296*0fca6ea1SDimitry Andric case BuiltinType::Kind::Float: 297*0fca6ea1SDimitry Andric case BuiltinType::Kind::BFloat16: 298*0fca6ea1SDimitry Andric return CGF.getContext().DoubleTy; 299*0fca6ea1SDimitry Andric case BuiltinType::Kind::Double: 300*0fca6ea1SDimitry Andric return CGF.getContext().LongDoubleTy; 301*0fca6ea1SDimitry Andric default: 302*0fca6ea1SDimitry Andric return ElementType; 303*0fca6ea1SDimitry Andric } 304*0fca6ea1SDimitry Andric } 305*0fca6ea1SDimitry Andric 306*0fca6ea1SDimitry Andric QualType HigherPrecisionTypeForComplexArithmetic(QualType ElementType, 307*0fca6ea1SDimitry Andric bool IsDivOpCode) { 308*0fca6ea1SDimitry Andric QualType HigherElementType = GetHigherPrecisionFPType(ElementType); 309*0fca6ea1SDimitry Andric const llvm::fltSemantics &ElementTypeSemantics = 310*0fca6ea1SDimitry Andric CGF.getContext().getFloatTypeSemantics(ElementType); 311*0fca6ea1SDimitry Andric const llvm::fltSemantics &HigherElementTypeSemantics = 312*0fca6ea1SDimitry Andric CGF.getContext().getFloatTypeSemantics(HigherElementType); 313*0fca6ea1SDimitry Andric // Check that the promoted type can handle the intermediate values without 314*0fca6ea1SDimitry Andric // overflowing. This can be interpreted as: 315*0fca6ea1SDimitry Andric // (SmallerType.LargestFiniteVal * SmallerType.LargestFiniteVal) * 2 <= 316*0fca6ea1SDimitry Andric // LargerType.LargestFiniteVal. 317*0fca6ea1SDimitry Andric // In terms of exponent it gives this formula: 318*0fca6ea1SDimitry Andric // (SmallerType.LargestFiniteVal * SmallerType.LargestFiniteVal 319*0fca6ea1SDimitry Andric // doubles the exponent of SmallerType.LargestFiniteVal) 320*0fca6ea1SDimitry Andric if (llvm::APFloat::semanticsMaxExponent(ElementTypeSemantics) * 2 + 1 <= 321*0fca6ea1SDimitry Andric llvm::APFloat::semanticsMaxExponent(HigherElementTypeSemantics)) { 322*0fca6ea1SDimitry Andric FPHasBeenPromoted = true; 323*0fca6ea1SDimitry Andric return CGF.getContext().getComplexType(HigherElementType); 324*0fca6ea1SDimitry Andric } else { 325*0fca6ea1SDimitry Andric DiagnosticsEngine &Diags = CGF.CGM.getDiags(); 326*0fca6ea1SDimitry Andric Diags.Report(diag::warn_next_larger_fp_type_same_size_than_fp); 327*0fca6ea1SDimitry Andric return QualType(); 328*0fca6ea1SDimitry Andric } 329*0fca6ea1SDimitry Andric } 330*0fca6ea1SDimitry Andric 331*0fca6ea1SDimitry Andric QualType getPromotionType(FPOptionsOverride Features, QualType Ty, 332*0fca6ea1SDimitry Andric bool IsDivOpCode = false) { 333bdd1243dSDimitry Andric if (auto *CT = Ty->getAs<ComplexType>()) { 334bdd1243dSDimitry Andric QualType ElementType = CT->getElementType(); 335*0fca6ea1SDimitry Andric bool IsFloatingType = ElementType->isFloatingType(); 336*0fca6ea1SDimitry Andric bool IsComplexRangePromoted = CGF.getLangOpts().getComplexRange() == 337*0fca6ea1SDimitry Andric LangOptions::ComplexRangeKind::CX_Promoted; 338*0fca6ea1SDimitry Andric bool HasNoComplexRangeOverride = !Features.hasComplexRangeOverride(); 339*0fca6ea1SDimitry Andric bool HasMatchingComplexRange = Features.hasComplexRangeOverride() && 340*0fca6ea1SDimitry Andric Features.getComplexRangeOverride() == 341*0fca6ea1SDimitry Andric CGF.getLangOpts().getComplexRange(); 342*0fca6ea1SDimitry Andric 343*0fca6ea1SDimitry Andric if (IsDivOpCode && IsFloatingType && IsComplexRangePromoted && 344*0fca6ea1SDimitry Andric (HasNoComplexRangeOverride || HasMatchingComplexRange)) 345*0fca6ea1SDimitry Andric return HigherPrecisionTypeForComplexArithmetic(ElementType, 346*0fca6ea1SDimitry Andric IsDivOpCode); 347bdd1243dSDimitry Andric if (ElementType.UseExcessPrecision(CGF.getContext())) 348bdd1243dSDimitry Andric return CGF.getContext().getComplexType(CGF.getContext().FloatTy); 3490b57cec5SDimitry Andric } 350bdd1243dSDimitry Andric if (Ty.UseExcessPrecision(CGF.getContext())) 351bdd1243dSDimitry Andric return CGF.getContext().FloatTy; 352bdd1243dSDimitry Andric return QualType(); 3530b57cec5SDimitry Andric } 354bdd1243dSDimitry Andric 355bdd1243dSDimitry Andric #define HANDLEBINOP(OP) \ 356bdd1243dSDimitry Andric ComplexPairTy VisitBin##OP(const BinaryOperator *E) { \ 357*0fca6ea1SDimitry Andric QualType promotionTy = getPromotionType( \ 358*0fca6ea1SDimitry Andric E->getStoredFPFeaturesOrDefault(), E->getType(), \ 359*0fca6ea1SDimitry Andric (E->getOpcode() == BinaryOperatorKind::BO_Div) ? true : false); \ 360bdd1243dSDimitry Andric ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy)); \ 361bdd1243dSDimitry Andric if (!promotionTy.isNull()) \ 362*0fca6ea1SDimitry Andric result = CGF.EmitUnPromotedValue(result, E->getType()); \ 363bdd1243dSDimitry Andric return result; \ 3640b57cec5SDimitry Andric } 365bdd1243dSDimitry Andric 366bdd1243dSDimitry Andric HANDLEBINOP(Mul) 367bdd1243dSDimitry Andric HANDLEBINOP(Div) 368bdd1243dSDimitry Andric HANDLEBINOP(Add) 369bdd1243dSDimitry Andric HANDLEBINOP(Sub) 370bdd1243dSDimitry Andric #undef HANDLEBINOP 3710b57cec5SDimitry Andric 372a7dea167SDimitry Andric ComplexPairTy VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) { 373a7dea167SDimitry Andric return Visit(E->getSemanticForm()); 374a7dea167SDimitry Andric } 375a7dea167SDimitry Andric 3760b57cec5SDimitry Andric // Compound assignments. 3770b57cec5SDimitry Andric ComplexPairTy VisitBinAddAssign(const CompoundAssignOperator *E) { 3780b57cec5SDimitry Andric return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd); 3790b57cec5SDimitry Andric } 3800b57cec5SDimitry Andric ComplexPairTy VisitBinSubAssign(const CompoundAssignOperator *E) { 3810b57cec5SDimitry Andric return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub); 3820b57cec5SDimitry Andric } 3830b57cec5SDimitry Andric ComplexPairTy VisitBinMulAssign(const CompoundAssignOperator *E) { 3840b57cec5SDimitry Andric return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul); 3850b57cec5SDimitry Andric } 3860b57cec5SDimitry Andric ComplexPairTy VisitBinDivAssign(const CompoundAssignOperator *E) { 3870b57cec5SDimitry Andric return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv); 3880b57cec5SDimitry Andric } 3890b57cec5SDimitry Andric 3900b57cec5SDimitry Andric // GCC rejects rem/and/or/xor for integer complex. 3910b57cec5SDimitry Andric // Logical and/or always return int, never complex. 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andric // No comparisons produce a complex result. 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric LValue EmitBinAssignLValue(const BinaryOperator *E, 3960b57cec5SDimitry Andric ComplexPairTy &Val); 3970b57cec5SDimitry Andric ComplexPairTy VisitBinAssign (const BinaryOperator *E); 3980b57cec5SDimitry Andric ComplexPairTy VisitBinComma (const BinaryOperator *E); 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric ComplexPairTy 4020b57cec5SDimitry Andric VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO); 4030b57cec5SDimitry Andric ComplexPairTy VisitChooseExpr(ChooseExpr *CE); 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric ComplexPairTy VisitInitListExpr(InitListExpr *E); 4060b57cec5SDimitry Andric 4070b57cec5SDimitry Andric ComplexPairTy VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { 4080b57cec5SDimitry Andric return EmitLoadOfLValue(E); 4090b57cec5SDimitry Andric } 4100b57cec5SDimitry Andric 4110b57cec5SDimitry Andric ComplexPairTy VisitVAArgExpr(VAArgExpr *E); 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric ComplexPairTy VisitAtomicExpr(AtomicExpr *E) { 4140b57cec5SDimitry Andric return CGF.EmitAtomicExpr(E).getComplexVal(); 4150b57cec5SDimitry Andric } 416*0fca6ea1SDimitry Andric 417*0fca6ea1SDimitry Andric ComplexPairTy VisitPackIndexingExpr(PackIndexingExpr *E) { 418*0fca6ea1SDimitry Andric return Visit(E->getSelectedExpr()); 419*0fca6ea1SDimitry Andric } 4200b57cec5SDimitry Andric }; 4210b57cec5SDimitry Andric } // end anonymous namespace. 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 4240b57cec5SDimitry Andric // Utilities 4250b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric Address CodeGenFunction::emitAddrOfRealComponent(Address addr, 4280b57cec5SDimitry Andric QualType complexType) { 4290b57cec5SDimitry Andric return Builder.CreateStructGEP(addr, 0, addr.getName() + ".realp"); 4300b57cec5SDimitry Andric } 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andric Address CodeGenFunction::emitAddrOfImagComponent(Address addr, 4330b57cec5SDimitry Andric QualType complexType) { 4340b57cec5SDimitry Andric return Builder.CreateStructGEP(addr, 1, addr.getName() + ".imagp"); 4350b57cec5SDimitry Andric } 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andric /// EmitLoadOfLValue - Given an RValue reference for a complex, emit code to 4380b57cec5SDimitry Andric /// load the real and imaginary pieces, returning them as Real/Imag. 4390b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitLoadOfLValue(LValue lvalue, 4400b57cec5SDimitry Andric SourceLocation loc) { 4410b57cec5SDimitry Andric assert(lvalue.isSimple() && "non-simple complex l-value?"); 4420b57cec5SDimitry Andric if (lvalue.getType()->isAtomicType()) 4430b57cec5SDimitry Andric return CGF.EmitAtomicLoad(lvalue, loc).getComplexVal(); 4440b57cec5SDimitry Andric 445*0fca6ea1SDimitry Andric Address SrcPtr = lvalue.getAddress(); 4460b57cec5SDimitry Andric bool isVolatile = lvalue.isVolatileQualified(); 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andric llvm::Value *Real = nullptr, *Imag = nullptr; 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andric if (!IgnoreReal || isVolatile) { 4510b57cec5SDimitry Andric Address RealP = CGF.emitAddrOfRealComponent(SrcPtr, lvalue.getType()); 4520b57cec5SDimitry Andric Real = Builder.CreateLoad(RealP, isVolatile, SrcPtr.getName() + ".real"); 4530b57cec5SDimitry Andric } 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric if (!IgnoreImag || isVolatile) { 4560b57cec5SDimitry Andric Address ImagP = CGF.emitAddrOfImagComponent(SrcPtr, lvalue.getType()); 4570b57cec5SDimitry Andric Imag = Builder.CreateLoad(ImagP, isVolatile, SrcPtr.getName() + ".imag"); 4580b57cec5SDimitry Andric } 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric return ComplexPairTy(Real, Imag); 4610b57cec5SDimitry Andric } 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andric /// EmitStoreOfComplex - Store the specified real/imag parts into the 4640b57cec5SDimitry Andric /// specified value pointer. 4650b57cec5SDimitry Andric void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, LValue lvalue, 4660b57cec5SDimitry Andric bool isInit) { 4670b57cec5SDimitry Andric if (lvalue.getType()->isAtomicType() || 4680b57cec5SDimitry Andric (!isInit && CGF.LValueIsSuitableForInlineAtomic(lvalue))) 4690b57cec5SDimitry Andric return CGF.EmitAtomicStore(RValue::getComplex(Val), lvalue, isInit); 4700b57cec5SDimitry Andric 471*0fca6ea1SDimitry Andric Address Ptr = lvalue.getAddress(); 4720b57cec5SDimitry Andric Address RealPtr = CGF.emitAddrOfRealComponent(Ptr, lvalue.getType()); 4730b57cec5SDimitry Andric Address ImagPtr = CGF.emitAddrOfImagComponent(Ptr, lvalue.getType()); 4740b57cec5SDimitry Andric 4750b57cec5SDimitry Andric Builder.CreateStore(Val.first, RealPtr, lvalue.isVolatileQualified()); 4760b57cec5SDimitry Andric Builder.CreateStore(Val.second, ImagPtr, lvalue.isVolatileQualified()); 4770b57cec5SDimitry Andric } 4780b57cec5SDimitry Andric 4790b57cec5SDimitry Andric 4800b57cec5SDimitry Andric 4810b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 4820b57cec5SDimitry Andric // Visitor Methods 4830b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 4840b57cec5SDimitry Andric 4850b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) { 4860b57cec5SDimitry Andric CGF.ErrorUnsupported(E, "complex expression"); 4870b57cec5SDimitry Andric llvm::Type *EltTy = 4880b57cec5SDimitry Andric CGF.ConvertType(getComplexType(E->getType())->getElementType()); 4890b57cec5SDimitry Andric llvm::Value *U = llvm::UndefValue::get(EltTy); 4900b57cec5SDimitry Andric return ComplexPairTy(U, U); 4910b57cec5SDimitry Andric } 4920b57cec5SDimitry Andric 4930b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter:: 4940b57cec5SDimitry Andric VisitImaginaryLiteral(const ImaginaryLiteral *IL) { 4950b57cec5SDimitry Andric llvm::Value *Imag = CGF.EmitScalarExpr(IL->getSubExpr()); 4960b57cec5SDimitry Andric return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag); 4970b57cec5SDimitry Andric } 4980b57cec5SDimitry Andric 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) { 5010b57cec5SDimitry Andric if (E->getCallReturnType(CGF.getContext())->isReferenceType()) 5020b57cec5SDimitry Andric return EmitLoadOfLValue(E); 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andric return CGF.EmitCallExpr(E).getComplexVal(); 5050b57cec5SDimitry Andric } 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) { 5080b57cec5SDimitry Andric CodeGenFunction::StmtExprEvaluation eval(CGF); 5090b57cec5SDimitry Andric Address RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(), true); 5100b57cec5SDimitry Andric assert(RetAlloca.isValid() && "Expected complex return value"); 5110b57cec5SDimitry Andric return EmitLoadOfLValue(CGF.MakeAddrLValue(RetAlloca, E->getType()), 5120b57cec5SDimitry Andric E->getExprLoc()); 5130b57cec5SDimitry Andric } 5140b57cec5SDimitry Andric 5150b57cec5SDimitry Andric /// Emit a cast from complex value Val to DestType. 5160b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val, 5170b57cec5SDimitry Andric QualType SrcType, 5180b57cec5SDimitry Andric QualType DestType, 5190b57cec5SDimitry Andric SourceLocation Loc) { 5200b57cec5SDimitry Andric // Get the src/dest element type. 5210b57cec5SDimitry Andric SrcType = SrcType->castAs<ComplexType>()->getElementType(); 5220b57cec5SDimitry Andric DestType = DestType->castAs<ComplexType>()->getElementType(); 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric // C99 6.3.1.6: When a value of complex type is converted to another 5250b57cec5SDimitry Andric // complex type, both the real and imaginary parts follow the conversion 5260b57cec5SDimitry Andric // rules for the corresponding real types. 5275ffd83dbSDimitry Andric if (Val.first) 5280b57cec5SDimitry Andric Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType, Loc); 5295ffd83dbSDimitry Andric if (Val.second) 5300b57cec5SDimitry Andric Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType, Loc); 5310b57cec5SDimitry Andric return Val; 5320b57cec5SDimitry Andric } 5330b57cec5SDimitry Andric 5340b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val, 5350b57cec5SDimitry Andric QualType SrcType, 5360b57cec5SDimitry Andric QualType DestType, 5370b57cec5SDimitry Andric SourceLocation Loc) { 5380b57cec5SDimitry Andric // Convert the input element to the element type of the complex. 5390b57cec5SDimitry Andric DestType = DestType->castAs<ComplexType>()->getElementType(); 5400b57cec5SDimitry Andric Val = CGF.EmitScalarConversion(Val, SrcType, DestType, Loc); 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andric // Return (realval, 0). 5430b57cec5SDimitry Andric return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType())); 5440b57cec5SDimitry Andric } 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op, 5470b57cec5SDimitry Andric QualType DestTy) { 5480b57cec5SDimitry Andric switch (CK) { 5490b57cec5SDimitry Andric case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!"); 5500b57cec5SDimitry Andric 5510b57cec5SDimitry Andric // Atomic to non-atomic casts may be more than a no-op for some platforms and 5520b57cec5SDimitry Andric // for some types. 5530b57cec5SDimitry Andric case CK_AtomicToNonAtomic: 5540b57cec5SDimitry Andric case CK_NonAtomicToAtomic: 5550b57cec5SDimitry Andric case CK_NoOp: 5560b57cec5SDimitry Andric case CK_LValueToRValue: 5570b57cec5SDimitry Andric case CK_UserDefinedConversion: 5580b57cec5SDimitry Andric return Visit(Op); 5590b57cec5SDimitry Andric 5600b57cec5SDimitry Andric case CK_LValueBitCast: { 5610b57cec5SDimitry Andric LValue origLV = CGF.EmitLValue(Op); 562*0fca6ea1SDimitry Andric Address V = origLV.getAddress().withElementType(CGF.ConvertType(DestTy)); 5630b57cec5SDimitry Andric return EmitLoadOfLValue(CGF.MakeAddrLValue(V, DestTy), Op->getExprLoc()); 5640b57cec5SDimitry Andric } 5650b57cec5SDimitry Andric 5660b57cec5SDimitry Andric case CK_LValueToRValueBitCast: { 5670b57cec5SDimitry Andric LValue SourceLVal = CGF.EmitLValue(Op); 568*0fca6ea1SDimitry Andric Address Addr = 569*0fca6ea1SDimitry Andric SourceLVal.getAddress().withElementType(CGF.ConvertTypeForMem(DestTy)); 5700b57cec5SDimitry Andric LValue DestLV = CGF.MakeAddrLValue(Addr, DestTy); 5710b57cec5SDimitry Andric DestLV.setTBAAInfo(TBAAAccessInfo::getMayAliasInfo()); 5720b57cec5SDimitry Andric return EmitLoadOfLValue(DestLV, Op->getExprLoc()); 5730b57cec5SDimitry Andric } 5740b57cec5SDimitry Andric 5750b57cec5SDimitry Andric case CK_BitCast: 5760b57cec5SDimitry Andric case CK_BaseToDerived: 5770b57cec5SDimitry Andric case CK_DerivedToBase: 5780b57cec5SDimitry Andric case CK_UncheckedDerivedToBase: 5790b57cec5SDimitry Andric case CK_Dynamic: 5800b57cec5SDimitry Andric case CK_ToUnion: 5810b57cec5SDimitry Andric case CK_ArrayToPointerDecay: 5820b57cec5SDimitry Andric case CK_FunctionToPointerDecay: 5830b57cec5SDimitry Andric case CK_NullToPointer: 5840b57cec5SDimitry Andric case CK_NullToMemberPointer: 5850b57cec5SDimitry Andric case CK_BaseToDerivedMemberPointer: 5860b57cec5SDimitry Andric case CK_DerivedToBaseMemberPointer: 5870b57cec5SDimitry Andric case CK_MemberPointerToBoolean: 5880b57cec5SDimitry Andric case CK_ReinterpretMemberPointer: 5890b57cec5SDimitry Andric case CK_ConstructorConversion: 5900b57cec5SDimitry Andric case CK_IntegralToPointer: 5910b57cec5SDimitry Andric case CK_PointerToIntegral: 5920b57cec5SDimitry Andric case CK_PointerToBoolean: 5930b57cec5SDimitry Andric case CK_ToVoid: 5940b57cec5SDimitry Andric case CK_VectorSplat: 5950b57cec5SDimitry Andric case CK_IntegralCast: 5960b57cec5SDimitry Andric case CK_BooleanToSignedIntegral: 5970b57cec5SDimitry Andric case CK_IntegralToBoolean: 5980b57cec5SDimitry Andric case CK_IntegralToFloating: 5990b57cec5SDimitry Andric case CK_FloatingToIntegral: 6000b57cec5SDimitry Andric case CK_FloatingToBoolean: 6010b57cec5SDimitry Andric case CK_FloatingCast: 6020b57cec5SDimitry Andric case CK_CPointerToObjCPointerCast: 6030b57cec5SDimitry Andric case CK_BlockPointerToObjCPointerCast: 6040b57cec5SDimitry Andric case CK_AnyPointerToBlockPointerCast: 6050b57cec5SDimitry Andric case CK_ObjCObjectLValueCast: 6060b57cec5SDimitry Andric case CK_FloatingComplexToReal: 6070b57cec5SDimitry Andric case CK_FloatingComplexToBoolean: 6080b57cec5SDimitry Andric case CK_IntegralComplexToReal: 6090b57cec5SDimitry Andric case CK_IntegralComplexToBoolean: 6100b57cec5SDimitry Andric case CK_ARCProduceObject: 6110b57cec5SDimitry Andric case CK_ARCConsumeObject: 6120b57cec5SDimitry Andric case CK_ARCReclaimReturnedObject: 6130b57cec5SDimitry Andric case CK_ARCExtendBlockObject: 6140b57cec5SDimitry Andric case CK_CopyAndAutoreleaseBlockObject: 6150b57cec5SDimitry Andric case CK_BuiltinFnToFnPtr: 6160b57cec5SDimitry Andric case CK_ZeroToOCLOpaqueType: 6170b57cec5SDimitry Andric case CK_AddressSpaceConversion: 6180b57cec5SDimitry Andric case CK_IntToOCLSampler: 619e8d8bef9SDimitry Andric case CK_FloatingToFixedPoint: 620e8d8bef9SDimitry Andric case CK_FixedPointToFloating: 6210b57cec5SDimitry Andric case CK_FixedPointCast: 6220b57cec5SDimitry Andric case CK_FixedPointToBoolean: 6230b57cec5SDimitry Andric case CK_FixedPointToIntegral: 6240b57cec5SDimitry Andric case CK_IntegralToFixedPoint: 625fe6060f1SDimitry Andric case CK_MatrixCast: 626*0fca6ea1SDimitry Andric case CK_HLSLVectorTruncation: 627*0fca6ea1SDimitry Andric case CK_HLSLArrayRValue: 6280b57cec5SDimitry Andric llvm_unreachable("invalid cast kind for complex value"); 6290b57cec5SDimitry Andric 6300b57cec5SDimitry Andric case CK_FloatingRealToComplex: 631e8d8bef9SDimitry Andric case CK_IntegralRealToComplex: { 632e8d8bef9SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op); 6330b57cec5SDimitry Andric return EmitScalarToComplexCast(CGF.EmitScalarExpr(Op), Op->getType(), 6340b57cec5SDimitry Andric DestTy, Op->getExprLoc()); 635e8d8bef9SDimitry Andric } 6360b57cec5SDimitry Andric 6370b57cec5SDimitry Andric case CK_FloatingComplexCast: 6380b57cec5SDimitry Andric case CK_FloatingComplexToIntegralComplex: 6390b57cec5SDimitry Andric case CK_IntegralComplexCast: 640e8d8bef9SDimitry Andric case CK_IntegralComplexToFloatingComplex: { 641e8d8bef9SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op); 6420b57cec5SDimitry Andric return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy, 6430b57cec5SDimitry Andric Op->getExprLoc()); 6440b57cec5SDimitry Andric } 645e8d8bef9SDimitry Andric } 6460b57cec5SDimitry Andric 6470b57cec5SDimitry Andric llvm_unreachable("unknown cast resulting in complex value"); 6480b57cec5SDimitry Andric } 6490b57cec5SDimitry Andric 650bdd1243dSDimitry Andric ComplexPairTy ComplexExprEmitter::VisitUnaryPlus(const UnaryOperator *E, 651bdd1243dSDimitry Andric QualType PromotionType) { 652*0fca6ea1SDimitry Andric E->hasStoredFPFeatures(); 653*0fca6ea1SDimitry Andric QualType promotionTy = 654*0fca6ea1SDimitry Andric PromotionType.isNull() 655*0fca6ea1SDimitry Andric ? getPromotionType(E->getStoredFPFeaturesOrDefault(), 656*0fca6ea1SDimitry Andric E->getSubExpr()->getType()) 657bdd1243dSDimitry Andric : PromotionType; 658bdd1243dSDimitry Andric ComplexPairTy result = VisitPlus(E, promotionTy); 659bdd1243dSDimitry Andric if (!promotionTy.isNull()) 660bdd1243dSDimitry Andric return CGF.EmitUnPromotedValue(result, E->getSubExpr()->getType()); 661bdd1243dSDimitry Andric return result; 662bdd1243dSDimitry Andric } 663bdd1243dSDimitry Andric 664bdd1243dSDimitry Andric ComplexPairTy ComplexExprEmitter::VisitPlus(const UnaryOperator *E, 665bdd1243dSDimitry Andric QualType PromotionType) { 6660b57cec5SDimitry Andric TestAndClearIgnoreReal(); 6670b57cec5SDimitry Andric TestAndClearIgnoreImag(); 668bdd1243dSDimitry Andric if (!PromotionType.isNull()) 669bdd1243dSDimitry Andric return CGF.EmitPromotedComplexExpr(E->getSubExpr(), PromotionType); 670bdd1243dSDimitry Andric return Visit(E->getSubExpr()); 671bdd1243dSDimitry Andric } 672bdd1243dSDimitry Andric 673bdd1243dSDimitry Andric ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E, 674bdd1243dSDimitry Andric QualType PromotionType) { 675*0fca6ea1SDimitry Andric QualType promotionTy = 676*0fca6ea1SDimitry Andric PromotionType.isNull() 677*0fca6ea1SDimitry Andric ? getPromotionType(E->getStoredFPFeaturesOrDefault(), 678*0fca6ea1SDimitry Andric E->getSubExpr()->getType()) 679bdd1243dSDimitry Andric : PromotionType; 680bdd1243dSDimitry Andric ComplexPairTy result = VisitMinus(E, promotionTy); 681bdd1243dSDimitry Andric if (!promotionTy.isNull()) 682bdd1243dSDimitry Andric return CGF.EmitUnPromotedValue(result, E->getSubExpr()->getType()); 683bdd1243dSDimitry Andric return result; 684bdd1243dSDimitry Andric } 685bdd1243dSDimitry Andric ComplexPairTy ComplexExprEmitter::VisitMinus(const UnaryOperator *E, 686bdd1243dSDimitry Andric QualType PromotionType) { 687bdd1243dSDimitry Andric TestAndClearIgnoreReal(); 688bdd1243dSDimitry Andric TestAndClearIgnoreImag(); 689bdd1243dSDimitry Andric ComplexPairTy Op; 690bdd1243dSDimitry Andric if (!PromotionType.isNull()) 691bdd1243dSDimitry Andric Op = CGF.EmitPromotedComplexExpr(E->getSubExpr(), PromotionType); 692bdd1243dSDimitry Andric else 693bdd1243dSDimitry Andric Op = Visit(E->getSubExpr()); 6940b57cec5SDimitry Andric 6950b57cec5SDimitry Andric llvm::Value *ResR, *ResI; 6960b57cec5SDimitry Andric if (Op.first->getType()->isFloatingPointTy()) { 6970b57cec5SDimitry Andric ResR = Builder.CreateFNeg(Op.first, "neg.r"); 6980b57cec5SDimitry Andric ResI = Builder.CreateFNeg(Op.second, "neg.i"); 6990b57cec5SDimitry Andric } else { 7000b57cec5SDimitry Andric ResR = Builder.CreateNeg(Op.first, "neg.r"); 7010b57cec5SDimitry Andric ResI = Builder.CreateNeg(Op.second, "neg.i"); 7020b57cec5SDimitry Andric } 7030b57cec5SDimitry Andric return ComplexPairTy(ResR, ResI); 7040b57cec5SDimitry Andric } 7050b57cec5SDimitry Andric 7060b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) { 7070b57cec5SDimitry Andric TestAndClearIgnoreReal(); 7080b57cec5SDimitry Andric TestAndClearIgnoreImag(); 7090b57cec5SDimitry Andric // ~(a+ib) = a + i*-b 7100b57cec5SDimitry Andric ComplexPairTy Op = Visit(E->getSubExpr()); 7110b57cec5SDimitry Andric llvm::Value *ResI; 7120b57cec5SDimitry Andric if (Op.second->getType()->isFloatingPointTy()) 7130b57cec5SDimitry Andric ResI = Builder.CreateFNeg(Op.second, "conj.i"); 7140b57cec5SDimitry Andric else 7150b57cec5SDimitry Andric ResI = Builder.CreateNeg(Op.second, "conj.i"); 7160b57cec5SDimitry Andric 7170b57cec5SDimitry Andric return ComplexPairTy(Op.first, ResI); 7180b57cec5SDimitry Andric } 7190b57cec5SDimitry Andric 7200b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitBinAdd(const BinOpInfo &Op) { 7210b57cec5SDimitry Andric llvm::Value *ResR, *ResI; 7220b57cec5SDimitry Andric 7230b57cec5SDimitry Andric if (Op.LHS.first->getType()->isFloatingPointTy()) { 724bdd1243dSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures); 7250b57cec5SDimitry Andric ResR = Builder.CreateFAdd(Op.LHS.first, Op.RHS.first, "add.r"); 7260b57cec5SDimitry Andric if (Op.LHS.second && Op.RHS.second) 7270b57cec5SDimitry Andric ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second, "add.i"); 7280b57cec5SDimitry Andric else 7290b57cec5SDimitry Andric ResI = Op.LHS.second ? Op.LHS.second : Op.RHS.second; 7300b57cec5SDimitry Andric assert(ResI && "Only one operand may be real!"); 7310b57cec5SDimitry Andric } else { 7320b57cec5SDimitry Andric ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first, "add.r"); 7330b57cec5SDimitry Andric assert(Op.LHS.second && Op.RHS.second && 7340b57cec5SDimitry Andric "Both operands of integer complex operators must be complex!"); 7350b57cec5SDimitry Andric ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second, "add.i"); 7360b57cec5SDimitry Andric } 7370b57cec5SDimitry Andric return ComplexPairTy(ResR, ResI); 7380b57cec5SDimitry Andric } 7390b57cec5SDimitry Andric 7400b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitBinSub(const BinOpInfo &Op) { 7410b57cec5SDimitry Andric llvm::Value *ResR, *ResI; 7420b57cec5SDimitry Andric if (Op.LHS.first->getType()->isFloatingPointTy()) { 743bdd1243dSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures); 7440b57cec5SDimitry Andric ResR = Builder.CreateFSub(Op.LHS.first, Op.RHS.first, "sub.r"); 7450b57cec5SDimitry Andric if (Op.LHS.second && Op.RHS.second) 7460b57cec5SDimitry Andric ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second, "sub.i"); 7470b57cec5SDimitry Andric else 7480b57cec5SDimitry Andric ResI = Op.LHS.second ? Op.LHS.second 7490b57cec5SDimitry Andric : Builder.CreateFNeg(Op.RHS.second, "sub.i"); 7500b57cec5SDimitry Andric assert(ResI && "Only one operand may be real!"); 7510b57cec5SDimitry Andric } else { 7520b57cec5SDimitry Andric ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first, "sub.r"); 7530b57cec5SDimitry Andric assert(Op.LHS.second && Op.RHS.second && 7540b57cec5SDimitry Andric "Both operands of integer complex operators must be complex!"); 7550b57cec5SDimitry Andric ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second, "sub.i"); 7560b57cec5SDimitry Andric } 7570b57cec5SDimitry Andric return ComplexPairTy(ResR, ResI); 7580b57cec5SDimitry Andric } 7590b57cec5SDimitry Andric 7600b57cec5SDimitry Andric /// Emit a libcall for a binary operation on complex types. 7610b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName, 7620b57cec5SDimitry Andric const BinOpInfo &Op) { 7630b57cec5SDimitry Andric CallArgList Args; 7640b57cec5SDimitry Andric Args.add(RValue::get(Op.LHS.first), 7650b57cec5SDimitry Andric Op.Ty->castAs<ComplexType>()->getElementType()); 7660b57cec5SDimitry Andric Args.add(RValue::get(Op.LHS.second), 7670b57cec5SDimitry Andric Op.Ty->castAs<ComplexType>()->getElementType()); 7680b57cec5SDimitry Andric Args.add(RValue::get(Op.RHS.first), 7690b57cec5SDimitry Andric Op.Ty->castAs<ComplexType>()->getElementType()); 7700b57cec5SDimitry Andric Args.add(RValue::get(Op.RHS.second), 7710b57cec5SDimitry Andric Op.Ty->castAs<ComplexType>()->getElementType()); 7720b57cec5SDimitry Andric 7730b57cec5SDimitry Andric // We *must* use the full CG function call building logic here because the 7740b57cec5SDimitry Andric // complex type has special ABI handling. We also should not forget about 7750b57cec5SDimitry Andric // special calling convention which may be used for compiler builtins. 7760b57cec5SDimitry Andric 7770b57cec5SDimitry Andric // We create a function qualified type to state that this call does not have 7780b57cec5SDimitry Andric // any exceptions. 7790b57cec5SDimitry Andric FunctionProtoType::ExtProtoInfo EPI; 7800b57cec5SDimitry Andric EPI = EPI.withExceptionSpec( 7810b57cec5SDimitry Andric FunctionProtoType::ExceptionSpecInfo(EST_BasicNoexcept)); 7820b57cec5SDimitry Andric SmallVector<QualType, 4> ArgsQTys( 7830b57cec5SDimitry Andric 4, Op.Ty->castAs<ComplexType>()->getElementType()); 7840b57cec5SDimitry Andric QualType FQTy = CGF.getContext().getFunctionType(Op.Ty, ArgsQTys, EPI); 7850b57cec5SDimitry Andric const CGFunctionInfo &FuncInfo = CGF.CGM.getTypes().arrangeFreeFunctionCall( 7860b57cec5SDimitry Andric Args, cast<FunctionType>(FQTy.getTypePtr()), false); 7870b57cec5SDimitry Andric 7880b57cec5SDimitry Andric llvm::FunctionType *FTy = CGF.CGM.getTypes().GetFunctionType(FuncInfo); 7890b57cec5SDimitry Andric llvm::FunctionCallee Func = CGF.CGM.CreateRuntimeFunction( 7900b57cec5SDimitry Andric FTy, LibCallName, llvm::AttributeList(), true); 7910b57cec5SDimitry Andric CGCallee Callee = CGCallee::forDirect(Func, FQTy->getAs<FunctionProtoType>()); 7920b57cec5SDimitry Andric 7930b57cec5SDimitry Andric llvm::CallBase *Call; 7940b57cec5SDimitry Andric RValue Res = CGF.EmitCall(FuncInfo, Callee, ReturnValueSlot(), Args, &Call); 7950b57cec5SDimitry Andric Call->setCallingConv(CGF.CGM.getRuntimeCC()); 7960b57cec5SDimitry Andric return Res.getComplexVal(); 7970b57cec5SDimitry Andric } 7980b57cec5SDimitry Andric 7990b57cec5SDimitry Andric /// Lookup the libcall name for a given floating point type complex 8000b57cec5SDimitry Andric /// multiply. 8010b57cec5SDimitry Andric static StringRef getComplexMultiplyLibCallName(llvm::Type *Ty) { 8020b57cec5SDimitry Andric switch (Ty->getTypeID()) { 8030b57cec5SDimitry Andric default: 8040b57cec5SDimitry Andric llvm_unreachable("Unsupported floating point type!"); 8050b57cec5SDimitry Andric case llvm::Type::HalfTyID: 8060b57cec5SDimitry Andric return "__mulhc3"; 8070b57cec5SDimitry Andric case llvm::Type::FloatTyID: 8080b57cec5SDimitry Andric return "__mulsc3"; 8090b57cec5SDimitry Andric case llvm::Type::DoubleTyID: 8100b57cec5SDimitry Andric return "__muldc3"; 8110b57cec5SDimitry Andric case llvm::Type::PPC_FP128TyID: 8120b57cec5SDimitry Andric return "__multc3"; 8130b57cec5SDimitry Andric case llvm::Type::X86_FP80TyID: 8140b57cec5SDimitry Andric return "__mulxc3"; 8150b57cec5SDimitry Andric case llvm::Type::FP128TyID: 8160b57cec5SDimitry Andric return "__multc3"; 8170b57cec5SDimitry Andric } 8180b57cec5SDimitry Andric } 8190b57cec5SDimitry Andric 8200b57cec5SDimitry Andric // See C11 Annex G.5.1 for the semantics of multiplicative operators on complex 8210b57cec5SDimitry Andric // typed values. 8220b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) { 8230b57cec5SDimitry Andric using llvm::Value; 8240b57cec5SDimitry Andric Value *ResR, *ResI; 8250b57cec5SDimitry Andric llvm::MDBuilder MDHelper(CGF.getLLVMContext()); 8260b57cec5SDimitry Andric 8270b57cec5SDimitry Andric if (Op.LHS.first->getType()->isFloatingPointTy()) { 8280b57cec5SDimitry Andric // The general formulation is: 8290b57cec5SDimitry Andric // (a + ib) * (c + id) = (a * c - b * d) + i(a * d + b * c) 8300b57cec5SDimitry Andric // 8310b57cec5SDimitry Andric // But we can fold away components which would be zero due to a real 8320b57cec5SDimitry Andric // operand according to C11 Annex G.5.1p2. 8330b57cec5SDimitry Andric 834bdd1243dSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures); 8350b57cec5SDimitry Andric if (Op.LHS.second && Op.RHS.second) { 8360b57cec5SDimitry Andric // If both operands are complex, emit the core math directly, and then 8370b57cec5SDimitry Andric // test for NaNs. If we find NaNs in the result, we delegate to a libcall 8380b57cec5SDimitry Andric // to carefully re-compute the correct infinity representation if 8390b57cec5SDimitry Andric // possible. The expectation is that the presence of NaNs here is 8400b57cec5SDimitry Andric // *extremely* rare, and so the cost of the libcall is almost irrelevant. 8410b57cec5SDimitry Andric // This is good, because the libcall re-computes the core multiplication 8420b57cec5SDimitry Andric // exactly the same as we do here and re-tests for NaNs in order to be 8430b57cec5SDimitry Andric // a generic complex*complex libcall. 8440b57cec5SDimitry Andric 8450b57cec5SDimitry Andric // First compute the four products. 8460b57cec5SDimitry Andric Value *AC = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul_ac"); 8470b57cec5SDimitry Andric Value *BD = Builder.CreateFMul(Op.LHS.second, Op.RHS.second, "mul_bd"); 8480b57cec5SDimitry Andric Value *AD = Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul_ad"); 8490b57cec5SDimitry Andric Value *BC = Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul_bc"); 8500b57cec5SDimitry Andric 8510b57cec5SDimitry Andric // The real part is the difference of the first two, the imaginary part is 8520b57cec5SDimitry Andric // the sum of the second. 8530b57cec5SDimitry Andric ResR = Builder.CreateFSub(AC, BD, "mul_r"); 8540b57cec5SDimitry Andric ResI = Builder.CreateFAdd(AD, BC, "mul_i"); 8550b57cec5SDimitry Andric 856*0fca6ea1SDimitry Andric if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Basic || 857*0fca6ea1SDimitry Andric Op.FPFeatures.getComplexRange() == LangOptions::CX_Improved || 858*0fca6ea1SDimitry Andric Op.FPFeatures.getComplexRange() == LangOptions::CX_Promoted) 8595f757f3fSDimitry Andric return ComplexPairTy(ResR, ResI); 8605f757f3fSDimitry Andric 8610b57cec5SDimitry Andric // Emit the test for the real part becoming NaN and create a branch to 8620b57cec5SDimitry Andric // handle it. We test for NaN by comparing the number to itself. 8630b57cec5SDimitry Andric Value *IsRNaN = Builder.CreateFCmpUNO(ResR, ResR, "isnan_cmp"); 8640b57cec5SDimitry Andric llvm::BasicBlock *ContBB = CGF.createBasicBlock("complex_mul_cont"); 8650b57cec5SDimitry Andric llvm::BasicBlock *INaNBB = CGF.createBasicBlock("complex_mul_imag_nan"); 8660b57cec5SDimitry Andric llvm::Instruction *Branch = Builder.CreateCondBr(IsRNaN, INaNBB, ContBB); 8670b57cec5SDimitry Andric llvm::BasicBlock *OrigBB = Branch->getParent(); 8680b57cec5SDimitry Andric 8690b57cec5SDimitry Andric // Give hint that we very much don't expect to see NaNs. 870*0fca6ea1SDimitry Andric llvm::MDNode *BrWeight = MDHelper.createUnlikelyBranchWeights(); 8710b57cec5SDimitry Andric Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight); 8720b57cec5SDimitry Andric 8730b57cec5SDimitry Andric // Now test the imaginary part and create its branch. 8740b57cec5SDimitry Andric CGF.EmitBlock(INaNBB); 8750b57cec5SDimitry Andric Value *IsINaN = Builder.CreateFCmpUNO(ResI, ResI, "isnan_cmp"); 8760b57cec5SDimitry Andric llvm::BasicBlock *LibCallBB = CGF.createBasicBlock("complex_mul_libcall"); 8770b57cec5SDimitry Andric Branch = Builder.CreateCondBr(IsINaN, LibCallBB, ContBB); 8780b57cec5SDimitry Andric Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight); 8790b57cec5SDimitry Andric 8800b57cec5SDimitry Andric // Now emit the libcall on this slowest of the slow paths. 8810b57cec5SDimitry Andric CGF.EmitBlock(LibCallBB); 8820b57cec5SDimitry Andric Value *LibCallR, *LibCallI; 8830b57cec5SDimitry Andric std::tie(LibCallR, LibCallI) = EmitComplexBinOpLibCall( 8840b57cec5SDimitry Andric getComplexMultiplyLibCallName(Op.LHS.first->getType()), Op); 8850b57cec5SDimitry Andric Builder.CreateBr(ContBB); 8860b57cec5SDimitry Andric 8870b57cec5SDimitry Andric // Finally continue execution by phi-ing together the different 8880b57cec5SDimitry Andric // computation paths. 8890b57cec5SDimitry Andric CGF.EmitBlock(ContBB); 8900b57cec5SDimitry Andric llvm::PHINode *RealPHI = Builder.CreatePHI(ResR->getType(), 3, "real_mul_phi"); 8910b57cec5SDimitry Andric RealPHI->addIncoming(ResR, OrigBB); 8920b57cec5SDimitry Andric RealPHI->addIncoming(ResR, INaNBB); 8930b57cec5SDimitry Andric RealPHI->addIncoming(LibCallR, LibCallBB); 8940b57cec5SDimitry Andric llvm::PHINode *ImagPHI = Builder.CreatePHI(ResI->getType(), 3, "imag_mul_phi"); 8950b57cec5SDimitry Andric ImagPHI->addIncoming(ResI, OrigBB); 8960b57cec5SDimitry Andric ImagPHI->addIncoming(ResI, INaNBB); 8970b57cec5SDimitry Andric ImagPHI->addIncoming(LibCallI, LibCallBB); 8980b57cec5SDimitry Andric return ComplexPairTy(RealPHI, ImagPHI); 8990b57cec5SDimitry Andric } 9000b57cec5SDimitry Andric assert((Op.LHS.second || Op.RHS.second) && 9010b57cec5SDimitry Andric "At least one operand must be complex!"); 9020b57cec5SDimitry Andric 9030b57cec5SDimitry Andric // If either of the operands is a real rather than a complex, the 9040b57cec5SDimitry Andric // imaginary component is ignored when computing the real component of the 9050b57cec5SDimitry Andric // result. 9060b57cec5SDimitry Andric ResR = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul.rl"); 9070b57cec5SDimitry Andric 9080b57cec5SDimitry Andric ResI = Op.LHS.second 9090b57cec5SDimitry Andric ? Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul.il") 9100b57cec5SDimitry Andric : Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul.ir"); 9110b57cec5SDimitry Andric } else { 9120b57cec5SDimitry Andric assert(Op.LHS.second && Op.RHS.second && 9130b57cec5SDimitry Andric "Both operands of integer complex operators must be complex!"); 9140b57cec5SDimitry Andric Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first, "mul.rl"); 9150b57cec5SDimitry Andric Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second, "mul.rr"); 9160b57cec5SDimitry Andric ResR = Builder.CreateSub(ResRl, ResRr, "mul.r"); 9170b57cec5SDimitry Andric 9180b57cec5SDimitry Andric Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first, "mul.il"); 9190b57cec5SDimitry Andric Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second, "mul.ir"); 9200b57cec5SDimitry Andric ResI = Builder.CreateAdd(ResIl, ResIr, "mul.i"); 9210b57cec5SDimitry Andric } 9220b57cec5SDimitry Andric return ComplexPairTy(ResR, ResI); 9230b57cec5SDimitry Andric } 9240b57cec5SDimitry Andric 9255f757f3fSDimitry Andric ComplexPairTy ComplexExprEmitter::EmitAlgebraicDiv(llvm::Value *LHSr, 9265f757f3fSDimitry Andric llvm::Value *LHSi, 9275f757f3fSDimitry Andric llvm::Value *RHSr, 9285f757f3fSDimitry Andric llvm::Value *RHSi) { 9295f757f3fSDimitry Andric // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) 9305f757f3fSDimitry Andric llvm::Value *DSTr, *DSTi; 9315f757f3fSDimitry Andric 9325f757f3fSDimitry Andric llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr); // a*c 9335f757f3fSDimitry Andric llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi); // b*d 9345f757f3fSDimitry Andric llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD); // ac+bd 9355f757f3fSDimitry Andric 9365f757f3fSDimitry Andric llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr); // c*c 9375f757f3fSDimitry Andric llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi); // d*d 9385f757f3fSDimitry Andric llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD); // cc+dd 9395f757f3fSDimitry Andric 9405f757f3fSDimitry Andric llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr); // b*c 9415f757f3fSDimitry Andric llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi); // a*d 9425f757f3fSDimitry Andric llvm::Value *BCmAD = Builder.CreateFSub(BC, AD); // bc-ad 9435f757f3fSDimitry Andric 9445f757f3fSDimitry Andric DSTr = Builder.CreateFDiv(ACpBD, CCpDD); 9455f757f3fSDimitry Andric DSTi = Builder.CreateFDiv(BCmAD, CCpDD); 9465f757f3fSDimitry Andric return ComplexPairTy(DSTr, DSTi); 9475f757f3fSDimitry Andric } 9485f757f3fSDimitry Andric 9495f757f3fSDimitry Andric // EmitFAbs - Emit a call to @llvm.fabs. 9505f757f3fSDimitry Andric static llvm::Value *EmitllvmFAbs(CodeGenFunction &CGF, llvm::Value *Value) { 9515f757f3fSDimitry Andric llvm::Function *Func = 9525f757f3fSDimitry Andric CGF.CGM.getIntrinsic(llvm::Intrinsic::fabs, Value->getType()); 9535f757f3fSDimitry Andric llvm::Value *Call = CGF.Builder.CreateCall(Func, Value); 9545f757f3fSDimitry Andric return Call; 9555f757f3fSDimitry Andric } 9565f757f3fSDimitry Andric 9575f757f3fSDimitry Andric // EmitRangeReductionDiv - Implements Smith's algorithm for complex division. 9585f757f3fSDimitry Andric // SMITH, R. L. Algorithm 116: Complex division. Commun. ACM 5, 8 (1962). 9595f757f3fSDimitry Andric ComplexPairTy ComplexExprEmitter::EmitRangeReductionDiv(llvm::Value *LHSr, 9605f757f3fSDimitry Andric llvm::Value *LHSi, 9615f757f3fSDimitry Andric llvm::Value *RHSr, 9625f757f3fSDimitry Andric llvm::Value *RHSi) { 9637a6dacacSDimitry Andric // FIXME: This could eventually be replaced by an LLVM intrinsic to 9647a6dacacSDimitry Andric // avoid this long IR sequence. 9657a6dacacSDimitry Andric 9665f757f3fSDimitry Andric // (a + ib) / (c + id) = (e + if) 9675f757f3fSDimitry Andric llvm::Value *FAbsRHSr = EmitllvmFAbs(CGF, RHSr); // |c| 9685f757f3fSDimitry Andric llvm::Value *FAbsRHSi = EmitllvmFAbs(CGF, RHSi); // |d| 9695f757f3fSDimitry Andric // |c| >= |d| 9705f757f3fSDimitry Andric llvm::Value *IsR = Builder.CreateFCmpUGT(FAbsRHSr, FAbsRHSi, "abs_cmp"); 9715f757f3fSDimitry Andric 9725f757f3fSDimitry Andric llvm::BasicBlock *TrueBB = 9735f757f3fSDimitry Andric CGF.createBasicBlock("abs_rhsr_greater_or_equal_abs_rhsi"); 9745f757f3fSDimitry Andric llvm::BasicBlock *FalseBB = 9755f757f3fSDimitry Andric CGF.createBasicBlock("abs_rhsr_less_than_abs_rhsi"); 9765f757f3fSDimitry Andric llvm::BasicBlock *ContBB = CGF.createBasicBlock("complex_div"); 9775f757f3fSDimitry Andric Builder.CreateCondBr(IsR, TrueBB, FalseBB); 9785f757f3fSDimitry Andric 9795f757f3fSDimitry Andric CGF.EmitBlock(TrueBB); 9805f757f3fSDimitry Andric // abs(c) >= abs(d) 9815f757f3fSDimitry Andric // r = d/c 9825f757f3fSDimitry Andric // tmp = c + rd 9835f757f3fSDimitry Andric // e = (a + br)/tmp 9845f757f3fSDimitry Andric // f = (b - ar)/tmp 9855f757f3fSDimitry Andric llvm::Value *DdC = Builder.CreateFDiv(RHSi, RHSr); // r=d/c 9865f757f3fSDimitry Andric 9875f757f3fSDimitry Andric llvm::Value *RD = Builder.CreateFMul(DdC, RHSi); // rd 9885f757f3fSDimitry Andric llvm::Value *CpRD = Builder.CreateFAdd(RHSr, RD); // tmp=c+rd 9895f757f3fSDimitry Andric 9905f757f3fSDimitry Andric llvm::Value *T3 = Builder.CreateFMul(LHSi, DdC); // br 9915f757f3fSDimitry Andric llvm::Value *T4 = Builder.CreateFAdd(LHSr, T3); // a+br 9925f757f3fSDimitry Andric llvm::Value *DSTTr = Builder.CreateFDiv(T4, CpRD); // (a+br)/tmp 9935f757f3fSDimitry Andric 9945f757f3fSDimitry Andric llvm::Value *T5 = Builder.CreateFMul(LHSr, DdC); // ar 9955f757f3fSDimitry Andric llvm::Value *T6 = Builder.CreateFSub(LHSi, T5); // b-ar 9965f757f3fSDimitry Andric llvm::Value *DSTTi = Builder.CreateFDiv(T6, CpRD); // (b-ar)/tmp 9975f757f3fSDimitry Andric Builder.CreateBr(ContBB); 9985f757f3fSDimitry Andric 9995f757f3fSDimitry Andric CGF.EmitBlock(FalseBB); 10005f757f3fSDimitry Andric // abs(c) < abs(d) 10015f757f3fSDimitry Andric // r = c/d 10025f757f3fSDimitry Andric // tmp = d + rc 10035f757f3fSDimitry Andric // e = (ar + b)/tmp 10045f757f3fSDimitry Andric // f = (br - a)/tmp 10055f757f3fSDimitry Andric llvm::Value *CdD = Builder.CreateFDiv(RHSr, RHSi); // r=c/d 10065f757f3fSDimitry Andric 10075f757f3fSDimitry Andric llvm::Value *RC = Builder.CreateFMul(CdD, RHSr); // rc 10085f757f3fSDimitry Andric llvm::Value *DpRC = Builder.CreateFAdd(RHSi, RC); // tmp=d+rc 10095f757f3fSDimitry Andric 10107a6dacacSDimitry Andric llvm::Value *T7 = Builder.CreateFMul(LHSr, CdD); // ar 10115f757f3fSDimitry Andric llvm::Value *T8 = Builder.CreateFAdd(T7, LHSi); // ar+b 10125f757f3fSDimitry Andric llvm::Value *DSTFr = Builder.CreateFDiv(T8, DpRC); // (ar+b)/tmp 10135f757f3fSDimitry Andric 10145f757f3fSDimitry Andric llvm::Value *T9 = Builder.CreateFMul(LHSi, CdD); // br 10155f757f3fSDimitry Andric llvm::Value *T10 = Builder.CreateFSub(T9, LHSr); // br-a 10165f757f3fSDimitry Andric llvm::Value *DSTFi = Builder.CreateFDiv(T10, DpRC); // (br-a)/tmp 10175f757f3fSDimitry Andric Builder.CreateBr(ContBB); 10185f757f3fSDimitry Andric 10195f757f3fSDimitry Andric // Phi together the computation paths. 10205f757f3fSDimitry Andric CGF.EmitBlock(ContBB); 10215f757f3fSDimitry Andric llvm::PHINode *VALr = Builder.CreatePHI(DSTTr->getType(), 2); 10225f757f3fSDimitry Andric VALr->addIncoming(DSTTr, TrueBB); 10235f757f3fSDimitry Andric VALr->addIncoming(DSTFr, FalseBB); 10245f757f3fSDimitry Andric llvm::PHINode *VALi = Builder.CreatePHI(DSTTi->getType(), 2); 10255f757f3fSDimitry Andric VALi->addIncoming(DSTTi, TrueBB); 10265f757f3fSDimitry Andric VALi->addIncoming(DSTFi, FalseBB); 10275f757f3fSDimitry Andric return ComplexPairTy(VALr, VALi); 10285f757f3fSDimitry Andric } 10295f757f3fSDimitry Andric 10300b57cec5SDimitry Andric // See C11 Annex G.5.1 for the semantics of multiplicative operators on complex 10310b57cec5SDimitry Andric // typed values. 10320b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { 10330b57cec5SDimitry Andric llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second; 10340b57cec5SDimitry Andric llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second; 10350b57cec5SDimitry Andric llvm::Value *DSTr, *DSTi; 10360b57cec5SDimitry Andric if (LHSr->getType()->isFloatingPointTy()) { 10375f757f3fSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures); 10385f757f3fSDimitry Andric if (!RHSi) { 10395f757f3fSDimitry Andric assert(LHSi && "Can have at most one non-complex operand!"); 10405f757f3fSDimitry Andric 10415f757f3fSDimitry Andric DSTr = Builder.CreateFDiv(LHSr, RHSr); 10425f757f3fSDimitry Andric DSTi = Builder.CreateFDiv(LHSi, RHSr); 10435f757f3fSDimitry Andric return ComplexPairTy(DSTr, DSTi); 10445f757f3fSDimitry Andric } 10455f757f3fSDimitry Andric llvm::Value *OrigLHSi = LHSi; 10465f757f3fSDimitry Andric if (!LHSi) 10475f757f3fSDimitry Andric LHSi = llvm::Constant::getNullValue(RHSi->getType()); 1048*0fca6ea1SDimitry Andric if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Improved || 1049*0fca6ea1SDimitry Andric (Op.FPFeatures.getComplexRange() == LangOptions::CX_Promoted && 1050*0fca6ea1SDimitry Andric !FPHasBeenPromoted)) 10515f757f3fSDimitry Andric return EmitRangeReductionDiv(LHSr, LHSi, RHSr, RHSi); 1052*0fca6ea1SDimitry Andric else if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Basic || 1053*0fca6ea1SDimitry Andric Op.FPFeatures.getComplexRange() == LangOptions::CX_Promoted) 10545f757f3fSDimitry Andric return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi); 10557a6dacacSDimitry Andric // '-ffast-math' is used in the command line but followed by an 1056*0fca6ea1SDimitry Andric // '-fno-cx-limited-range' or '-fcomplex-arithmetic=full'. 1057*0fca6ea1SDimitry Andric else if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Full) { 10585f757f3fSDimitry Andric LHSi = OrigLHSi; 10590b57cec5SDimitry Andric // If we have a complex operand on the RHS and FastMath is not allowed, we 10600b57cec5SDimitry Andric // delegate to a libcall to handle all of the complexities and minimize 10610b57cec5SDimitry Andric // underflow/overflow cases. When FastMath is allowed we construct the 10620b57cec5SDimitry Andric // divide inline using the same algorithm as for integer operands. 10630b57cec5SDimitry Andric BinOpInfo LibCallOp = Op; 10640b57cec5SDimitry Andric // If LHS was a real, supply a null imaginary part. 10650b57cec5SDimitry Andric if (!LHSi) 10660b57cec5SDimitry Andric LibCallOp.LHS.second = llvm::Constant::getNullValue(LHSr->getType()); 10670b57cec5SDimitry Andric 10680b57cec5SDimitry Andric switch (LHSr->getType()->getTypeID()) { 10690b57cec5SDimitry Andric default: 10700b57cec5SDimitry Andric llvm_unreachable("Unsupported floating point type!"); 10710b57cec5SDimitry Andric case llvm::Type::HalfTyID: 10720b57cec5SDimitry Andric return EmitComplexBinOpLibCall("__divhc3", LibCallOp); 10730b57cec5SDimitry Andric case llvm::Type::FloatTyID: 10740b57cec5SDimitry Andric return EmitComplexBinOpLibCall("__divsc3", LibCallOp); 10750b57cec5SDimitry Andric case llvm::Type::DoubleTyID: 10760b57cec5SDimitry Andric return EmitComplexBinOpLibCall("__divdc3", LibCallOp); 10770b57cec5SDimitry Andric case llvm::Type::PPC_FP128TyID: 10780b57cec5SDimitry Andric return EmitComplexBinOpLibCall("__divtc3", LibCallOp); 10790b57cec5SDimitry Andric case llvm::Type::X86_FP80TyID: 10800b57cec5SDimitry Andric return EmitComplexBinOpLibCall("__divxc3", LibCallOp); 10810b57cec5SDimitry Andric case llvm::Type::FP128TyID: 10820b57cec5SDimitry Andric return EmitComplexBinOpLibCall("__divtc3", LibCallOp); 10830b57cec5SDimitry Andric } 10840b57cec5SDimitry Andric } else { 10855f757f3fSDimitry Andric return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi); 10860b57cec5SDimitry Andric } 10870b57cec5SDimitry Andric } else { 10880b57cec5SDimitry Andric assert(Op.LHS.second && Op.RHS.second && 10890b57cec5SDimitry Andric "Both operands of integer complex operators must be complex!"); 10900b57cec5SDimitry Andric // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) 10910b57cec5SDimitry Andric llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr); // a*c 10920b57cec5SDimitry Andric llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi); // b*d 10930b57cec5SDimitry Andric llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2); // ac+bd 10940b57cec5SDimitry Andric 10950b57cec5SDimitry Andric llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr); // c*c 10960b57cec5SDimitry Andric llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi); // d*d 10970b57cec5SDimitry Andric llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5); // cc+dd 10980b57cec5SDimitry Andric 10990b57cec5SDimitry Andric llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr); // b*c 11000b57cec5SDimitry Andric llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi); // a*d 11010b57cec5SDimitry Andric llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8); // bc-ad 11020b57cec5SDimitry Andric 11030b57cec5SDimitry Andric if (Op.Ty->castAs<ComplexType>()->getElementType()->isUnsignedIntegerType()) { 11040b57cec5SDimitry Andric DSTr = Builder.CreateUDiv(Tmp3, Tmp6); 11050b57cec5SDimitry Andric DSTi = Builder.CreateUDiv(Tmp9, Tmp6); 11060b57cec5SDimitry Andric } else { 11070b57cec5SDimitry Andric DSTr = Builder.CreateSDiv(Tmp3, Tmp6); 11080b57cec5SDimitry Andric DSTi = Builder.CreateSDiv(Tmp9, Tmp6); 11090b57cec5SDimitry Andric } 11100b57cec5SDimitry Andric } 11110b57cec5SDimitry Andric 11120b57cec5SDimitry Andric return ComplexPairTy(DSTr, DSTi); 11130b57cec5SDimitry Andric } 11140b57cec5SDimitry Andric 1115bdd1243dSDimitry Andric ComplexPairTy CodeGenFunction::EmitUnPromotedValue(ComplexPairTy result, 1116bdd1243dSDimitry Andric QualType UnPromotionType) { 1117bdd1243dSDimitry Andric llvm::Type *ComplexElementTy = 1118bdd1243dSDimitry Andric ConvertType(UnPromotionType->castAs<ComplexType>()->getElementType()); 1119bdd1243dSDimitry Andric if (result.first) 1120bdd1243dSDimitry Andric result.first = 1121bdd1243dSDimitry Andric Builder.CreateFPTrunc(result.first, ComplexElementTy, "unpromotion"); 1122bdd1243dSDimitry Andric if (result.second) 1123bdd1243dSDimitry Andric result.second = 1124bdd1243dSDimitry Andric Builder.CreateFPTrunc(result.second, ComplexElementTy, "unpromotion"); 1125bdd1243dSDimitry Andric return result; 1126bdd1243dSDimitry Andric } 1127bdd1243dSDimitry Andric 1128bdd1243dSDimitry Andric ComplexPairTy CodeGenFunction::EmitPromotedValue(ComplexPairTy result, 1129bdd1243dSDimitry Andric QualType PromotionType) { 1130bdd1243dSDimitry Andric llvm::Type *ComplexElementTy = 1131bdd1243dSDimitry Andric ConvertType(PromotionType->castAs<ComplexType>()->getElementType()); 1132bdd1243dSDimitry Andric if (result.first) 1133bdd1243dSDimitry Andric result.first = Builder.CreateFPExt(result.first, ComplexElementTy, "ext"); 1134bdd1243dSDimitry Andric if (result.second) 1135bdd1243dSDimitry Andric result.second = Builder.CreateFPExt(result.second, ComplexElementTy, "ext"); 1136bdd1243dSDimitry Andric 1137bdd1243dSDimitry Andric return result; 1138bdd1243dSDimitry Andric } 1139bdd1243dSDimitry Andric 1140bdd1243dSDimitry Andric ComplexPairTy ComplexExprEmitter::EmitPromoted(const Expr *E, 1141bdd1243dSDimitry Andric QualType PromotionType) { 1142bdd1243dSDimitry Andric E = E->IgnoreParens(); 1143bdd1243dSDimitry Andric if (auto BO = dyn_cast<BinaryOperator>(E)) { 1144bdd1243dSDimitry Andric switch (BO->getOpcode()) { 1145bdd1243dSDimitry Andric #define HANDLE_BINOP(OP) \ 1146bdd1243dSDimitry Andric case BO_##OP: \ 1147bdd1243dSDimitry Andric return EmitBin##OP(EmitBinOps(BO, PromotionType)); 1148bdd1243dSDimitry Andric HANDLE_BINOP(Add) 1149bdd1243dSDimitry Andric HANDLE_BINOP(Sub) 1150bdd1243dSDimitry Andric HANDLE_BINOP(Mul) 1151bdd1243dSDimitry Andric HANDLE_BINOP(Div) 1152bdd1243dSDimitry Andric #undef HANDLE_BINOP 1153bdd1243dSDimitry Andric default: 1154bdd1243dSDimitry Andric break; 1155bdd1243dSDimitry Andric } 1156bdd1243dSDimitry Andric } else if (auto UO = dyn_cast<UnaryOperator>(E)) { 1157bdd1243dSDimitry Andric switch (UO->getOpcode()) { 1158bdd1243dSDimitry Andric case UO_Minus: 1159bdd1243dSDimitry Andric return VisitMinus(UO, PromotionType); 1160bdd1243dSDimitry Andric case UO_Plus: 1161bdd1243dSDimitry Andric return VisitPlus(UO, PromotionType); 1162bdd1243dSDimitry Andric default: 1163bdd1243dSDimitry Andric break; 1164bdd1243dSDimitry Andric } 1165bdd1243dSDimitry Andric } 1166bdd1243dSDimitry Andric auto result = Visit(const_cast<Expr *>(E)); 1167bdd1243dSDimitry Andric if (!PromotionType.isNull()) 1168bdd1243dSDimitry Andric return CGF.EmitPromotedValue(result, PromotionType); 1169bdd1243dSDimitry Andric else 1170bdd1243dSDimitry Andric return result; 1171bdd1243dSDimitry Andric } 1172bdd1243dSDimitry Andric 1173bdd1243dSDimitry Andric ComplexPairTy CodeGenFunction::EmitPromotedComplexExpr(const Expr *E, 1174bdd1243dSDimitry Andric QualType DstTy) { 1175bdd1243dSDimitry Andric return ComplexExprEmitter(*this).EmitPromoted(E, DstTy); 1176bdd1243dSDimitry Andric } 1177bdd1243dSDimitry Andric 1178bdd1243dSDimitry Andric ComplexPairTy 1179bdd1243dSDimitry Andric ComplexExprEmitter::EmitPromotedComplexOperand(const Expr *E, 1180bdd1243dSDimitry Andric QualType OverallPromotionType) { 1181bdd1243dSDimitry Andric if (E->getType()->isAnyComplexType()) { 1182bdd1243dSDimitry Andric if (!OverallPromotionType.isNull()) 1183bdd1243dSDimitry Andric return CGF.EmitPromotedComplexExpr(E, OverallPromotionType); 1184bdd1243dSDimitry Andric else 1185bdd1243dSDimitry Andric return Visit(const_cast<Expr *>(E)); 1186bdd1243dSDimitry Andric } else { 1187bdd1243dSDimitry Andric if (!OverallPromotionType.isNull()) { 1188bdd1243dSDimitry Andric QualType ComplexElementTy = 1189bdd1243dSDimitry Andric OverallPromotionType->castAs<ComplexType>()->getElementType(); 1190bdd1243dSDimitry Andric return ComplexPairTy(CGF.EmitPromotedScalarExpr(E, ComplexElementTy), 1191bdd1243dSDimitry Andric nullptr); 1192bdd1243dSDimitry Andric } else { 1193bdd1243dSDimitry Andric return ComplexPairTy(CGF.EmitScalarExpr(E), nullptr); 1194bdd1243dSDimitry Andric } 1195bdd1243dSDimitry Andric } 1196bdd1243dSDimitry Andric } 1197bdd1243dSDimitry Andric 11980b57cec5SDimitry Andric ComplexExprEmitter::BinOpInfo 1199bdd1243dSDimitry Andric ComplexExprEmitter::EmitBinOps(const BinaryOperator *E, 1200bdd1243dSDimitry Andric QualType PromotionType) { 12010b57cec5SDimitry Andric TestAndClearIgnoreReal(); 12020b57cec5SDimitry Andric TestAndClearIgnoreImag(); 12030b57cec5SDimitry Andric BinOpInfo Ops; 12040b57cec5SDimitry Andric 1205bdd1243dSDimitry Andric Ops.LHS = EmitPromotedComplexOperand(E->getLHS(), PromotionType); 1206bdd1243dSDimitry Andric Ops.RHS = EmitPromotedComplexOperand(E->getRHS(), PromotionType); 1207bdd1243dSDimitry Andric if (!PromotionType.isNull()) 1208bdd1243dSDimitry Andric Ops.Ty = PromotionType; 1209bdd1243dSDimitry Andric else 12100b57cec5SDimitry Andric Ops.Ty = E->getType(); 1211bdd1243dSDimitry Andric Ops.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts()); 12120b57cec5SDimitry Andric return Ops; 12130b57cec5SDimitry Andric } 12140b57cec5SDimitry Andric 12150b57cec5SDimitry Andric 12160b57cec5SDimitry Andric LValue ComplexExprEmitter:: 12170b57cec5SDimitry Andric EmitCompoundAssignLValue(const CompoundAssignOperator *E, 12180b57cec5SDimitry Andric ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&), 12190b57cec5SDimitry Andric RValue &Val) { 12200b57cec5SDimitry Andric TestAndClearIgnoreReal(); 12210b57cec5SDimitry Andric TestAndClearIgnoreImag(); 12220b57cec5SDimitry Andric QualType LHSTy = E->getLHS()->getType(); 12230b57cec5SDimitry Andric if (const AtomicType *AT = LHSTy->getAs<AtomicType>()) 12240b57cec5SDimitry Andric LHSTy = AT->getValueType(); 12250b57cec5SDimitry Andric 12260b57cec5SDimitry Andric BinOpInfo OpInfo; 1227bdd1243dSDimitry Andric OpInfo.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts()); 1228bdd1243dSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures); 12290b57cec5SDimitry Andric 12300b57cec5SDimitry Andric // Load the RHS and LHS operands. 12310b57cec5SDimitry Andric // __block variables need to have the rhs evaluated first, plus this should 12320b57cec5SDimitry Andric // improve codegen a little. 1233bdd1243dSDimitry Andric QualType PromotionTypeCR; 1234*0fca6ea1SDimitry Andric PromotionTypeCR = getPromotionType(E->getStoredFPFeaturesOrDefault(), 1235*0fca6ea1SDimitry Andric E->getComputationResultType()); 1236bdd1243dSDimitry Andric if (PromotionTypeCR.isNull()) 1237bdd1243dSDimitry Andric PromotionTypeCR = E->getComputationResultType(); 1238bdd1243dSDimitry Andric OpInfo.Ty = PromotionTypeCR; 1239bdd1243dSDimitry Andric QualType ComplexElementTy = 1240bdd1243dSDimitry Andric OpInfo.Ty->castAs<ComplexType>()->getElementType(); 1241*0fca6ea1SDimitry Andric QualType PromotionTypeRHS = getPromotionType( 1242*0fca6ea1SDimitry Andric E->getStoredFPFeaturesOrDefault(), E->getRHS()->getType()); 12430b57cec5SDimitry Andric 12440b57cec5SDimitry Andric // The RHS should have been converted to the computation type. 12450b57cec5SDimitry Andric if (E->getRHS()->getType()->isRealFloatingType()) { 1246bdd1243dSDimitry Andric if (!PromotionTypeRHS.isNull()) 1247bdd1243dSDimitry Andric OpInfo.RHS = ComplexPairTy( 1248bdd1243dSDimitry Andric CGF.EmitPromotedScalarExpr(E->getRHS(), PromotionTypeRHS), nullptr); 1249bdd1243dSDimitry Andric else { 1250bdd1243dSDimitry Andric assert(CGF.getContext().hasSameUnqualifiedType(ComplexElementTy, 1251bdd1243dSDimitry Andric E->getRHS()->getType())); 1252bdd1243dSDimitry Andric 12530b57cec5SDimitry Andric OpInfo.RHS = ComplexPairTy(CGF.EmitScalarExpr(E->getRHS()), nullptr); 1254bdd1243dSDimitry Andric } 12550b57cec5SDimitry Andric } else { 1256bdd1243dSDimitry Andric if (!PromotionTypeRHS.isNull()) { 1257bdd1243dSDimitry Andric OpInfo.RHS = ComplexPairTy( 1258bdd1243dSDimitry Andric CGF.EmitPromotedComplexExpr(E->getRHS(), PromotionTypeRHS)); 1259bdd1243dSDimitry Andric } else { 1260bdd1243dSDimitry Andric assert(CGF.getContext().hasSameUnqualifiedType(OpInfo.Ty, 1261bdd1243dSDimitry Andric E->getRHS()->getType())); 12620b57cec5SDimitry Andric OpInfo.RHS = Visit(E->getRHS()); 12630b57cec5SDimitry Andric } 1264bdd1243dSDimitry Andric } 12650b57cec5SDimitry Andric 12660b57cec5SDimitry Andric LValue LHS = CGF.EmitLValue(E->getLHS()); 12670b57cec5SDimitry Andric 12680b57cec5SDimitry Andric // Load from the l-value and convert it. 12690b57cec5SDimitry Andric SourceLocation Loc = E->getExprLoc(); 1270*0fca6ea1SDimitry Andric QualType PromotionTypeLHS = getPromotionType( 1271*0fca6ea1SDimitry Andric E->getStoredFPFeaturesOrDefault(), E->getComputationLHSType()); 12720b57cec5SDimitry Andric if (LHSTy->isAnyComplexType()) { 12730b57cec5SDimitry Andric ComplexPairTy LHSVal = EmitLoadOfLValue(LHS, Loc); 1274bdd1243dSDimitry Andric if (!PromotionTypeLHS.isNull()) 1275bdd1243dSDimitry Andric OpInfo.LHS = 1276bdd1243dSDimitry Andric EmitComplexToComplexCast(LHSVal, LHSTy, PromotionTypeLHS, Loc); 1277bdd1243dSDimitry Andric else 12780b57cec5SDimitry Andric OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc); 12790b57cec5SDimitry Andric } else { 12800b57cec5SDimitry Andric llvm::Value *LHSVal = CGF.EmitLoadOfScalar(LHS, Loc); 12810b57cec5SDimitry Andric // For floating point real operands we can directly pass the scalar form 12820b57cec5SDimitry Andric // to the binary operator emission and potentially get more efficient code. 12830b57cec5SDimitry Andric if (LHSTy->isRealFloatingType()) { 1284bdd1243dSDimitry Andric QualType PromotedComplexElementTy; 1285bdd1243dSDimitry Andric if (!PromotionTypeLHS.isNull()) { 1286bdd1243dSDimitry Andric PromotedComplexElementTy = 1287bdd1243dSDimitry Andric cast<ComplexType>(PromotionTypeLHS)->getElementType(); 1288bdd1243dSDimitry Andric if (!CGF.getContext().hasSameUnqualifiedType(PromotedComplexElementTy, 1289bdd1243dSDimitry Andric PromotionTypeLHS)) 1290bdd1243dSDimitry Andric LHSVal = CGF.EmitScalarConversion(LHSVal, LHSTy, 1291bdd1243dSDimitry Andric PromotedComplexElementTy, Loc); 1292bdd1243dSDimitry Andric } else { 12930b57cec5SDimitry Andric if (!CGF.getContext().hasSameUnqualifiedType(ComplexElementTy, LHSTy)) 1294bdd1243dSDimitry Andric LHSVal = 1295bdd1243dSDimitry Andric CGF.EmitScalarConversion(LHSVal, LHSTy, ComplexElementTy, Loc); 1296bdd1243dSDimitry Andric } 12970b57cec5SDimitry Andric OpInfo.LHS = ComplexPairTy(LHSVal, nullptr); 12980b57cec5SDimitry Andric } else { 12990b57cec5SDimitry Andric OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc); 13000b57cec5SDimitry Andric } 13010b57cec5SDimitry Andric } 13020b57cec5SDimitry Andric 13030b57cec5SDimitry Andric // Expand the binary operator. 13040b57cec5SDimitry Andric ComplexPairTy Result = (this->*Func)(OpInfo); 13050b57cec5SDimitry Andric 13060b57cec5SDimitry Andric // Truncate the result and store it into the LHS lvalue. 13070b57cec5SDimitry Andric if (LHSTy->isAnyComplexType()) { 13080b57cec5SDimitry Andric ComplexPairTy ResVal = 13090b57cec5SDimitry Andric EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy, Loc); 13100b57cec5SDimitry Andric EmitStoreOfComplex(ResVal, LHS, /*isInit*/ false); 13110b57cec5SDimitry Andric Val = RValue::getComplex(ResVal); 13120b57cec5SDimitry Andric } else { 13130b57cec5SDimitry Andric llvm::Value *ResVal = 13140b57cec5SDimitry Andric CGF.EmitComplexToScalarConversion(Result, OpInfo.Ty, LHSTy, Loc); 13150b57cec5SDimitry Andric CGF.EmitStoreOfScalar(ResVal, LHS, /*isInit*/ false); 13160b57cec5SDimitry Andric Val = RValue::get(ResVal); 13170b57cec5SDimitry Andric } 13180b57cec5SDimitry Andric 13190b57cec5SDimitry Andric return LHS; 13200b57cec5SDimitry Andric } 13210b57cec5SDimitry Andric 13220b57cec5SDimitry Andric // Compound assignments. 13230b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter:: 13240b57cec5SDimitry Andric EmitCompoundAssign(const CompoundAssignOperator *E, 13250b57cec5SDimitry Andric ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){ 13260b57cec5SDimitry Andric RValue Val; 13270b57cec5SDimitry Andric LValue LV = EmitCompoundAssignLValue(E, Func, Val); 13280b57cec5SDimitry Andric 13290b57cec5SDimitry Andric // The result of an assignment in C is the assigned r-value. 13300b57cec5SDimitry Andric if (!CGF.getLangOpts().CPlusPlus) 13310b57cec5SDimitry Andric return Val.getComplexVal(); 13320b57cec5SDimitry Andric 13330b57cec5SDimitry Andric // If the lvalue is non-volatile, return the computed value of the assignment. 13340b57cec5SDimitry Andric if (!LV.isVolatileQualified()) 13350b57cec5SDimitry Andric return Val.getComplexVal(); 13360b57cec5SDimitry Andric 13370b57cec5SDimitry Andric return EmitLoadOfLValue(LV, E->getExprLoc()); 13380b57cec5SDimitry Andric } 13390b57cec5SDimitry Andric 13400b57cec5SDimitry Andric LValue ComplexExprEmitter::EmitBinAssignLValue(const BinaryOperator *E, 13410b57cec5SDimitry Andric ComplexPairTy &Val) { 13420b57cec5SDimitry Andric assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(), 13430b57cec5SDimitry Andric E->getRHS()->getType()) && 13440b57cec5SDimitry Andric "Invalid assignment"); 13450b57cec5SDimitry Andric TestAndClearIgnoreReal(); 13460b57cec5SDimitry Andric TestAndClearIgnoreImag(); 13470b57cec5SDimitry Andric 13480b57cec5SDimitry Andric // Emit the RHS. __block variables need the RHS evaluated first. 13490b57cec5SDimitry Andric Val = Visit(E->getRHS()); 13500b57cec5SDimitry Andric 13510b57cec5SDimitry Andric // Compute the address to store into. 13520b57cec5SDimitry Andric LValue LHS = CGF.EmitLValue(E->getLHS()); 13530b57cec5SDimitry Andric 13540b57cec5SDimitry Andric // Store the result value into the LHS lvalue. 13550b57cec5SDimitry Andric EmitStoreOfComplex(Val, LHS, /*isInit*/ false); 13560b57cec5SDimitry Andric 13570b57cec5SDimitry Andric return LHS; 13580b57cec5SDimitry Andric } 13590b57cec5SDimitry Andric 13600b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) { 13610b57cec5SDimitry Andric ComplexPairTy Val; 13620b57cec5SDimitry Andric LValue LV = EmitBinAssignLValue(E, Val); 13630b57cec5SDimitry Andric 13640b57cec5SDimitry Andric // The result of an assignment in C is the assigned r-value. 13650b57cec5SDimitry Andric if (!CGF.getLangOpts().CPlusPlus) 13660b57cec5SDimitry Andric return Val; 13670b57cec5SDimitry Andric 13680b57cec5SDimitry Andric // If the lvalue is non-volatile, return the computed value of the assignment. 13690b57cec5SDimitry Andric if (!LV.isVolatileQualified()) 13700b57cec5SDimitry Andric return Val; 13710b57cec5SDimitry Andric 13720b57cec5SDimitry Andric return EmitLoadOfLValue(LV, E->getExprLoc()); 13730b57cec5SDimitry Andric } 13740b57cec5SDimitry Andric 13750b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) { 13760b57cec5SDimitry Andric CGF.EmitIgnoredExpr(E->getLHS()); 13770b57cec5SDimitry Andric return Visit(E->getRHS()); 13780b57cec5SDimitry Andric } 13790b57cec5SDimitry Andric 13800b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter:: 13810b57cec5SDimitry Andric VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { 13820b57cec5SDimitry Andric TestAndClearIgnoreReal(); 13830b57cec5SDimitry Andric TestAndClearIgnoreImag(); 13840b57cec5SDimitry Andric llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true"); 13850b57cec5SDimitry Andric llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false"); 13860b57cec5SDimitry Andric llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end"); 13870b57cec5SDimitry Andric 13880b57cec5SDimitry Andric // Bind the common expression if necessary. 13890b57cec5SDimitry Andric CodeGenFunction::OpaqueValueMapping binding(CGF, E); 13900b57cec5SDimitry Andric 13910b57cec5SDimitry Andric 13920b57cec5SDimitry Andric CodeGenFunction::ConditionalEvaluation eval(CGF); 13930b57cec5SDimitry Andric CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock, 13940b57cec5SDimitry Andric CGF.getProfileCount(E)); 13950b57cec5SDimitry Andric 13960b57cec5SDimitry Andric eval.begin(CGF); 13970b57cec5SDimitry Andric CGF.EmitBlock(LHSBlock); 1398*0fca6ea1SDimitry Andric if (llvm::EnableSingleByteCoverage) 1399*0fca6ea1SDimitry Andric CGF.incrementProfileCounter(E->getTrueExpr()); 1400*0fca6ea1SDimitry Andric else 14010b57cec5SDimitry Andric CGF.incrementProfileCounter(E); 1402*0fca6ea1SDimitry Andric 14030b57cec5SDimitry Andric ComplexPairTy LHS = Visit(E->getTrueExpr()); 14040b57cec5SDimitry Andric LHSBlock = Builder.GetInsertBlock(); 14050b57cec5SDimitry Andric CGF.EmitBranch(ContBlock); 14060b57cec5SDimitry Andric eval.end(CGF); 14070b57cec5SDimitry Andric 14080b57cec5SDimitry Andric eval.begin(CGF); 14090b57cec5SDimitry Andric CGF.EmitBlock(RHSBlock); 1410*0fca6ea1SDimitry Andric if (llvm::EnableSingleByteCoverage) 1411*0fca6ea1SDimitry Andric CGF.incrementProfileCounter(E->getFalseExpr()); 14120b57cec5SDimitry Andric ComplexPairTy RHS = Visit(E->getFalseExpr()); 14130b57cec5SDimitry Andric RHSBlock = Builder.GetInsertBlock(); 14140b57cec5SDimitry Andric CGF.EmitBlock(ContBlock); 1415*0fca6ea1SDimitry Andric if (llvm::EnableSingleByteCoverage) 1416*0fca6ea1SDimitry Andric CGF.incrementProfileCounter(E); 14170b57cec5SDimitry Andric eval.end(CGF); 14180b57cec5SDimitry Andric 14190b57cec5SDimitry Andric // Create a PHI node for the real part. 14200b57cec5SDimitry Andric llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), 2, "cond.r"); 14210b57cec5SDimitry Andric RealPN->addIncoming(LHS.first, LHSBlock); 14220b57cec5SDimitry Andric RealPN->addIncoming(RHS.first, RHSBlock); 14230b57cec5SDimitry Andric 14240b57cec5SDimitry Andric // Create a PHI node for the imaginary part. 14250b57cec5SDimitry Andric llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), 2, "cond.i"); 14260b57cec5SDimitry Andric ImagPN->addIncoming(LHS.second, LHSBlock); 14270b57cec5SDimitry Andric ImagPN->addIncoming(RHS.second, RHSBlock); 14280b57cec5SDimitry Andric 14290b57cec5SDimitry Andric return ComplexPairTy(RealPN, ImagPN); 14300b57cec5SDimitry Andric } 14310b57cec5SDimitry Andric 14320b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) { 14330b57cec5SDimitry Andric return Visit(E->getChosenSubExpr()); 14340b57cec5SDimitry Andric } 14350b57cec5SDimitry Andric 14360b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) { 14370b57cec5SDimitry Andric bool Ignore = TestAndClearIgnoreReal(); 14380b57cec5SDimitry Andric (void)Ignore; 14390b57cec5SDimitry Andric assert (Ignore == false && "init list ignored"); 14400b57cec5SDimitry Andric Ignore = TestAndClearIgnoreImag(); 14410b57cec5SDimitry Andric (void)Ignore; 14420b57cec5SDimitry Andric assert (Ignore == false && "init list ignored"); 14430b57cec5SDimitry Andric 14440b57cec5SDimitry Andric if (E->getNumInits() == 2) { 14450b57cec5SDimitry Andric llvm::Value *Real = CGF.EmitScalarExpr(E->getInit(0)); 14460b57cec5SDimitry Andric llvm::Value *Imag = CGF.EmitScalarExpr(E->getInit(1)); 14470b57cec5SDimitry Andric return ComplexPairTy(Real, Imag); 14480b57cec5SDimitry Andric } else if (E->getNumInits() == 1) { 14490b57cec5SDimitry Andric return Visit(E->getInit(0)); 14500b57cec5SDimitry Andric } 14510b57cec5SDimitry Andric 14520b57cec5SDimitry Andric // Empty init list initializes to null 14530b57cec5SDimitry Andric assert(E->getNumInits() == 0 && "Unexpected number of inits"); 14540b57cec5SDimitry Andric QualType Ty = E->getType()->castAs<ComplexType>()->getElementType(); 14550b57cec5SDimitry Andric llvm::Type* LTy = CGF.ConvertType(Ty); 14560b57cec5SDimitry Andric llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy); 14570b57cec5SDimitry Andric return ComplexPairTy(zeroConstant, zeroConstant); 14580b57cec5SDimitry Andric } 14590b57cec5SDimitry Andric 14600b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) { 14610b57cec5SDimitry Andric Address ArgValue = Address::invalid(); 1462*0fca6ea1SDimitry Andric RValue RV = CGF.EmitVAArg(E, ArgValue); 14630b57cec5SDimitry Andric 1464*0fca6ea1SDimitry Andric if (!ArgValue.isValid()) { 14650b57cec5SDimitry Andric CGF.ErrorUnsupported(E, "complex va_arg expression"); 14660b57cec5SDimitry Andric llvm::Type *EltTy = 14670b57cec5SDimitry Andric CGF.ConvertType(E->getType()->castAs<ComplexType>()->getElementType()); 14680b57cec5SDimitry Andric llvm::Value *U = llvm::UndefValue::get(EltTy); 14690b57cec5SDimitry Andric return ComplexPairTy(U, U); 14700b57cec5SDimitry Andric } 14710b57cec5SDimitry Andric 1472*0fca6ea1SDimitry Andric return RV.getComplexVal(); 14730b57cec5SDimitry Andric } 14740b57cec5SDimitry Andric 14750b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 14760b57cec5SDimitry Andric // Entry Point into this File 14770b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 14780b57cec5SDimitry Andric 14790b57cec5SDimitry Andric /// EmitComplexExpr - Emit the computation of the specified expression of 14800b57cec5SDimitry Andric /// complex type, ignoring the result. 14810b57cec5SDimitry Andric ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E, bool IgnoreReal, 14820b57cec5SDimitry Andric bool IgnoreImag) { 14830b57cec5SDimitry Andric assert(E && getComplexType(E->getType()) && 14840b57cec5SDimitry Andric "Invalid complex expression to emit"); 14850b57cec5SDimitry Andric 14860b57cec5SDimitry Andric return ComplexExprEmitter(*this, IgnoreReal, IgnoreImag) 14870b57cec5SDimitry Andric .Visit(const_cast<Expr *>(E)); 14880b57cec5SDimitry Andric } 14890b57cec5SDimitry Andric 14900b57cec5SDimitry Andric void CodeGenFunction::EmitComplexExprIntoLValue(const Expr *E, LValue dest, 14910b57cec5SDimitry Andric bool isInit) { 14920b57cec5SDimitry Andric assert(E && getComplexType(E->getType()) && 14930b57cec5SDimitry Andric "Invalid complex expression to emit"); 14940b57cec5SDimitry Andric ComplexExprEmitter Emitter(*this); 14950b57cec5SDimitry Andric ComplexPairTy Val = Emitter.Visit(const_cast<Expr*>(E)); 14960b57cec5SDimitry Andric Emitter.EmitStoreOfComplex(Val, dest, isInit); 14970b57cec5SDimitry Andric } 14980b57cec5SDimitry Andric 14990b57cec5SDimitry Andric /// EmitStoreOfComplex - Store a complex number into the specified l-value. 15000b57cec5SDimitry Andric void CodeGenFunction::EmitStoreOfComplex(ComplexPairTy V, LValue dest, 15010b57cec5SDimitry Andric bool isInit) { 15020b57cec5SDimitry Andric ComplexExprEmitter(*this).EmitStoreOfComplex(V, dest, isInit); 15030b57cec5SDimitry Andric } 15040b57cec5SDimitry Andric 15050b57cec5SDimitry Andric /// EmitLoadOfComplex - Load a complex number from the specified address. 15060b57cec5SDimitry Andric ComplexPairTy CodeGenFunction::EmitLoadOfComplex(LValue src, 15070b57cec5SDimitry Andric SourceLocation loc) { 15080b57cec5SDimitry Andric return ComplexExprEmitter(*this).EmitLoadOfLValue(src, loc); 15090b57cec5SDimitry Andric } 15100b57cec5SDimitry Andric 15110b57cec5SDimitry Andric LValue CodeGenFunction::EmitComplexAssignmentLValue(const BinaryOperator *E) { 15120b57cec5SDimitry Andric assert(E->getOpcode() == BO_Assign); 15130b57cec5SDimitry Andric ComplexPairTy Val; // ignored 1514480093f4SDimitry Andric LValue LVal = ComplexExprEmitter(*this).EmitBinAssignLValue(E, Val); 1515480093f4SDimitry Andric if (getLangOpts().OpenMP) 1516480093f4SDimitry Andric CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(*this, 1517480093f4SDimitry Andric E->getLHS()); 1518480093f4SDimitry Andric return LVal; 15190b57cec5SDimitry Andric } 15200b57cec5SDimitry Andric 15210b57cec5SDimitry Andric typedef ComplexPairTy (ComplexExprEmitter::*CompoundFunc)( 15220b57cec5SDimitry Andric const ComplexExprEmitter::BinOpInfo &); 15230b57cec5SDimitry Andric 15240b57cec5SDimitry Andric static CompoundFunc getComplexOp(BinaryOperatorKind Op) { 15250b57cec5SDimitry Andric switch (Op) { 15260b57cec5SDimitry Andric case BO_MulAssign: return &ComplexExprEmitter::EmitBinMul; 15270b57cec5SDimitry Andric case BO_DivAssign: return &ComplexExprEmitter::EmitBinDiv; 15280b57cec5SDimitry Andric case BO_SubAssign: return &ComplexExprEmitter::EmitBinSub; 15290b57cec5SDimitry Andric case BO_AddAssign: return &ComplexExprEmitter::EmitBinAdd; 15300b57cec5SDimitry Andric default: 15310b57cec5SDimitry Andric llvm_unreachable("unexpected complex compound assignment"); 15320b57cec5SDimitry Andric } 15330b57cec5SDimitry Andric } 15340b57cec5SDimitry Andric 15350b57cec5SDimitry Andric LValue CodeGenFunction:: 15360b57cec5SDimitry Andric EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E) { 15370b57cec5SDimitry Andric CompoundFunc Op = getComplexOp(E->getOpcode()); 15380b57cec5SDimitry Andric RValue Val; 15390b57cec5SDimitry Andric return ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val); 15400b57cec5SDimitry Andric } 15410b57cec5SDimitry Andric 15420b57cec5SDimitry Andric LValue CodeGenFunction:: 15430b57cec5SDimitry Andric EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, 15440b57cec5SDimitry Andric llvm::Value *&Result) { 15450b57cec5SDimitry Andric CompoundFunc Op = getComplexOp(E->getOpcode()); 15460b57cec5SDimitry Andric RValue Val; 15470b57cec5SDimitry Andric LValue Ret = ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val); 15480b57cec5SDimitry Andric Result = Val.getScalarVal(); 15490b57cec5SDimitry Andric return Ret; 15500b57cec5SDimitry Andric } 1551