1*0b57cec5SDimitry Andric //===--- CGExprComplex.cpp - Emit LLVM Code for Complex Exprs -------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This contains code to emit Expr nodes with complex types as LLVM code. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13480093f4SDimitry Andric #include "CGOpenMPRuntime.h" 14*0b57cec5SDimitry Andric #include "CodeGenFunction.h" 15*0b57cec5SDimitry Andric #include "CodeGenModule.h" 165ffd83dbSDimitry Andric #include "ConstantEmitter.h" 17*0b57cec5SDimitry Andric #include "clang/AST/StmtVisitor.h" 18*0b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 19*0b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 20*0b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 21*0b57cec5SDimitry Andric #include "llvm/IR/MDBuilder.h" 22*0b57cec5SDimitry Andric #include "llvm/IR/Metadata.h" 23*0b57cec5SDimitry Andric #include <algorithm> 24*0b57cec5SDimitry Andric using namespace clang; 25*0b57cec5SDimitry Andric using namespace CodeGen; 26*0b57cec5SDimitry Andric 27*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 28*0b57cec5SDimitry Andric // Complex Expression Emitter 29*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 30*0b57cec5SDimitry Andric 31*0b57cec5SDimitry Andric typedef CodeGenFunction::ComplexPairTy ComplexPairTy; 32*0b57cec5SDimitry Andric 33*0b57cec5SDimitry Andric /// Return the complex type that we are meant to emit. 34*0b57cec5SDimitry Andric static const ComplexType *getComplexType(QualType type) { 35*0b57cec5SDimitry Andric type = type.getCanonicalType(); 36*0b57cec5SDimitry Andric if (const ComplexType *comp = dyn_cast<ComplexType>(type)) { 37*0b57cec5SDimitry Andric return comp; 38*0b57cec5SDimitry Andric } else { 39*0b57cec5SDimitry Andric return cast<ComplexType>(cast<AtomicType>(type)->getValueType()); 40*0b57cec5SDimitry Andric } 41*0b57cec5SDimitry Andric } 42*0b57cec5SDimitry Andric 43*0b57cec5SDimitry Andric namespace { 44*0b57cec5SDimitry Andric class ComplexExprEmitter 45*0b57cec5SDimitry Andric : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> { 46*0b57cec5SDimitry Andric CodeGenFunction &CGF; 47*0b57cec5SDimitry Andric CGBuilderTy &Builder; 48*0b57cec5SDimitry Andric bool IgnoreReal; 49*0b57cec5SDimitry Andric bool IgnoreImag; 50*0b57cec5SDimitry Andric public: 51*0b57cec5SDimitry Andric ComplexExprEmitter(CodeGenFunction &cgf, bool ir=false, bool ii=false) 52*0b57cec5SDimitry Andric : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii) { 53*0b57cec5SDimitry Andric } 54*0b57cec5SDimitry Andric 55*0b57cec5SDimitry Andric 56*0b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 57*0b57cec5SDimitry Andric // Utilities 58*0b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 59*0b57cec5SDimitry Andric 60*0b57cec5SDimitry Andric bool TestAndClearIgnoreReal() { 61*0b57cec5SDimitry Andric bool I = IgnoreReal; 62*0b57cec5SDimitry Andric IgnoreReal = false; 63*0b57cec5SDimitry Andric return I; 64*0b57cec5SDimitry Andric } 65*0b57cec5SDimitry Andric bool TestAndClearIgnoreImag() { 66*0b57cec5SDimitry Andric bool I = IgnoreImag; 67*0b57cec5SDimitry Andric IgnoreImag = false; 68*0b57cec5SDimitry Andric return I; 69*0b57cec5SDimitry Andric } 70*0b57cec5SDimitry Andric 71*0b57cec5SDimitry Andric /// EmitLoadOfLValue - Given an expression with complex type that represents a 72*0b57cec5SDimitry Andric /// value l-value, this method emits the address of the l-value, then loads 73*0b57cec5SDimitry Andric /// and returns the result. 74*0b57cec5SDimitry Andric ComplexPairTy EmitLoadOfLValue(const Expr *E) { 75*0b57cec5SDimitry Andric return EmitLoadOfLValue(CGF.EmitLValue(E), E->getExprLoc()); 76*0b57cec5SDimitry Andric } 77*0b57cec5SDimitry Andric 78*0b57cec5SDimitry Andric ComplexPairTy EmitLoadOfLValue(LValue LV, SourceLocation Loc); 79*0b57cec5SDimitry Andric 80*0b57cec5SDimitry Andric /// EmitStoreOfComplex - Store the specified real/imag parts into the 81*0b57cec5SDimitry Andric /// specified value pointer. 82*0b57cec5SDimitry Andric void EmitStoreOfComplex(ComplexPairTy Val, LValue LV, bool isInit); 83*0b57cec5SDimitry Andric 84*0b57cec5SDimitry Andric /// Emit a cast from complex value Val to DestType. 85*0b57cec5SDimitry Andric ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType, 86*0b57cec5SDimitry Andric QualType DestType, SourceLocation Loc); 87*0b57cec5SDimitry Andric /// Emit a cast from scalar value Val to DestType. 88*0b57cec5SDimitry Andric ComplexPairTy EmitScalarToComplexCast(llvm::Value *Val, QualType SrcType, 89*0b57cec5SDimitry Andric QualType DestType, SourceLocation Loc); 90*0b57cec5SDimitry Andric 91*0b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 92*0b57cec5SDimitry Andric // Visitor Methods 93*0b57cec5SDimitry Andric //===--------------------------------------------------------------------===// 94*0b57cec5SDimitry Andric 95*0b57cec5SDimitry Andric ComplexPairTy Visit(Expr *E) { 96*0b57cec5SDimitry Andric ApplyDebugLocation DL(CGF, E); 97*0b57cec5SDimitry Andric return StmtVisitor<ComplexExprEmitter, ComplexPairTy>::Visit(E); 98*0b57cec5SDimitry Andric } 99*0b57cec5SDimitry Andric 100*0b57cec5SDimitry Andric ComplexPairTy VisitStmt(Stmt *S) { 1015ffd83dbSDimitry Andric S->dump(llvm::errs(), CGF.getContext()); 102*0b57cec5SDimitry Andric llvm_unreachable("Stmt can't have complex result type!"); 103*0b57cec5SDimitry Andric } 104*0b57cec5SDimitry Andric ComplexPairTy VisitExpr(Expr *S); 105*0b57cec5SDimitry Andric ComplexPairTy VisitConstantExpr(ConstantExpr *E) { 1065ffd83dbSDimitry Andric if (llvm::Constant *Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) 1075ffd83dbSDimitry Andric return ComplexPairTy(Result->getAggregateElement(0U), 1085ffd83dbSDimitry Andric Result->getAggregateElement(1U)); 109*0b57cec5SDimitry Andric return Visit(E->getSubExpr()); 110*0b57cec5SDimitry Andric } 111*0b57cec5SDimitry Andric ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());} 112*0b57cec5SDimitry Andric ComplexPairTy VisitGenericSelectionExpr(GenericSelectionExpr *GE) { 113*0b57cec5SDimitry Andric return Visit(GE->getResultExpr()); 114*0b57cec5SDimitry Andric } 115*0b57cec5SDimitry Andric ComplexPairTy VisitImaginaryLiteral(const ImaginaryLiteral *IL); 116*0b57cec5SDimitry Andric ComplexPairTy 117*0b57cec5SDimitry Andric VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *PE) { 118*0b57cec5SDimitry Andric return Visit(PE->getReplacement()); 119*0b57cec5SDimitry Andric } 120*0b57cec5SDimitry Andric ComplexPairTy VisitCoawaitExpr(CoawaitExpr *S) { 121*0b57cec5SDimitry Andric return CGF.EmitCoawaitExpr(*S).getComplexVal(); 122*0b57cec5SDimitry Andric } 123*0b57cec5SDimitry Andric ComplexPairTy VisitCoyieldExpr(CoyieldExpr *S) { 124*0b57cec5SDimitry Andric return CGF.EmitCoyieldExpr(*S).getComplexVal(); 125*0b57cec5SDimitry Andric } 126*0b57cec5SDimitry Andric ComplexPairTy VisitUnaryCoawait(const UnaryOperator *E) { 127*0b57cec5SDimitry Andric return Visit(E->getSubExpr()); 128*0b57cec5SDimitry Andric } 129*0b57cec5SDimitry Andric 130*0b57cec5SDimitry Andric ComplexPairTy emitConstant(const CodeGenFunction::ConstantEmission &Constant, 131*0b57cec5SDimitry Andric Expr *E) { 132*0b57cec5SDimitry Andric assert(Constant && "not a constant"); 133*0b57cec5SDimitry Andric if (Constant.isReference()) 134*0b57cec5SDimitry Andric return EmitLoadOfLValue(Constant.getReferenceLValue(CGF, E), 135*0b57cec5SDimitry Andric E->getExprLoc()); 136*0b57cec5SDimitry Andric 137*0b57cec5SDimitry Andric llvm::Constant *pair = Constant.getValue(); 138*0b57cec5SDimitry Andric return ComplexPairTy(pair->getAggregateElement(0U), 139*0b57cec5SDimitry Andric pair->getAggregateElement(1U)); 140*0b57cec5SDimitry Andric } 141*0b57cec5SDimitry Andric 142*0b57cec5SDimitry Andric // l-values. 143*0b57cec5SDimitry Andric ComplexPairTy VisitDeclRefExpr(DeclRefExpr *E) { 144*0b57cec5SDimitry Andric if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E)) 145*0b57cec5SDimitry Andric return emitConstant(Constant, E); 146*0b57cec5SDimitry Andric return EmitLoadOfLValue(E); 147*0b57cec5SDimitry Andric } 148*0b57cec5SDimitry Andric ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { 149*0b57cec5SDimitry Andric return EmitLoadOfLValue(E); 150*0b57cec5SDimitry Andric } 151*0b57cec5SDimitry Andric ComplexPairTy VisitObjCMessageExpr(ObjCMessageExpr *E) { 152*0b57cec5SDimitry Andric return CGF.EmitObjCMessageExpr(E).getComplexVal(); 153*0b57cec5SDimitry Andric } 154*0b57cec5SDimitry Andric ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); } 155*0b57cec5SDimitry Andric ComplexPairTy VisitMemberExpr(MemberExpr *ME) { 156*0b57cec5SDimitry Andric if (CodeGenFunction::ConstantEmission Constant = 157*0b57cec5SDimitry Andric CGF.tryEmitAsConstant(ME)) { 158*0b57cec5SDimitry Andric CGF.EmitIgnoredExpr(ME->getBase()); 159*0b57cec5SDimitry Andric return emitConstant(Constant, ME); 160*0b57cec5SDimitry Andric } 161*0b57cec5SDimitry Andric return EmitLoadOfLValue(ME); 162*0b57cec5SDimitry Andric } 163*0b57cec5SDimitry Andric ComplexPairTy VisitOpaqueValueExpr(OpaqueValueExpr *E) { 164*0b57cec5SDimitry Andric if (E->isGLValue()) 165*0b57cec5SDimitry Andric return EmitLoadOfLValue(CGF.getOrCreateOpaqueLValueMapping(E), 166*0b57cec5SDimitry Andric E->getExprLoc()); 167*0b57cec5SDimitry Andric return CGF.getOrCreateOpaqueRValueMapping(E).getComplexVal(); 168*0b57cec5SDimitry Andric } 169*0b57cec5SDimitry Andric 170*0b57cec5SDimitry Andric ComplexPairTy VisitPseudoObjectExpr(PseudoObjectExpr *E) { 171*0b57cec5SDimitry Andric return CGF.EmitPseudoObjectRValue(E).getComplexVal(); 172*0b57cec5SDimitry Andric } 173*0b57cec5SDimitry Andric 174*0b57cec5SDimitry Andric // FIXME: CompoundLiteralExpr 175*0b57cec5SDimitry Andric 176*0b57cec5SDimitry Andric ComplexPairTy EmitCast(CastKind CK, Expr *Op, QualType DestTy); 177*0b57cec5SDimitry Andric ComplexPairTy VisitImplicitCastExpr(ImplicitCastExpr *E) { 178*0b57cec5SDimitry Andric // Unlike for scalars, we don't have to worry about function->ptr demotion 179*0b57cec5SDimitry Andric // here. 180*0b57cec5SDimitry Andric return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType()); 181*0b57cec5SDimitry Andric } 182*0b57cec5SDimitry Andric ComplexPairTy VisitCastExpr(CastExpr *E) { 183*0b57cec5SDimitry Andric if (const auto *ECE = dyn_cast<ExplicitCastExpr>(E)) 184*0b57cec5SDimitry Andric CGF.CGM.EmitExplicitCastExprType(ECE, &CGF); 185*0b57cec5SDimitry Andric return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType()); 186*0b57cec5SDimitry Andric } 187*0b57cec5SDimitry Andric ComplexPairTy VisitCallExpr(const CallExpr *E); 188*0b57cec5SDimitry Andric ComplexPairTy VisitStmtExpr(const StmtExpr *E); 189*0b57cec5SDimitry Andric 190*0b57cec5SDimitry Andric // Operators. 191*0b57cec5SDimitry Andric ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E, 192*0b57cec5SDimitry Andric bool isInc, bool isPre) { 193*0b57cec5SDimitry Andric LValue LV = CGF.EmitLValue(E->getSubExpr()); 194*0b57cec5SDimitry Andric return CGF.EmitComplexPrePostIncDec(E, LV, isInc, isPre); 195*0b57cec5SDimitry Andric } 196*0b57cec5SDimitry Andric ComplexPairTy VisitUnaryPostDec(const UnaryOperator *E) { 197*0b57cec5SDimitry Andric return VisitPrePostIncDec(E, false, false); 198*0b57cec5SDimitry Andric } 199*0b57cec5SDimitry Andric ComplexPairTy VisitUnaryPostInc(const UnaryOperator *E) { 200*0b57cec5SDimitry Andric return VisitPrePostIncDec(E, true, false); 201*0b57cec5SDimitry Andric } 202*0b57cec5SDimitry Andric ComplexPairTy VisitUnaryPreDec(const UnaryOperator *E) { 203*0b57cec5SDimitry Andric return VisitPrePostIncDec(E, false, true); 204*0b57cec5SDimitry Andric } 205*0b57cec5SDimitry Andric ComplexPairTy VisitUnaryPreInc(const UnaryOperator *E) { 206*0b57cec5SDimitry Andric return VisitPrePostIncDec(E, true, true); 207*0b57cec5SDimitry Andric } 208*0b57cec5SDimitry Andric ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); } 209bdd1243dSDimitry Andric 210bdd1243dSDimitry Andric ComplexPairTy VisitUnaryPlus(const UnaryOperator *E, 211bdd1243dSDimitry Andric QualType PromotionType = QualType()); 212bdd1243dSDimitry Andric ComplexPairTy VisitPlus(const UnaryOperator *E, QualType PromotionType); 213bdd1243dSDimitry Andric ComplexPairTy VisitUnaryMinus(const UnaryOperator *E, 214bdd1243dSDimitry Andric QualType PromotionType = QualType()); 215bdd1243dSDimitry Andric ComplexPairTy VisitMinus(const UnaryOperator *E, QualType PromotionType); 216*0b57cec5SDimitry Andric ComplexPairTy VisitUnaryNot (const UnaryOperator *E); 217*0b57cec5SDimitry Andric // LNot,Real,Imag never return complex. 218*0b57cec5SDimitry Andric ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) { 219*0b57cec5SDimitry Andric return Visit(E->getSubExpr()); 220*0b57cec5SDimitry Andric } 221*0b57cec5SDimitry Andric ComplexPairTy VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) { 222*0b57cec5SDimitry Andric CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE); 223*0b57cec5SDimitry Andric return Visit(DAE->getExpr()); 224*0b57cec5SDimitry Andric } 225*0b57cec5SDimitry Andric ComplexPairTy VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) { 226*0b57cec5SDimitry Andric CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE); 227*0b57cec5SDimitry Andric return Visit(DIE->getExpr()); 228*0b57cec5SDimitry Andric } 229*0b57cec5SDimitry Andric ComplexPairTy VisitExprWithCleanups(ExprWithCleanups *E) { 230*0b57cec5SDimitry Andric CodeGenFunction::RunCleanupsScope Scope(CGF); 231*0b57cec5SDimitry Andric ComplexPairTy Vals = Visit(E->getSubExpr()); 232*0b57cec5SDimitry Andric // Defend against dominance problems caused by jumps out of expression 233*0b57cec5SDimitry Andric // evaluation through the shared cleanup block. 234*0b57cec5SDimitry Andric Scope.ForceCleanup({&Vals.first, &Vals.second}); 235*0b57cec5SDimitry Andric return Vals; 236*0b57cec5SDimitry Andric } 237*0b57cec5SDimitry Andric ComplexPairTy VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { 238*0b57cec5SDimitry Andric assert(E->getType()->isAnyComplexType() && "Expected complex type!"); 239*0b57cec5SDimitry Andric QualType Elem = E->getType()->castAs<ComplexType>()->getElementType(); 240*0b57cec5SDimitry Andric llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem)); 241*0b57cec5SDimitry Andric return ComplexPairTy(Null, Null); 242*0b57cec5SDimitry Andric } 243*0b57cec5SDimitry Andric ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) { 244*0b57cec5SDimitry Andric assert(E->getType()->isAnyComplexType() && "Expected complex type!"); 245*0b57cec5SDimitry Andric QualType Elem = E->getType()->castAs<ComplexType>()->getElementType(); 246*0b57cec5SDimitry Andric llvm::Constant *Null = 247*0b57cec5SDimitry Andric llvm::Constant::getNullValue(CGF.ConvertType(Elem)); 248*0b57cec5SDimitry Andric return ComplexPairTy(Null, Null); 249*0b57cec5SDimitry Andric } 250*0b57cec5SDimitry Andric 251*0b57cec5SDimitry Andric struct BinOpInfo { 252*0b57cec5SDimitry Andric ComplexPairTy LHS; 253*0b57cec5SDimitry Andric ComplexPairTy RHS; 254*0b57cec5SDimitry Andric QualType Ty; // Computation Type. 255bdd1243dSDimitry Andric FPOptions FPFeatures; 256*0b57cec5SDimitry Andric }; 257*0b57cec5SDimitry Andric 258bdd1243dSDimitry Andric BinOpInfo EmitBinOps(const BinaryOperator *E, 259bdd1243dSDimitry Andric QualType PromotionTy = QualType()); 260bdd1243dSDimitry Andric ComplexPairTy EmitPromoted(const Expr *E, QualType PromotionTy); 261bdd1243dSDimitry Andric ComplexPairTy EmitPromotedComplexOperand(const Expr *E, QualType PromotionTy); 262*0b57cec5SDimitry Andric LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E, 263*0b57cec5SDimitry Andric ComplexPairTy (ComplexExprEmitter::*Func) 264*0b57cec5SDimitry Andric (const BinOpInfo &), 265*0b57cec5SDimitry Andric RValue &Val); 266*0b57cec5SDimitry Andric ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E, 267*0b57cec5SDimitry Andric ComplexPairTy (ComplexExprEmitter::*Func) 268*0b57cec5SDimitry Andric (const BinOpInfo &)); 269*0b57cec5SDimitry Andric 270*0b57cec5SDimitry Andric ComplexPairTy EmitBinAdd(const BinOpInfo &Op); 271*0b57cec5SDimitry Andric ComplexPairTy EmitBinSub(const BinOpInfo &Op); 272*0b57cec5SDimitry Andric ComplexPairTy EmitBinMul(const BinOpInfo &Op); 273*0b57cec5SDimitry Andric ComplexPairTy EmitBinDiv(const BinOpInfo &Op); 274*0b57cec5SDimitry Andric 275*0b57cec5SDimitry Andric ComplexPairTy EmitComplexBinOpLibCall(StringRef LibCallName, 276*0b57cec5SDimitry Andric const BinOpInfo &Op); 277*0b57cec5SDimitry Andric 278bdd1243dSDimitry Andric QualType getPromotionType(QualType Ty) { 279bdd1243dSDimitry Andric if (auto *CT = Ty->getAs<ComplexType>()) { 280bdd1243dSDimitry Andric QualType ElementType = CT->getElementType(); 281bdd1243dSDimitry Andric if (ElementType.UseExcessPrecision(CGF.getContext())) 282bdd1243dSDimitry Andric return CGF.getContext().getComplexType(CGF.getContext().FloatTy); 283*0b57cec5SDimitry Andric } 284bdd1243dSDimitry Andric if (Ty.UseExcessPrecision(CGF.getContext())) 285bdd1243dSDimitry Andric return CGF.getContext().FloatTy; 286bdd1243dSDimitry Andric return QualType(); 287*0b57cec5SDimitry Andric } 288bdd1243dSDimitry Andric 289bdd1243dSDimitry Andric #define HANDLEBINOP(OP) \ 290bdd1243dSDimitry Andric ComplexPairTy VisitBin##OP(const BinaryOperator *E) { \ 291bdd1243dSDimitry Andric QualType promotionTy = getPromotionType(E->getType()); \ 292bdd1243dSDimitry Andric ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy)); \ 293bdd1243dSDimitry Andric if (!promotionTy.isNull()) \ 294bdd1243dSDimitry Andric result = \ 295bdd1243dSDimitry Andric CGF.EmitUnPromotedValue(result, E->getType()); \ 296bdd1243dSDimitry Andric return result; \ 297*0b57cec5SDimitry Andric } 298bdd1243dSDimitry Andric 299bdd1243dSDimitry Andric HANDLEBINOP(Mul) 300bdd1243dSDimitry Andric HANDLEBINOP(Div) 301bdd1243dSDimitry Andric HANDLEBINOP(Add) 302bdd1243dSDimitry Andric HANDLEBINOP(Sub) 303bdd1243dSDimitry Andric #undef HANDLEBINOP 304*0b57cec5SDimitry Andric 305a7dea167SDimitry Andric ComplexPairTy VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) { 306a7dea167SDimitry Andric return Visit(E->getSemanticForm()); 307a7dea167SDimitry Andric } 308a7dea167SDimitry Andric 309*0b57cec5SDimitry Andric // Compound assignments. 310*0b57cec5SDimitry Andric ComplexPairTy VisitBinAddAssign(const CompoundAssignOperator *E) { 311*0b57cec5SDimitry Andric return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd); 312*0b57cec5SDimitry Andric } 313*0b57cec5SDimitry Andric ComplexPairTy VisitBinSubAssign(const CompoundAssignOperator *E) { 314*0b57cec5SDimitry Andric return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub); 315*0b57cec5SDimitry Andric } 316*0b57cec5SDimitry Andric ComplexPairTy VisitBinMulAssign(const CompoundAssignOperator *E) { 317*0b57cec5SDimitry Andric return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul); 318*0b57cec5SDimitry Andric } 319*0b57cec5SDimitry Andric ComplexPairTy VisitBinDivAssign(const CompoundAssignOperator *E) { 320*0b57cec5SDimitry Andric return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv); 321*0b57cec5SDimitry Andric } 322*0b57cec5SDimitry Andric 323*0b57cec5SDimitry Andric // GCC rejects rem/and/or/xor for integer complex. 324*0b57cec5SDimitry Andric // Logical and/or always return int, never complex. 325*0b57cec5SDimitry Andric 326*0b57cec5SDimitry Andric // No comparisons produce a complex result. 327*0b57cec5SDimitry Andric 328*0b57cec5SDimitry Andric LValue EmitBinAssignLValue(const BinaryOperator *E, 329*0b57cec5SDimitry Andric ComplexPairTy &Val); 330*0b57cec5SDimitry Andric ComplexPairTy VisitBinAssign (const BinaryOperator *E); 331*0b57cec5SDimitry Andric ComplexPairTy VisitBinComma (const BinaryOperator *E); 332*0b57cec5SDimitry Andric 333*0b57cec5SDimitry Andric 334*0b57cec5SDimitry Andric ComplexPairTy 335*0b57cec5SDimitry Andric VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO); 336*0b57cec5SDimitry Andric ComplexPairTy VisitChooseExpr(ChooseExpr *CE); 337*0b57cec5SDimitry Andric 338*0b57cec5SDimitry Andric ComplexPairTy VisitInitListExpr(InitListExpr *E); 339*0b57cec5SDimitry Andric 340*0b57cec5SDimitry Andric ComplexPairTy VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { 341*0b57cec5SDimitry Andric return EmitLoadOfLValue(E); 342*0b57cec5SDimitry Andric } 343*0b57cec5SDimitry Andric 344*0b57cec5SDimitry Andric ComplexPairTy VisitVAArgExpr(VAArgExpr *E); 345*0b57cec5SDimitry Andric 346*0b57cec5SDimitry Andric ComplexPairTy VisitAtomicExpr(AtomicExpr *E) { 347*0b57cec5SDimitry Andric return CGF.EmitAtomicExpr(E).getComplexVal(); 348*0b57cec5SDimitry Andric } 349*0b57cec5SDimitry Andric }; 350*0b57cec5SDimitry Andric } // end anonymous namespace. 351*0b57cec5SDimitry Andric 352*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 353*0b57cec5SDimitry Andric // Utilities 354*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 355*0b57cec5SDimitry Andric 356*0b57cec5SDimitry Andric Address CodeGenFunction::emitAddrOfRealComponent(Address addr, 357*0b57cec5SDimitry Andric QualType complexType) { 358*0b57cec5SDimitry Andric return Builder.CreateStructGEP(addr, 0, addr.getName() + ".realp"); 359*0b57cec5SDimitry Andric } 360*0b57cec5SDimitry Andric 361*0b57cec5SDimitry Andric Address CodeGenFunction::emitAddrOfImagComponent(Address addr, 362*0b57cec5SDimitry Andric QualType complexType) { 363*0b57cec5SDimitry Andric return Builder.CreateStructGEP(addr, 1, addr.getName() + ".imagp"); 364*0b57cec5SDimitry Andric } 365*0b57cec5SDimitry Andric 366*0b57cec5SDimitry Andric /// EmitLoadOfLValue - Given an RValue reference for a complex, emit code to 367*0b57cec5SDimitry Andric /// load the real and imaginary pieces, returning them as Real/Imag. 368*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitLoadOfLValue(LValue lvalue, 369*0b57cec5SDimitry Andric SourceLocation loc) { 370*0b57cec5SDimitry Andric assert(lvalue.isSimple() && "non-simple complex l-value?"); 371*0b57cec5SDimitry Andric if (lvalue.getType()->isAtomicType()) 372*0b57cec5SDimitry Andric return CGF.EmitAtomicLoad(lvalue, loc).getComplexVal(); 373*0b57cec5SDimitry Andric 374480093f4SDimitry Andric Address SrcPtr = lvalue.getAddress(CGF); 375*0b57cec5SDimitry Andric bool isVolatile = lvalue.isVolatileQualified(); 376*0b57cec5SDimitry Andric 377*0b57cec5SDimitry Andric llvm::Value *Real = nullptr, *Imag = nullptr; 378*0b57cec5SDimitry Andric 379*0b57cec5SDimitry Andric if (!IgnoreReal || isVolatile) { 380*0b57cec5SDimitry Andric Address RealP = CGF.emitAddrOfRealComponent(SrcPtr, lvalue.getType()); 381*0b57cec5SDimitry Andric Real = Builder.CreateLoad(RealP, isVolatile, SrcPtr.getName() + ".real"); 382*0b57cec5SDimitry Andric } 383*0b57cec5SDimitry Andric 384*0b57cec5SDimitry Andric if (!IgnoreImag || isVolatile) { 385*0b57cec5SDimitry Andric Address ImagP = CGF.emitAddrOfImagComponent(SrcPtr, lvalue.getType()); 386*0b57cec5SDimitry Andric Imag = Builder.CreateLoad(ImagP, isVolatile, SrcPtr.getName() + ".imag"); 387*0b57cec5SDimitry Andric } 388*0b57cec5SDimitry Andric 389*0b57cec5SDimitry Andric return ComplexPairTy(Real, Imag); 390*0b57cec5SDimitry Andric } 391*0b57cec5SDimitry Andric 392*0b57cec5SDimitry Andric /// EmitStoreOfComplex - Store the specified real/imag parts into the 393*0b57cec5SDimitry Andric /// specified value pointer. 394*0b57cec5SDimitry Andric void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, LValue lvalue, 395*0b57cec5SDimitry Andric bool isInit) { 396*0b57cec5SDimitry Andric if (lvalue.getType()->isAtomicType() || 397*0b57cec5SDimitry Andric (!isInit && CGF.LValueIsSuitableForInlineAtomic(lvalue))) 398*0b57cec5SDimitry Andric return CGF.EmitAtomicStore(RValue::getComplex(Val), lvalue, isInit); 399*0b57cec5SDimitry Andric 400480093f4SDimitry Andric Address Ptr = lvalue.getAddress(CGF); 401*0b57cec5SDimitry Andric Address RealPtr = CGF.emitAddrOfRealComponent(Ptr, lvalue.getType()); 402*0b57cec5SDimitry Andric Address ImagPtr = CGF.emitAddrOfImagComponent(Ptr, lvalue.getType()); 403*0b57cec5SDimitry Andric 404*0b57cec5SDimitry Andric Builder.CreateStore(Val.first, RealPtr, lvalue.isVolatileQualified()); 405*0b57cec5SDimitry Andric Builder.CreateStore(Val.second, ImagPtr, lvalue.isVolatileQualified()); 406*0b57cec5SDimitry Andric } 407*0b57cec5SDimitry Andric 408*0b57cec5SDimitry Andric 409*0b57cec5SDimitry Andric 410*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 411*0b57cec5SDimitry Andric // Visitor Methods 412*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 413*0b57cec5SDimitry Andric 414*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) { 415*0b57cec5SDimitry Andric CGF.ErrorUnsupported(E, "complex expression"); 416*0b57cec5SDimitry Andric llvm::Type *EltTy = 417*0b57cec5SDimitry Andric CGF.ConvertType(getComplexType(E->getType())->getElementType()); 418*0b57cec5SDimitry Andric llvm::Value *U = llvm::UndefValue::get(EltTy); 419*0b57cec5SDimitry Andric return ComplexPairTy(U, U); 420*0b57cec5SDimitry Andric } 421*0b57cec5SDimitry Andric 422*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter:: 423*0b57cec5SDimitry Andric VisitImaginaryLiteral(const ImaginaryLiteral *IL) { 424*0b57cec5SDimitry Andric llvm::Value *Imag = CGF.EmitScalarExpr(IL->getSubExpr()); 425*0b57cec5SDimitry Andric return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag); 426*0b57cec5SDimitry Andric } 427*0b57cec5SDimitry Andric 428*0b57cec5SDimitry Andric 429*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) { 430*0b57cec5SDimitry Andric if (E->getCallReturnType(CGF.getContext())->isReferenceType()) 431*0b57cec5SDimitry Andric return EmitLoadOfLValue(E); 432*0b57cec5SDimitry Andric 433*0b57cec5SDimitry Andric return CGF.EmitCallExpr(E).getComplexVal(); 434*0b57cec5SDimitry Andric } 435*0b57cec5SDimitry Andric 436*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) { 437*0b57cec5SDimitry Andric CodeGenFunction::StmtExprEvaluation eval(CGF); 438*0b57cec5SDimitry Andric Address RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(), true); 439*0b57cec5SDimitry Andric assert(RetAlloca.isValid() && "Expected complex return value"); 440*0b57cec5SDimitry Andric return EmitLoadOfLValue(CGF.MakeAddrLValue(RetAlloca, E->getType()), 441*0b57cec5SDimitry Andric E->getExprLoc()); 442*0b57cec5SDimitry Andric } 443*0b57cec5SDimitry Andric 444*0b57cec5SDimitry Andric /// Emit a cast from complex value Val to DestType. 445*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val, 446*0b57cec5SDimitry Andric QualType SrcType, 447*0b57cec5SDimitry Andric QualType DestType, 448*0b57cec5SDimitry Andric SourceLocation Loc) { 449*0b57cec5SDimitry Andric // Get the src/dest element type. 450*0b57cec5SDimitry Andric SrcType = SrcType->castAs<ComplexType>()->getElementType(); 451*0b57cec5SDimitry Andric DestType = DestType->castAs<ComplexType>()->getElementType(); 452*0b57cec5SDimitry Andric 453*0b57cec5SDimitry Andric // C99 6.3.1.6: When a value of complex type is converted to another 454*0b57cec5SDimitry Andric // complex type, both the real and imaginary parts follow the conversion 455*0b57cec5SDimitry Andric // rules for the corresponding real types. 4565ffd83dbSDimitry Andric if (Val.first) 457*0b57cec5SDimitry Andric Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType, Loc); 4585ffd83dbSDimitry Andric if (Val.second) 459*0b57cec5SDimitry Andric Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType, Loc); 460*0b57cec5SDimitry Andric return Val; 461*0b57cec5SDimitry Andric } 462*0b57cec5SDimitry Andric 463*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val, 464*0b57cec5SDimitry Andric QualType SrcType, 465*0b57cec5SDimitry Andric QualType DestType, 466*0b57cec5SDimitry Andric SourceLocation Loc) { 467*0b57cec5SDimitry Andric // Convert the input element to the element type of the complex. 468*0b57cec5SDimitry Andric DestType = DestType->castAs<ComplexType>()->getElementType(); 469*0b57cec5SDimitry Andric Val = CGF.EmitScalarConversion(Val, SrcType, DestType, Loc); 470*0b57cec5SDimitry Andric 471*0b57cec5SDimitry Andric // Return (realval, 0). 472*0b57cec5SDimitry Andric return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType())); 473*0b57cec5SDimitry Andric } 474*0b57cec5SDimitry Andric 475*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op, 476*0b57cec5SDimitry Andric QualType DestTy) { 477*0b57cec5SDimitry Andric switch (CK) { 478*0b57cec5SDimitry Andric case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!"); 479*0b57cec5SDimitry Andric 480*0b57cec5SDimitry Andric // Atomic to non-atomic casts may be more than a no-op for some platforms and 481*0b57cec5SDimitry Andric // for some types. 482*0b57cec5SDimitry Andric case CK_AtomicToNonAtomic: 483*0b57cec5SDimitry Andric case CK_NonAtomicToAtomic: 484*0b57cec5SDimitry Andric case CK_NoOp: 485*0b57cec5SDimitry Andric case CK_LValueToRValue: 486*0b57cec5SDimitry Andric case CK_UserDefinedConversion: 487*0b57cec5SDimitry Andric return Visit(Op); 488*0b57cec5SDimitry Andric 489*0b57cec5SDimitry Andric case CK_LValueBitCast: { 490*0b57cec5SDimitry Andric LValue origLV = CGF.EmitLValue(Op); 491480093f4SDimitry Andric Address V = origLV.getAddress(CGF); 492*0b57cec5SDimitry Andric V = Builder.CreateElementBitCast(V, CGF.ConvertType(DestTy)); 493*0b57cec5SDimitry Andric return EmitLoadOfLValue(CGF.MakeAddrLValue(V, DestTy), Op->getExprLoc()); 494*0b57cec5SDimitry Andric } 495*0b57cec5SDimitry Andric 496*0b57cec5SDimitry Andric case CK_LValueToRValueBitCast: { 497*0b57cec5SDimitry Andric LValue SourceLVal = CGF.EmitLValue(Op); 498480093f4SDimitry Andric Address Addr = Builder.CreateElementBitCast(SourceLVal.getAddress(CGF), 499*0b57cec5SDimitry Andric CGF.ConvertTypeForMem(DestTy)); 500*0b57cec5SDimitry Andric LValue DestLV = CGF.MakeAddrLValue(Addr, DestTy); 501*0b57cec5SDimitry Andric DestLV.setTBAAInfo(TBAAAccessInfo::getMayAliasInfo()); 502*0b57cec5SDimitry Andric return EmitLoadOfLValue(DestLV, Op->getExprLoc()); 503*0b57cec5SDimitry Andric } 504*0b57cec5SDimitry Andric 505*0b57cec5SDimitry Andric case CK_BitCast: 506*0b57cec5SDimitry Andric case CK_BaseToDerived: 507*0b57cec5SDimitry Andric case CK_DerivedToBase: 508*0b57cec5SDimitry Andric case CK_UncheckedDerivedToBase: 509*0b57cec5SDimitry Andric case CK_Dynamic: 510*0b57cec5SDimitry Andric case CK_ToUnion: 511*0b57cec5SDimitry Andric case CK_ArrayToPointerDecay: 512*0b57cec5SDimitry Andric case CK_FunctionToPointerDecay: 513*0b57cec5SDimitry Andric case CK_NullToPointer: 514*0b57cec5SDimitry Andric case CK_NullToMemberPointer: 515*0b57cec5SDimitry Andric case CK_BaseToDerivedMemberPointer: 516*0b57cec5SDimitry Andric case CK_DerivedToBaseMemberPointer: 517*0b57cec5SDimitry Andric case CK_MemberPointerToBoolean: 518*0b57cec5SDimitry Andric case CK_ReinterpretMemberPointer: 519*0b57cec5SDimitry Andric case CK_ConstructorConversion: 520*0b57cec5SDimitry Andric case CK_IntegralToPointer: 521*0b57cec5SDimitry Andric case CK_PointerToIntegral: 522*0b57cec5SDimitry Andric case CK_PointerToBoolean: 523*0b57cec5SDimitry Andric case CK_ToVoid: 524*0b57cec5SDimitry Andric case CK_VectorSplat: 525*0b57cec5SDimitry Andric case CK_IntegralCast: 526*0b57cec5SDimitry Andric case CK_BooleanToSignedIntegral: 527*0b57cec5SDimitry Andric case CK_IntegralToBoolean: 528*0b57cec5SDimitry Andric case CK_IntegralToFloating: 529*0b57cec5SDimitry Andric case CK_FloatingToIntegral: 530*0b57cec5SDimitry Andric case CK_FloatingToBoolean: 531*0b57cec5SDimitry Andric case CK_FloatingCast: 532*0b57cec5SDimitry Andric case CK_CPointerToObjCPointerCast: 533*0b57cec5SDimitry Andric case CK_BlockPointerToObjCPointerCast: 534*0b57cec5SDimitry Andric case CK_AnyPointerToBlockPointerCast: 535*0b57cec5SDimitry Andric case CK_ObjCObjectLValueCast: 536*0b57cec5SDimitry Andric case CK_FloatingComplexToReal: 537*0b57cec5SDimitry Andric case CK_FloatingComplexToBoolean: 538*0b57cec5SDimitry Andric case CK_IntegralComplexToReal: 539*0b57cec5SDimitry Andric case CK_IntegralComplexToBoolean: 540*0b57cec5SDimitry Andric case CK_ARCProduceObject: 541*0b57cec5SDimitry Andric case CK_ARCConsumeObject: 542*0b57cec5SDimitry Andric case CK_ARCReclaimReturnedObject: 543*0b57cec5SDimitry Andric case CK_ARCExtendBlockObject: 544*0b57cec5SDimitry Andric case CK_CopyAndAutoreleaseBlockObject: 545*0b57cec5SDimitry Andric case CK_BuiltinFnToFnPtr: 546*0b57cec5SDimitry Andric case CK_ZeroToOCLOpaqueType: 547*0b57cec5SDimitry Andric case CK_AddressSpaceConversion: 548*0b57cec5SDimitry Andric case CK_IntToOCLSampler: 549e8d8bef9SDimitry Andric case CK_FloatingToFixedPoint: 550e8d8bef9SDimitry Andric case CK_FixedPointToFloating: 551*0b57cec5SDimitry Andric case CK_FixedPointCast: 552*0b57cec5SDimitry Andric case CK_FixedPointToBoolean: 553*0b57cec5SDimitry Andric case CK_FixedPointToIntegral: 554*0b57cec5SDimitry Andric case CK_IntegralToFixedPoint: 555fe6060f1SDimitry Andric case CK_MatrixCast: 556*0b57cec5SDimitry Andric llvm_unreachable("invalid cast kind for complex value"); 557*0b57cec5SDimitry Andric 558*0b57cec5SDimitry Andric case CK_FloatingRealToComplex: 559e8d8bef9SDimitry Andric case CK_IntegralRealToComplex: { 560e8d8bef9SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op); 561*0b57cec5SDimitry Andric return EmitScalarToComplexCast(CGF.EmitScalarExpr(Op), Op->getType(), 562*0b57cec5SDimitry Andric DestTy, Op->getExprLoc()); 563e8d8bef9SDimitry Andric } 564*0b57cec5SDimitry Andric 565*0b57cec5SDimitry Andric case CK_FloatingComplexCast: 566*0b57cec5SDimitry Andric case CK_FloatingComplexToIntegralComplex: 567*0b57cec5SDimitry Andric case CK_IntegralComplexCast: 568e8d8bef9SDimitry Andric case CK_IntegralComplexToFloatingComplex: { 569e8d8bef9SDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op); 570*0b57cec5SDimitry Andric return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy, 571*0b57cec5SDimitry Andric Op->getExprLoc()); 572*0b57cec5SDimitry Andric } 573e8d8bef9SDimitry Andric } 574*0b57cec5SDimitry Andric 575*0b57cec5SDimitry Andric llvm_unreachable("unknown cast resulting in complex value"); 576*0b57cec5SDimitry Andric } 577*0b57cec5SDimitry Andric 578bdd1243dSDimitry Andric ComplexPairTy ComplexExprEmitter::VisitUnaryPlus(const UnaryOperator *E, 579bdd1243dSDimitry Andric QualType PromotionType) { 580bdd1243dSDimitry Andric QualType promotionTy = PromotionType.isNull() 581bdd1243dSDimitry Andric ? getPromotionType(E->getSubExpr()->getType()) 582bdd1243dSDimitry Andric : PromotionType; 583bdd1243dSDimitry Andric ComplexPairTy result = VisitPlus(E, promotionTy); 584bdd1243dSDimitry Andric if (!promotionTy.isNull()) 585bdd1243dSDimitry Andric return CGF.EmitUnPromotedValue(result, E->getSubExpr()->getType()); 586bdd1243dSDimitry Andric return result; 587bdd1243dSDimitry Andric } 588bdd1243dSDimitry Andric 589bdd1243dSDimitry Andric ComplexPairTy ComplexExprEmitter::VisitPlus(const UnaryOperator *E, 590bdd1243dSDimitry Andric QualType PromotionType) { 591*0b57cec5SDimitry Andric TestAndClearIgnoreReal(); 592*0b57cec5SDimitry Andric TestAndClearIgnoreImag(); 593bdd1243dSDimitry Andric if (!PromotionType.isNull()) 594bdd1243dSDimitry Andric return CGF.EmitPromotedComplexExpr(E->getSubExpr(), PromotionType); 595bdd1243dSDimitry Andric return Visit(E->getSubExpr()); 596bdd1243dSDimitry Andric } 597bdd1243dSDimitry Andric 598bdd1243dSDimitry Andric ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E, 599bdd1243dSDimitry Andric QualType PromotionType) { 600bdd1243dSDimitry Andric QualType promotionTy = PromotionType.isNull() 601bdd1243dSDimitry Andric ? getPromotionType(E->getSubExpr()->getType()) 602bdd1243dSDimitry Andric : PromotionType; 603bdd1243dSDimitry Andric ComplexPairTy result = VisitMinus(E, promotionTy); 604bdd1243dSDimitry Andric if (!promotionTy.isNull()) 605bdd1243dSDimitry Andric return CGF.EmitUnPromotedValue(result, E->getSubExpr()->getType()); 606bdd1243dSDimitry Andric return result; 607bdd1243dSDimitry Andric } 608bdd1243dSDimitry Andric ComplexPairTy ComplexExprEmitter::VisitMinus(const UnaryOperator *E, 609bdd1243dSDimitry Andric QualType PromotionType) { 610bdd1243dSDimitry Andric TestAndClearIgnoreReal(); 611bdd1243dSDimitry Andric TestAndClearIgnoreImag(); 612bdd1243dSDimitry Andric ComplexPairTy Op; 613bdd1243dSDimitry Andric if (!PromotionType.isNull()) 614bdd1243dSDimitry Andric Op = CGF.EmitPromotedComplexExpr(E->getSubExpr(), PromotionType); 615bdd1243dSDimitry Andric else 616bdd1243dSDimitry Andric Op = Visit(E->getSubExpr()); 617*0b57cec5SDimitry Andric 618*0b57cec5SDimitry Andric llvm::Value *ResR, *ResI; 619*0b57cec5SDimitry Andric if (Op.first->getType()->isFloatingPointTy()) { 620*0b57cec5SDimitry Andric ResR = Builder.CreateFNeg(Op.first, "neg.r"); 621*0b57cec5SDimitry Andric ResI = Builder.CreateFNeg(Op.second, "neg.i"); 622*0b57cec5SDimitry Andric } else { 623*0b57cec5SDimitry Andric ResR = Builder.CreateNeg(Op.first, "neg.r"); 624*0b57cec5SDimitry Andric ResI = Builder.CreateNeg(Op.second, "neg.i"); 625*0b57cec5SDimitry Andric } 626*0b57cec5SDimitry Andric return ComplexPairTy(ResR, ResI); 627*0b57cec5SDimitry Andric } 628*0b57cec5SDimitry Andric 629*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) { 630*0b57cec5SDimitry Andric TestAndClearIgnoreReal(); 631*0b57cec5SDimitry Andric TestAndClearIgnoreImag(); 632*0b57cec5SDimitry Andric // ~(a+ib) = a + i*-b 633*0b57cec5SDimitry Andric ComplexPairTy Op = Visit(E->getSubExpr()); 634*0b57cec5SDimitry Andric llvm::Value *ResI; 635*0b57cec5SDimitry Andric if (Op.second->getType()->isFloatingPointTy()) 636*0b57cec5SDimitry Andric ResI = Builder.CreateFNeg(Op.second, "conj.i"); 637*0b57cec5SDimitry Andric else 638*0b57cec5SDimitry Andric ResI = Builder.CreateNeg(Op.second, "conj.i"); 639*0b57cec5SDimitry Andric 640*0b57cec5SDimitry Andric return ComplexPairTy(Op.first, ResI); 641*0b57cec5SDimitry Andric } 642*0b57cec5SDimitry Andric 643*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitBinAdd(const BinOpInfo &Op) { 644*0b57cec5SDimitry Andric llvm::Value *ResR, *ResI; 645*0b57cec5SDimitry Andric 646*0b57cec5SDimitry Andric if (Op.LHS.first->getType()->isFloatingPointTy()) { 647bdd1243dSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures); 648*0b57cec5SDimitry Andric ResR = Builder.CreateFAdd(Op.LHS.first, Op.RHS.first, "add.r"); 649*0b57cec5SDimitry Andric if (Op.LHS.second && Op.RHS.second) 650*0b57cec5SDimitry Andric ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second, "add.i"); 651*0b57cec5SDimitry Andric else 652*0b57cec5SDimitry Andric ResI = Op.LHS.second ? Op.LHS.second : Op.RHS.second; 653*0b57cec5SDimitry Andric assert(ResI && "Only one operand may be real!"); 654*0b57cec5SDimitry Andric } else { 655*0b57cec5SDimitry Andric ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first, "add.r"); 656*0b57cec5SDimitry Andric assert(Op.LHS.second && Op.RHS.second && 657*0b57cec5SDimitry Andric "Both operands of integer complex operators must be complex!"); 658*0b57cec5SDimitry Andric ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second, "add.i"); 659*0b57cec5SDimitry Andric } 660*0b57cec5SDimitry Andric return ComplexPairTy(ResR, ResI); 661*0b57cec5SDimitry Andric } 662*0b57cec5SDimitry Andric 663*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitBinSub(const BinOpInfo &Op) { 664*0b57cec5SDimitry Andric llvm::Value *ResR, *ResI; 665*0b57cec5SDimitry Andric if (Op.LHS.first->getType()->isFloatingPointTy()) { 666bdd1243dSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures); 667*0b57cec5SDimitry Andric ResR = Builder.CreateFSub(Op.LHS.first, Op.RHS.first, "sub.r"); 668*0b57cec5SDimitry Andric if (Op.LHS.second && Op.RHS.second) 669*0b57cec5SDimitry Andric ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second, "sub.i"); 670*0b57cec5SDimitry Andric else 671*0b57cec5SDimitry Andric ResI = Op.LHS.second ? Op.LHS.second 672*0b57cec5SDimitry Andric : Builder.CreateFNeg(Op.RHS.second, "sub.i"); 673*0b57cec5SDimitry Andric assert(ResI && "Only one operand may be real!"); 674*0b57cec5SDimitry Andric } else { 675*0b57cec5SDimitry Andric ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first, "sub.r"); 676*0b57cec5SDimitry Andric assert(Op.LHS.second && Op.RHS.second && 677*0b57cec5SDimitry Andric "Both operands of integer complex operators must be complex!"); 678*0b57cec5SDimitry Andric ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second, "sub.i"); 679*0b57cec5SDimitry Andric } 680*0b57cec5SDimitry Andric return ComplexPairTy(ResR, ResI); 681*0b57cec5SDimitry Andric } 682*0b57cec5SDimitry Andric 683*0b57cec5SDimitry Andric /// Emit a libcall for a binary operation on complex types. 684*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName, 685*0b57cec5SDimitry Andric const BinOpInfo &Op) { 686*0b57cec5SDimitry Andric CallArgList Args; 687*0b57cec5SDimitry Andric Args.add(RValue::get(Op.LHS.first), 688*0b57cec5SDimitry Andric Op.Ty->castAs<ComplexType>()->getElementType()); 689*0b57cec5SDimitry Andric Args.add(RValue::get(Op.LHS.second), 690*0b57cec5SDimitry Andric Op.Ty->castAs<ComplexType>()->getElementType()); 691*0b57cec5SDimitry Andric Args.add(RValue::get(Op.RHS.first), 692*0b57cec5SDimitry Andric Op.Ty->castAs<ComplexType>()->getElementType()); 693*0b57cec5SDimitry Andric Args.add(RValue::get(Op.RHS.second), 694*0b57cec5SDimitry Andric Op.Ty->castAs<ComplexType>()->getElementType()); 695*0b57cec5SDimitry Andric 696*0b57cec5SDimitry Andric // We *must* use the full CG function call building logic here because the 697*0b57cec5SDimitry Andric // complex type has special ABI handling. We also should not forget about 698*0b57cec5SDimitry Andric // special calling convention which may be used for compiler builtins. 699*0b57cec5SDimitry Andric 700*0b57cec5SDimitry Andric // We create a function qualified type to state that this call does not have 701*0b57cec5SDimitry Andric // any exceptions. 702*0b57cec5SDimitry Andric FunctionProtoType::ExtProtoInfo EPI; 703*0b57cec5SDimitry Andric EPI = EPI.withExceptionSpec( 704*0b57cec5SDimitry Andric FunctionProtoType::ExceptionSpecInfo(EST_BasicNoexcept)); 705*0b57cec5SDimitry Andric SmallVector<QualType, 4> ArgsQTys( 706*0b57cec5SDimitry Andric 4, Op.Ty->castAs<ComplexType>()->getElementType()); 707*0b57cec5SDimitry Andric QualType FQTy = CGF.getContext().getFunctionType(Op.Ty, ArgsQTys, EPI); 708*0b57cec5SDimitry Andric const CGFunctionInfo &FuncInfo = CGF.CGM.getTypes().arrangeFreeFunctionCall( 709*0b57cec5SDimitry Andric Args, cast<FunctionType>(FQTy.getTypePtr()), false); 710*0b57cec5SDimitry Andric 711*0b57cec5SDimitry Andric llvm::FunctionType *FTy = CGF.CGM.getTypes().GetFunctionType(FuncInfo); 712*0b57cec5SDimitry Andric llvm::FunctionCallee Func = CGF.CGM.CreateRuntimeFunction( 713*0b57cec5SDimitry Andric FTy, LibCallName, llvm::AttributeList(), true); 714*0b57cec5SDimitry Andric CGCallee Callee = CGCallee::forDirect(Func, FQTy->getAs<FunctionProtoType>()); 715*0b57cec5SDimitry Andric 716*0b57cec5SDimitry Andric llvm::CallBase *Call; 717*0b57cec5SDimitry Andric RValue Res = CGF.EmitCall(FuncInfo, Callee, ReturnValueSlot(), Args, &Call); 718*0b57cec5SDimitry Andric Call->setCallingConv(CGF.CGM.getRuntimeCC()); 719*0b57cec5SDimitry Andric return Res.getComplexVal(); 720*0b57cec5SDimitry Andric } 721*0b57cec5SDimitry Andric 722*0b57cec5SDimitry Andric /// Lookup the libcall name for a given floating point type complex 723*0b57cec5SDimitry Andric /// multiply. 724*0b57cec5SDimitry Andric static StringRef getComplexMultiplyLibCallName(llvm::Type *Ty) { 725*0b57cec5SDimitry Andric switch (Ty->getTypeID()) { 726*0b57cec5SDimitry Andric default: 727*0b57cec5SDimitry Andric llvm_unreachable("Unsupported floating point type!"); 728*0b57cec5SDimitry Andric case llvm::Type::HalfTyID: 729*0b57cec5SDimitry Andric return "__mulhc3"; 730*0b57cec5SDimitry Andric case llvm::Type::FloatTyID: 731*0b57cec5SDimitry Andric return "__mulsc3"; 732*0b57cec5SDimitry Andric case llvm::Type::DoubleTyID: 733*0b57cec5SDimitry Andric return "__muldc3"; 734*0b57cec5SDimitry Andric case llvm::Type::PPC_FP128TyID: 735*0b57cec5SDimitry Andric return "__multc3"; 736*0b57cec5SDimitry Andric case llvm::Type::X86_FP80TyID: 737*0b57cec5SDimitry Andric return "__mulxc3"; 738*0b57cec5SDimitry Andric case llvm::Type::FP128TyID: 739*0b57cec5SDimitry Andric return "__multc3"; 740*0b57cec5SDimitry Andric } 741*0b57cec5SDimitry Andric } 742*0b57cec5SDimitry Andric 743*0b57cec5SDimitry Andric // See C11 Annex G.5.1 for the semantics of multiplicative operators on complex 744*0b57cec5SDimitry Andric // typed values. 745*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) { 746*0b57cec5SDimitry Andric using llvm::Value; 747*0b57cec5SDimitry Andric Value *ResR, *ResI; 748*0b57cec5SDimitry Andric llvm::MDBuilder MDHelper(CGF.getLLVMContext()); 749*0b57cec5SDimitry Andric 750*0b57cec5SDimitry Andric if (Op.LHS.first->getType()->isFloatingPointTy()) { 751*0b57cec5SDimitry Andric // The general formulation is: 752*0b57cec5SDimitry Andric // (a + ib) * (c + id) = (a * c - b * d) + i(a * d + b * c) 753*0b57cec5SDimitry Andric // 754*0b57cec5SDimitry Andric // But we can fold away components which would be zero due to a real 755*0b57cec5SDimitry Andric // operand according to C11 Annex G.5.1p2. 756*0b57cec5SDimitry Andric // FIXME: C11 also provides for imaginary types which would allow folding 757*0b57cec5SDimitry Andric // still more of this within the type system. 758*0b57cec5SDimitry Andric 759bdd1243dSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures); 760*0b57cec5SDimitry Andric if (Op.LHS.second && Op.RHS.second) { 761*0b57cec5SDimitry Andric // If both operands are complex, emit the core math directly, and then 762*0b57cec5SDimitry Andric // test for NaNs. If we find NaNs in the result, we delegate to a libcall 763*0b57cec5SDimitry Andric // to carefully re-compute the correct infinity representation if 764*0b57cec5SDimitry Andric // possible. The expectation is that the presence of NaNs here is 765*0b57cec5SDimitry Andric // *extremely* rare, and so the cost of the libcall is almost irrelevant. 766*0b57cec5SDimitry Andric // This is good, because the libcall re-computes the core multiplication 767*0b57cec5SDimitry Andric // exactly the same as we do here and re-tests for NaNs in order to be 768*0b57cec5SDimitry Andric // a generic complex*complex libcall. 769*0b57cec5SDimitry Andric 770*0b57cec5SDimitry Andric // First compute the four products. 771*0b57cec5SDimitry Andric Value *AC = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul_ac"); 772*0b57cec5SDimitry Andric Value *BD = Builder.CreateFMul(Op.LHS.second, Op.RHS.second, "mul_bd"); 773*0b57cec5SDimitry Andric Value *AD = Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul_ad"); 774*0b57cec5SDimitry Andric Value *BC = Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul_bc"); 775*0b57cec5SDimitry Andric 776*0b57cec5SDimitry Andric // The real part is the difference of the first two, the imaginary part is 777*0b57cec5SDimitry Andric // the sum of the second. 778*0b57cec5SDimitry Andric ResR = Builder.CreateFSub(AC, BD, "mul_r"); 779*0b57cec5SDimitry Andric ResI = Builder.CreateFAdd(AD, BC, "mul_i"); 780*0b57cec5SDimitry Andric 781*0b57cec5SDimitry Andric // Emit the test for the real part becoming NaN and create a branch to 782*0b57cec5SDimitry Andric // handle it. We test for NaN by comparing the number to itself. 783*0b57cec5SDimitry Andric Value *IsRNaN = Builder.CreateFCmpUNO(ResR, ResR, "isnan_cmp"); 784*0b57cec5SDimitry Andric llvm::BasicBlock *ContBB = CGF.createBasicBlock("complex_mul_cont"); 785*0b57cec5SDimitry Andric llvm::BasicBlock *INaNBB = CGF.createBasicBlock("complex_mul_imag_nan"); 786*0b57cec5SDimitry Andric llvm::Instruction *Branch = Builder.CreateCondBr(IsRNaN, INaNBB, ContBB); 787*0b57cec5SDimitry Andric llvm::BasicBlock *OrigBB = Branch->getParent(); 788*0b57cec5SDimitry Andric 789*0b57cec5SDimitry Andric // Give hint that we very much don't expect to see NaNs. 790*0b57cec5SDimitry Andric // Value chosen to match UR_NONTAKEN_WEIGHT, see BranchProbabilityInfo.cpp 791*0b57cec5SDimitry Andric llvm::MDNode *BrWeight = MDHelper.createBranchWeights(1, (1U << 20) - 1); 792*0b57cec5SDimitry Andric Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight); 793*0b57cec5SDimitry Andric 794*0b57cec5SDimitry Andric // Now test the imaginary part and create its branch. 795*0b57cec5SDimitry Andric CGF.EmitBlock(INaNBB); 796*0b57cec5SDimitry Andric Value *IsINaN = Builder.CreateFCmpUNO(ResI, ResI, "isnan_cmp"); 797*0b57cec5SDimitry Andric llvm::BasicBlock *LibCallBB = CGF.createBasicBlock("complex_mul_libcall"); 798*0b57cec5SDimitry Andric Branch = Builder.CreateCondBr(IsINaN, LibCallBB, ContBB); 799*0b57cec5SDimitry Andric Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight); 800*0b57cec5SDimitry Andric 801*0b57cec5SDimitry Andric // Now emit the libcall on this slowest of the slow paths. 802*0b57cec5SDimitry Andric CGF.EmitBlock(LibCallBB); 803*0b57cec5SDimitry Andric Value *LibCallR, *LibCallI; 804*0b57cec5SDimitry Andric std::tie(LibCallR, LibCallI) = EmitComplexBinOpLibCall( 805*0b57cec5SDimitry Andric getComplexMultiplyLibCallName(Op.LHS.first->getType()), Op); 806*0b57cec5SDimitry Andric Builder.CreateBr(ContBB); 807*0b57cec5SDimitry Andric 808*0b57cec5SDimitry Andric // Finally continue execution by phi-ing together the different 809*0b57cec5SDimitry Andric // computation paths. 810*0b57cec5SDimitry Andric CGF.EmitBlock(ContBB); 811*0b57cec5SDimitry Andric llvm::PHINode *RealPHI = Builder.CreatePHI(ResR->getType(), 3, "real_mul_phi"); 812*0b57cec5SDimitry Andric RealPHI->addIncoming(ResR, OrigBB); 813*0b57cec5SDimitry Andric RealPHI->addIncoming(ResR, INaNBB); 814*0b57cec5SDimitry Andric RealPHI->addIncoming(LibCallR, LibCallBB); 815*0b57cec5SDimitry Andric llvm::PHINode *ImagPHI = Builder.CreatePHI(ResI->getType(), 3, "imag_mul_phi"); 816*0b57cec5SDimitry Andric ImagPHI->addIncoming(ResI, OrigBB); 817*0b57cec5SDimitry Andric ImagPHI->addIncoming(ResI, INaNBB); 818*0b57cec5SDimitry Andric ImagPHI->addIncoming(LibCallI, LibCallBB); 819*0b57cec5SDimitry Andric return ComplexPairTy(RealPHI, ImagPHI); 820*0b57cec5SDimitry Andric } 821*0b57cec5SDimitry Andric assert((Op.LHS.second || Op.RHS.second) && 822*0b57cec5SDimitry Andric "At least one operand must be complex!"); 823*0b57cec5SDimitry Andric 824*0b57cec5SDimitry Andric // If either of the operands is a real rather than a complex, the 825*0b57cec5SDimitry Andric // imaginary component is ignored when computing the real component of the 826*0b57cec5SDimitry Andric // result. 827*0b57cec5SDimitry Andric ResR = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul.rl"); 828*0b57cec5SDimitry Andric 829*0b57cec5SDimitry Andric ResI = Op.LHS.second 830*0b57cec5SDimitry Andric ? Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul.il") 831*0b57cec5SDimitry Andric : Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul.ir"); 832*0b57cec5SDimitry Andric } else { 833*0b57cec5SDimitry Andric assert(Op.LHS.second && Op.RHS.second && 834*0b57cec5SDimitry Andric "Both operands of integer complex operators must be complex!"); 835*0b57cec5SDimitry Andric Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first, "mul.rl"); 836*0b57cec5SDimitry Andric Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second, "mul.rr"); 837*0b57cec5SDimitry Andric ResR = Builder.CreateSub(ResRl, ResRr, "mul.r"); 838*0b57cec5SDimitry Andric 839*0b57cec5SDimitry Andric Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first, "mul.il"); 840*0b57cec5SDimitry Andric Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second, "mul.ir"); 841*0b57cec5SDimitry Andric ResI = Builder.CreateAdd(ResIl, ResIr, "mul.i"); 842*0b57cec5SDimitry Andric } 843*0b57cec5SDimitry Andric return ComplexPairTy(ResR, ResI); 844*0b57cec5SDimitry Andric } 845*0b57cec5SDimitry Andric 846*0b57cec5SDimitry Andric // See C11 Annex G.5.1 for the semantics of multiplicative operators on complex 847*0b57cec5SDimitry Andric // typed values. 848*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) { 849*0b57cec5SDimitry Andric llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second; 850*0b57cec5SDimitry Andric llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second; 851*0b57cec5SDimitry Andric 852*0b57cec5SDimitry Andric llvm::Value *DSTr, *DSTi; 853*0b57cec5SDimitry Andric if (LHSr->getType()->isFloatingPointTy()) { 854*0b57cec5SDimitry Andric // If we have a complex operand on the RHS and FastMath is not allowed, we 855*0b57cec5SDimitry Andric // delegate to a libcall to handle all of the complexities and minimize 856*0b57cec5SDimitry Andric // underflow/overflow cases. When FastMath is allowed we construct the 857*0b57cec5SDimitry Andric // divide inline using the same algorithm as for integer operands. 858*0b57cec5SDimitry Andric // 859*0b57cec5SDimitry Andric // FIXME: We would be able to avoid the libcall in many places if we 860*0b57cec5SDimitry Andric // supported imaginary types in addition to complex types. 861bdd1243dSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures); 862*0b57cec5SDimitry Andric if (RHSi && !CGF.getLangOpts().FastMath) { 863*0b57cec5SDimitry Andric BinOpInfo LibCallOp = Op; 864*0b57cec5SDimitry Andric // If LHS was a real, supply a null imaginary part. 865*0b57cec5SDimitry Andric if (!LHSi) 866*0b57cec5SDimitry Andric LibCallOp.LHS.second = llvm::Constant::getNullValue(LHSr->getType()); 867*0b57cec5SDimitry Andric 868*0b57cec5SDimitry Andric switch (LHSr->getType()->getTypeID()) { 869*0b57cec5SDimitry Andric default: 870*0b57cec5SDimitry Andric llvm_unreachable("Unsupported floating point type!"); 871*0b57cec5SDimitry Andric case llvm::Type::HalfTyID: 872*0b57cec5SDimitry Andric return EmitComplexBinOpLibCall("__divhc3", LibCallOp); 873*0b57cec5SDimitry Andric case llvm::Type::FloatTyID: 874*0b57cec5SDimitry Andric return EmitComplexBinOpLibCall("__divsc3", LibCallOp); 875*0b57cec5SDimitry Andric case llvm::Type::DoubleTyID: 876*0b57cec5SDimitry Andric return EmitComplexBinOpLibCall("__divdc3", LibCallOp); 877*0b57cec5SDimitry Andric case llvm::Type::PPC_FP128TyID: 878*0b57cec5SDimitry Andric return EmitComplexBinOpLibCall("__divtc3", LibCallOp); 879*0b57cec5SDimitry Andric case llvm::Type::X86_FP80TyID: 880*0b57cec5SDimitry Andric return EmitComplexBinOpLibCall("__divxc3", LibCallOp); 881*0b57cec5SDimitry Andric case llvm::Type::FP128TyID: 882*0b57cec5SDimitry Andric return EmitComplexBinOpLibCall("__divtc3", LibCallOp); 883*0b57cec5SDimitry Andric } 884*0b57cec5SDimitry Andric } else if (RHSi) { 885*0b57cec5SDimitry Andric if (!LHSi) 886*0b57cec5SDimitry Andric LHSi = llvm::Constant::getNullValue(RHSi->getType()); 887*0b57cec5SDimitry Andric 888*0b57cec5SDimitry Andric // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) 889*0b57cec5SDimitry Andric llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr); // a*c 890*0b57cec5SDimitry Andric llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi); // b*d 891*0b57cec5SDimitry Andric llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD); // ac+bd 892*0b57cec5SDimitry Andric 893*0b57cec5SDimitry Andric llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr); // c*c 894*0b57cec5SDimitry Andric llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi); // d*d 895*0b57cec5SDimitry Andric llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD); // cc+dd 896*0b57cec5SDimitry Andric 897*0b57cec5SDimitry Andric llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr); // b*c 898*0b57cec5SDimitry Andric llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi); // a*d 899*0b57cec5SDimitry Andric llvm::Value *BCmAD = Builder.CreateFSub(BC, AD); // bc-ad 900*0b57cec5SDimitry Andric 901*0b57cec5SDimitry Andric DSTr = Builder.CreateFDiv(ACpBD, CCpDD); 902*0b57cec5SDimitry Andric DSTi = Builder.CreateFDiv(BCmAD, CCpDD); 903*0b57cec5SDimitry Andric } else { 904*0b57cec5SDimitry Andric assert(LHSi && "Can have at most one non-complex operand!"); 905*0b57cec5SDimitry Andric 906*0b57cec5SDimitry Andric DSTr = Builder.CreateFDiv(LHSr, RHSr); 907*0b57cec5SDimitry Andric DSTi = Builder.CreateFDiv(LHSi, RHSr); 908*0b57cec5SDimitry Andric } 909*0b57cec5SDimitry Andric } else { 910*0b57cec5SDimitry Andric assert(Op.LHS.second && Op.RHS.second && 911*0b57cec5SDimitry Andric "Both operands of integer complex operators must be complex!"); 912*0b57cec5SDimitry Andric // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) 913*0b57cec5SDimitry Andric llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr); // a*c 914*0b57cec5SDimitry Andric llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi); // b*d 915*0b57cec5SDimitry Andric llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2); // ac+bd 916*0b57cec5SDimitry Andric 917*0b57cec5SDimitry Andric llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr); // c*c 918*0b57cec5SDimitry Andric llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi); // d*d 919*0b57cec5SDimitry Andric llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5); // cc+dd 920*0b57cec5SDimitry Andric 921*0b57cec5SDimitry Andric llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr); // b*c 922*0b57cec5SDimitry Andric llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi); // a*d 923*0b57cec5SDimitry Andric llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8); // bc-ad 924*0b57cec5SDimitry Andric 925*0b57cec5SDimitry Andric if (Op.Ty->castAs<ComplexType>()->getElementType()->isUnsignedIntegerType()) { 926*0b57cec5SDimitry Andric DSTr = Builder.CreateUDiv(Tmp3, Tmp6); 927*0b57cec5SDimitry Andric DSTi = Builder.CreateUDiv(Tmp9, Tmp6); 928*0b57cec5SDimitry Andric } else { 929*0b57cec5SDimitry Andric DSTr = Builder.CreateSDiv(Tmp3, Tmp6); 930*0b57cec5SDimitry Andric DSTi = Builder.CreateSDiv(Tmp9, Tmp6); 931*0b57cec5SDimitry Andric } 932*0b57cec5SDimitry Andric } 933*0b57cec5SDimitry Andric 934*0b57cec5SDimitry Andric return ComplexPairTy(DSTr, DSTi); 935*0b57cec5SDimitry Andric } 936*0b57cec5SDimitry Andric 937bdd1243dSDimitry Andric ComplexPairTy CodeGenFunction::EmitUnPromotedValue(ComplexPairTy result, 938bdd1243dSDimitry Andric QualType UnPromotionType) { 939bdd1243dSDimitry Andric llvm::Type *ComplexElementTy = 940bdd1243dSDimitry Andric ConvertType(UnPromotionType->castAs<ComplexType>()->getElementType()); 941bdd1243dSDimitry Andric if (result.first) 942bdd1243dSDimitry Andric result.first = 943bdd1243dSDimitry Andric Builder.CreateFPTrunc(result.first, ComplexElementTy, "unpromotion"); 944bdd1243dSDimitry Andric if (result.second) 945bdd1243dSDimitry Andric result.second = 946bdd1243dSDimitry Andric Builder.CreateFPTrunc(result.second, ComplexElementTy, "unpromotion"); 947bdd1243dSDimitry Andric return result; 948bdd1243dSDimitry Andric } 949bdd1243dSDimitry Andric 950bdd1243dSDimitry Andric ComplexPairTy CodeGenFunction::EmitPromotedValue(ComplexPairTy result, 951bdd1243dSDimitry Andric QualType PromotionType) { 952bdd1243dSDimitry Andric llvm::Type *ComplexElementTy = 953bdd1243dSDimitry Andric ConvertType(PromotionType->castAs<ComplexType>()->getElementType()); 954bdd1243dSDimitry Andric if (result.first) 955bdd1243dSDimitry Andric result.first = Builder.CreateFPExt(result.first, ComplexElementTy, "ext"); 956bdd1243dSDimitry Andric if (result.second) 957bdd1243dSDimitry Andric result.second = Builder.CreateFPExt(result.second, ComplexElementTy, "ext"); 958bdd1243dSDimitry Andric 959bdd1243dSDimitry Andric return result; 960bdd1243dSDimitry Andric } 961bdd1243dSDimitry Andric 962bdd1243dSDimitry Andric ComplexPairTy ComplexExprEmitter::EmitPromoted(const Expr *E, 963bdd1243dSDimitry Andric QualType PromotionType) { 964bdd1243dSDimitry Andric E = E->IgnoreParens(); 965bdd1243dSDimitry Andric if (auto BO = dyn_cast<BinaryOperator>(E)) { 966bdd1243dSDimitry Andric switch (BO->getOpcode()) { 967bdd1243dSDimitry Andric #define HANDLE_BINOP(OP) \ 968bdd1243dSDimitry Andric case BO_##OP: \ 969bdd1243dSDimitry Andric return EmitBin##OP(EmitBinOps(BO, PromotionType)); 970bdd1243dSDimitry Andric HANDLE_BINOP(Add) 971bdd1243dSDimitry Andric HANDLE_BINOP(Sub) 972bdd1243dSDimitry Andric HANDLE_BINOP(Mul) 973bdd1243dSDimitry Andric HANDLE_BINOP(Div) 974bdd1243dSDimitry Andric #undef HANDLE_BINOP 975bdd1243dSDimitry Andric default: 976bdd1243dSDimitry Andric break; 977bdd1243dSDimitry Andric } 978bdd1243dSDimitry Andric } else if (auto UO = dyn_cast<UnaryOperator>(E)) { 979bdd1243dSDimitry Andric switch (UO->getOpcode()) { 980bdd1243dSDimitry Andric case UO_Minus: 981bdd1243dSDimitry Andric return VisitMinus(UO, PromotionType); 982bdd1243dSDimitry Andric case UO_Plus: 983bdd1243dSDimitry Andric return VisitPlus(UO, PromotionType); 984bdd1243dSDimitry Andric default: 985bdd1243dSDimitry Andric break; 986bdd1243dSDimitry Andric } 987bdd1243dSDimitry Andric } 988bdd1243dSDimitry Andric auto result = Visit(const_cast<Expr *>(E)); 989bdd1243dSDimitry Andric if (!PromotionType.isNull()) 990bdd1243dSDimitry Andric return CGF.EmitPromotedValue(result, PromotionType); 991bdd1243dSDimitry Andric else 992bdd1243dSDimitry Andric return result; 993bdd1243dSDimitry Andric } 994bdd1243dSDimitry Andric 995bdd1243dSDimitry Andric ComplexPairTy CodeGenFunction::EmitPromotedComplexExpr(const Expr *E, 996bdd1243dSDimitry Andric QualType DstTy) { 997bdd1243dSDimitry Andric return ComplexExprEmitter(*this).EmitPromoted(E, DstTy); 998bdd1243dSDimitry Andric } 999bdd1243dSDimitry Andric 1000bdd1243dSDimitry Andric ComplexPairTy 1001bdd1243dSDimitry Andric ComplexExprEmitter::EmitPromotedComplexOperand(const Expr *E, 1002bdd1243dSDimitry Andric QualType OverallPromotionType) { 1003bdd1243dSDimitry Andric if (E->getType()->isAnyComplexType()) { 1004bdd1243dSDimitry Andric if (!OverallPromotionType.isNull()) 1005bdd1243dSDimitry Andric return CGF.EmitPromotedComplexExpr(E, OverallPromotionType); 1006bdd1243dSDimitry Andric else 1007bdd1243dSDimitry Andric return Visit(const_cast<Expr *>(E)); 1008bdd1243dSDimitry Andric } else { 1009bdd1243dSDimitry Andric if (!OverallPromotionType.isNull()) { 1010bdd1243dSDimitry Andric QualType ComplexElementTy = 1011bdd1243dSDimitry Andric OverallPromotionType->castAs<ComplexType>()->getElementType(); 1012bdd1243dSDimitry Andric return ComplexPairTy(CGF.EmitPromotedScalarExpr(E, ComplexElementTy), 1013bdd1243dSDimitry Andric nullptr); 1014bdd1243dSDimitry Andric } else { 1015bdd1243dSDimitry Andric return ComplexPairTy(CGF.EmitScalarExpr(E), nullptr); 1016bdd1243dSDimitry Andric } 1017bdd1243dSDimitry Andric } 1018bdd1243dSDimitry Andric } 1019bdd1243dSDimitry Andric 1020*0b57cec5SDimitry Andric ComplexExprEmitter::BinOpInfo 1021bdd1243dSDimitry Andric ComplexExprEmitter::EmitBinOps(const BinaryOperator *E, 1022bdd1243dSDimitry Andric QualType PromotionType) { 1023*0b57cec5SDimitry Andric TestAndClearIgnoreReal(); 1024*0b57cec5SDimitry Andric TestAndClearIgnoreImag(); 1025*0b57cec5SDimitry Andric BinOpInfo Ops; 1026*0b57cec5SDimitry Andric 1027bdd1243dSDimitry Andric Ops.LHS = EmitPromotedComplexOperand(E->getLHS(), PromotionType); 1028bdd1243dSDimitry Andric Ops.RHS = EmitPromotedComplexOperand(E->getRHS(), PromotionType); 1029bdd1243dSDimitry Andric if (!PromotionType.isNull()) 1030bdd1243dSDimitry Andric Ops.Ty = PromotionType; 1031bdd1243dSDimitry Andric else 1032*0b57cec5SDimitry Andric Ops.Ty = E->getType(); 1033bdd1243dSDimitry Andric Ops.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts()); 1034*0b57cec5SDimitry Andric return Ops; 1035*0b57cec5SDimitry Andric } 1036*0b57cec5SDimitry Andric 1037*0b57cec5SDimitry Andric 1038*0b57cec5SDimitry Andric LValue ComplexExprEmitter:: 1039*0b57cec5SDimitry Andric EmitCompoundAssignLValue(const CompoundAssignOperator *E, 1040*0b57cec5SDimitry Andric ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&), 1041*0b57cec5SDimitry Andric RValue &Val) { 1042*0b57cec5SDimitry Andric TestAndClearIgnoreReal(); 1043*0b57cec5SDimitry Andric TestAndClearIgnoreImag(); 1044*0b57cec5SDimitry Andric QualType LHSTy = E->getLHS()->getType(); 1045*0b57cec5SDimitry Andric if (const AtomicType *AT = LHSTy->getAs<AtomicType>()) 1046*0b57cec5SDimitry Andric LHSTy = AT->getValueType(); 1047*0b57cec5SDimitry Andric 1048*0b57cec5SDimitry Andric BinOpInfo OpInfo; 1049bdd1243dSDimitry Andric OpInfo.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts()); 1050bdd1243dSDimitry Andric CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures); 1051*0b57cec5SDimitry Andric 1052*0b57cec5SDimitry Andric // Load the RHS and LHS operands. 1053*0b57cec5SDimitry Andric // __block variables need to have the rhs evaluated first, plus this should 1054*0b57cec5SDimitry Andric // improve codegen a little. 1055bdd1243dSDimitry Andric QualType PromotionTypeCR; 1056bdd1243dSDimitry Andric PromotionTypeCR = getPromotionType(E->getComputationResultType()); 1057bdd1243dSDimitry Andric if (PromotionTypeCR.isNull()) 1058bdd1243dSDimitry Andric PromotionTypeCR = E->getComputationResultType(); 1059bdd1243dSDimitry Andric OpInfo.Ty = PromotionTypeCR; 1060bdd1243dSDimitry Andric QualType ComplexElementTy = 1061bdd1243dSDimitry Andric OpInfo.Ty->castAs<ComplexType>()->getElementType(); 1062bdd1243dSDimitry Andric QualType PromotionTypeRHS = getPromotionType(E->getRHS()->getType()); 1063*0b57cec5SDimitry Andric 1064*0b57cec5SDimitry Andric // The RHS should have been converted to the computation type. 1065*0b57cec5SDimitry Andric if (E->getRHS()->getType()->isRealFloatingType()) { 1066bdd1243dSDimitry Andric if (!PromotionTypeRHS.isNull()) 1067bdd1243dSDimitry Andric OpInfo.RHS = ComplexPairTy( 1068bdd1243dSDimitry Andric CGF.EmitPromotedScalarExpr(E->getRHS(), PromotionTypeRHS), nullptr); 1069bdd1243dSDimitry Andric else { 1070bdd1243dSDimitry Andric assert(CGF.getContext().hasSameUnqualifiedType(ComplexElementTy, 1071bdd1243dSDimitry Andric E->getRHS()->getType())); 1072bdd1243dSDimitry Andric 1073*0b57cec5SDimitry Andric OpInfo.RHS = ComplexPairTy(CGF.EmitScalarExpr(E->getRHS()), nullptr); 1074bdd1243dSDimitry Andric } 1075*0b57cec5SDimitry Andric } else { 1076bdd1243dSDimitry Andric if (!PromotionTypeRHS.isNull()) { 1077bdd1243dSDimitry Andric OpInfo.RHS = ComplexPairTy( 1078bdd1243dSDimitry Andric CGF.EmitPromotedComplexExpr(E->getRHS(), PromotionTypeRHS)); 1079bdd1243dSDimitry Andric } else { 1080bdd1243dSDimitry Andric assert(CGF.getContext().hasSameUnqualifiedType(OpInfo.Ty, 1081bdd1243dSDimitry Andric E->getRHS()->getType())); 1082*0b57cec5SDimitry Andric OpInfo.RHS = Visit(E->getRHS()); 1083*0b57cec5SDimitry Andric } 1084bdd1243dSDimitry Andric } 1085*0b57cec5SDimitry Andric 1086*0b57cec5SDimitry Andric LValue LHS = CGF.EmitLValue(E->getLHS()); 1087*0b57cec5SDimitry Andric 1088*0b57cec5SDimitry Andric // Load from the l-value and convert it. 1089*0b57cec5SDimitry Andric SourceLocation Loc = E->getExprLoc(); 1090bdd1243dSDimitry Andric QualType PromotionTypeLHS = getPromotionType(E->getComputationLHSType()); 1091*0b57cec5SDimitry Andric if (LHSTy->isAnyComplexType()) { 1092*0b57cec5SDimitry Andric ComplexPairTy LHSVal = EmitLoadOfLValue(LHS, Loc); 1093bdd1243dSDimitry Andric if (!PromotionTypeLHS.isNull()) 1094bdd1243dSDimitry Andric OpInfo.LHS = 1095bdd1243dSDimitry Andric EmitComplexToComplexCast(LHSVal, LHSTy, PromotionTypeLHS, Loc); 1096bdd1243dSDimitry Andric else 1097*0b57cec5SDimitry Andric OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc); 1098*0b57cec5SDimitry Andric } else { 1099*0b57cec5SDimitry Andric llvm::Value *LHSVal = CGF.EmitLoadOfScalar(LHS, Loc); 1100*0b57cec5SDimitry Andric // For floating point real operands we can directly pass the scalar form 1101*0b57cec5SDimitry Andric // to the binary operator emission and potentially get more efficient code. 1102*0b57cec5SDimitry Andric if (LHSTy->isRealFloatingType()) { 1103bdd1243dSDimitry Andric QualType PromotedComplexElementTy; 1104bdd1243dSDimitry Andric if (!PromotionTypeLHS.isNull()) { 1105bdd1243dSDimitry Andric PromotedComplexElementTy = 1106bdd1243dSDimitry Andric cast<ComplexType>(PromotionTypeLHS)->getElementType(); 1107bdd1243dSDimitry Andric if (!CGF.getContext().hasSameUnqualifiedType(PromotedComplexElementTy, 1108bdd1243dSDimitry Andric PromotionTypeLHS)) 1109bdd1243dSDimitry Andric LHSVal = CGF.EmitScalarConversion(LHSVal, LHSTy, 1110bdd1243dSDimitry Andric PromotedComplexElementTy, Loc); 1111bdd1243dSDimitry Andric } else { 1112*0b57cec5SDimitry Andric if (!CGF.getContext().hasSameUnqualifiedType(ComplexElementTy, LHSTy)) 1113bdd1243dSDimitry Andric LHSVal = 1114bdd1243dSDimitry Andric CGF.EmitScalarConversion(LHSVal, LHSTy, ComplexElementTy, Loc); 1115bdd1243dSDimitry Andric } 1116*0b57cec5SDimitry Andric OpInfo.LHS = ComplexPairTy(LHSVal, nullptr); 1117*0b57cec5SDimitry Andric } else { 1118*0b57cec5SDimitry Andric OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc); 1119*0b57cec5SDimitry Andric } 1120*0b57cec5SDimitry Andric } 1121*0b57cec5SDimitry Andric 1122*0b57cec5SDimitry Andric // Expand the binary operator. 1123*0b57cec5SDimitry Andric ComplexPairTy Result = (this->*Func)(OpInfo); 1124*0b57cec5SDimitry Andric 1125*0b57cec5SDimitry Andric // Truncate the result and store it into the LHS lvalue. 1126*0b57cec5SDimitry Andric if (LHSTy->isAnyComplexType()) { 1127*0b57cec5SDimitry Andric ComplexPairTy ResVal = 1128*0b57cec5SDimitry Andric EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy, Loc); 1129*0b57cec5SDimitry Andric EmitStoreOfComplex(ResVal, LHS, /*isInit*/ false); 1130*0b57cec5SDimitry Andric Val = RValue::getComplex(ResVal); 1131*0b57cec5SDimitry Andric } else { 1132*0b57cec5SDimitry Andric llvm::Value *ResVal = 1133*0b57cec5SDimitry Andric CGF.EmitComplexToScalarConversion(Result, OpInfo.Ty, LHSTy, Loc); 1134*0b57cec5SDimitry Andric CGF.EmitStoreOfScalar(ResVal, LHS, /*isInit*/ false); 1135*0b57cec5SDimitry Andric Val = RValue::get(ResVal); 1136*0b57cec5SDimitry Andric } 1137*0b57cec5SDimitry Andric 1138*0b57cec5SDimitry Andric return LHS; 1139*0b57cec5SDimitry Andric } 1140*0b57cec5SDimitry Andric 1141*0b57cec5SDimitry Andric // Compound assignments. 1142*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter:: 1143*0b57cec5SDimitry Andric EmitCompoundAssign(const CompoundAssignOperator *E, 1144*0b57cec5SDimitry Andric ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){ 1145*0b57cec5SDimitry Andric RValue Val; 1146*0b57cec5SDimitry Andric LValue LV = EmitCompoundAssignLValue(E, Func, Val); 1147*0b57cec5SDimitry Andric 1148*0b57cec5SDimitry Andric // The result of an assignment in C is the assigned r-value. 1149*0b57cec5SDimitry Andric if (!CGF.getLangOpts().CPlusPlus) 1150*0b57cec5SDimitry Andric return Val.getComplexVal(); 1151*0b57cec5SDimitry Andric 1152*0b57cec5SDimitry Andric // If the lvalue is non-volatile, return the computed value of the assignment. 1153*0b57cec5SDimitry Andric if (!LV.isVolatileQualified()) 1154*0b57cec5SDimitry Andric return Val.getComplexVal(); 1155*0b57cec5SDimitry Andric 1156*0b57cec5SDimitry Andric return EmitLoadOfLValue(LV, E->getExprLoc()); 1157*0b57cec5SDimitry Andric } 1158*0b57cec5SDimitry Andric 1159*0b57cec5SDimitry Andric LValue ComplexExprEmitter::EmitBinAssignLValue(const BinaryOperator *E, 1160*0b57cec5SDimitry Andric ComplexPairTy &Val) { 1161*0b57cec5SDimitry Andric assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(), 1162*0b57cec5SDimitry Andric E->getRHS()->getType()) && 1163*0b57cec5SDimitry Andric "Invalid assignment"); 1164*0b57cec5SDimitry Andric TestAndClearIgnoreReal(); 1165*0b57cec5SDimitry Andric TestAndClearIgnoreImag(); 1166*0b57cec5SDimitry Andric 1167*0b57cec5SDimitry Andric // Emit the RHS. __block variables need the RHS evaluated first. 1168*0b57cec5SDimitry Andric Val = Visit(E->getRHS()); 1169*0b57cec5SDimitry Andric 1170*0b57cec5SDimitry Andric // Compute the address to store into. 1171*0b57cec5SDimitry Andric LValue LHS = CGF.EmitLValue(E->getLHS()); 1172*0b57cec5SDimitry Andric 1173*0b57cec5SDimitry Andric // Store the result value into the LHS lvalue. 1174*0b57cec5SDimitry Andric EmitStoreOfComplex(Val, LHS, /*isInit*/ false); 1175*0b57cec5SDimitry Andric 1176*0b57cec5SDimitry Andric return LHS; 1177*0b57cec5SDimitry Andric } 1178*0b57cec5SDimitry Andric 1179*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) { 1180*0b57cec5SDimitry Andric ComplexPairTy Val; 1181*0b57cec5SDimitry Andric LValue LV = EmitBinAssignLValue(E, Val); 1182*0b57cec5SDimitry Andric 1183*0b57cec5SDimitry Andric // The result of an assignment in C is the assigned r-value. 1184*0b57cec5SDimitry Andric if (!CGF.getLangOpts().CPlusPlus) 1185*0b57cec5SDimitry Andric return Val; 1186*0b57cec5SDimitry Andric 1187*0b57cec5SDimitry Andric // If the lvalue is non-volatile, return the computed value of the assignment. 1188*0b57cec5SDimitry Andric if (!LV.isVolatileQualified()) 1189*0b57cec5SDimitry Andric return Val; 1190*0b57cec5SDimitry Andric 1191*0b57cec5SDimitry Andric return EmitLoadOfLValue(LV, E->getExprLoc()); 1192*0b57cec5SDimitry Andric } 1193*0b57cec5SDimitry Andric 1194*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) { 1195*0b57cec5SDimitry Andric CGF.EmitIgnoredExpr(E->getLHS()); 1196*0b57cec5SDimitry Andric return Visit(E->getRHS()); 1197*0b57cec5SDimitry Andric } 1198*0b57cec5SDimitry Andric 1199*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter:: 1200*0b57cec5SDimitry Andric VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { 1201*0b57cec5SDimitry Andric TestAndClearIgnoreReal(); 1202*0b57cec5SDimitry Andric TestAndClearIgnoreImag(); 1203*0b57cec5SDimitry Andric llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true"); 1204*0b57cec5SDimitry Andric llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false"); 1205*0b57cec5SDimitry Andric llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end"); 1206*0b57cec5SDimitry Andric 1207*0b57cec5SDimitry Andric // Bind the common expression if necessary. 1208*0b57cec5SDimitry Andric CodeGenFunction::OpaqueValueMapping binding(CGF, E); 1209*0b57cec5SDimitry Andric 1210*0b57cec5SDimitry Andric 1211*0b57cec5SDimitry Andric CodeGenFunction::ConditionalEvaluation eval(CGF); 1212*0b57cec5SDimitry Andric CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock, 1213*0b57cec5SDimitry Andric CGF.getProfileCount(E)); 1214*0b57cec5SDimitry Andric 1215*0b57cec5SDimitry Andric eval.begin(CGF); 1216*0b57cec5SDimitry Andric CGF.EmitBlock(LHSBlock); 1217*0b57cec5SDimitry Andric CGF.incrementProfileCounter(E); 1218*0b57cec5SDimitry Andric ComplexPairTy LHS = Visit(E->getTrueExpr()); 1219*0b57cec5SDimitry Andric LHSBlock = Builder.GetInsertBlock(); 1220*0b57cec5SDimitry Andric CGF.EmitBranch(ContBlock); 1221*0b57cec5SDimitry Andric eval.end(CGF); 1222*0b57cec5SDimitry Andric 1223*0b57cec5SDimitry Andric eval.begin(CGF); 1224*0b57cec5SDimitry Andric CGF.EmitBlock(RHSBlock); 1225*0b57cec5SDimitry Andric ComplexPairTy RHS = Visit(E->getFalseExpr()); 1226*0b57cec5SDimitry Andric RHSBlock = Builder.GetInsertBlock(); 1227*0b57cec5SDimitry Andric CGF.EmitBlock(ContBlock); 1228*0b57cec5SDimitry Andric eval.end(CGF); 1229*0b57cec5SDimitry Andric 1230*0b57cec5SDimitry Andric // Create a PHI node for the real part. 1231*0b57cec5SDimitry Andric llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), 2, "cond.r"); 1232*0b57cec5SDimitry Andric RealPN->addIncoming(LHS.first, LHSBlock); 1233*0b57cec5SDimitry Andric RealPN->addIncoming(RHS.first, RHSBlock); 1234*0b57cec5SDimitry Andric 1235*0b57cec5SDimitry Andric // Create a PHI node for the imaginary part. 1236*0b57cec5SDimitry Andric llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), 2, "cond.i"); 1237*0b57cec5SDimitry Andric ImagPN->addIncoming(LHS.second, LHSBlock); 1238*0b57cec5SDimitry Andric ImagPN->addIncoming(RHS.second, RHSBlock); 1239*0b57cec5SDimitry Andric 1240*0b57cec5SDimitry Andric return ComplexPairTy(RealPN, ImagPN); 1241*0b57cec5SDimitry Andric } 1242*0b57cec5SDimitry Andric 1243*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) { 1244*0b57cec5SDimitry Andric return Visit(E->getChosenSubExpr()); 1245*0b57cec5SDimitry Andric } 1246*0b57cec5SDimitry Andric 1247*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) { 1248*0b57cec5SDimitry Andric bool Ignore = TestAndClearIgnoreReal(); 1249*0b57cec5SDimitry Andric (void)Ignore; 1250*0b57cec5SDimitry Andric assert (Ignore == false && "init list ignored"); 1251*0b57cec5SDimitry Andric Ignore = TestAndClearIgnoreImag(); 1252*0b57cec5SDimitry Andric (void)Ignore; 1253*0b57cec5SDimitry Andric assert (Ignore == false && "init list ignored"); 1254*0b57cec5SDimitry Andric 1255*0b57cec5SDimitry Andric if (E->getNumInits() == 2) { 1256*0b57cec5SDimitry Andric llvm::Value *Real = CGF.EmitScalarExpr(E->getInit(0)); 1257*0b57cec5SDimitry Andric llvm::Value *Imag = CGF.EmitScalarExpr(E->getInit(1)); 1258*0b57cec5SDimitry Andric return ComplexPairTy(Real, Imag); 1259*0b57cec5SDimitry Andric } else if (E->getNumInits() == 1) { 1260*0b57cec5SDimitry Andric return Visit(E->getInit(0)); 1261*0b57cec5SDimitry Andric } 1262*0b57cec5SDimitry Andric 1263*0b57cec5SDimitry Andric // Empty init list initializes to null 1264*0b57cec5SDimitry Andric assert(E->getNumInits() == 0 && "Unexpected number of inits"); 1265*0b57cec5SDimitry Andric QualType Ty = E->getType()->castAs<ComplexType>()->getElementType(); 1266*0b57cec5SDimitry Andric llvm::Type* LTy = CGF.ConvertType(Ty); 1267*0b57cec5SDimitry Andric llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy); 1268*0b57cec5SDimitry Andric return ComplexPairTy(zeroConstant, zeroConstant); 1269*0b57cec5SDimitry Andric } 1270*0b57cec5SDimitry Andric 1271*0b57cec5SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) { 1272*0b57cec5SDimitry Andric Address ArgValue = Address::invalid(); 1273*0b57cec5SDimitry Andric Address ArgPtr = CGF.EmitVAArg(E, ArgValue); 1274*0b57cec5SDimitry Andric 1275*0b57cec5SDimitry Andric if (!ArgPtr.isValid()) { 1276*0b57cec5SDimitry Andric CGF.ErrorUnsupported(E, "complex va_arg expression"); 1277*0b57cec5SDimitry Andric llvm::Type *EltTy = 1278*0b57cec5SDimitry Andric CGF.ConvertType(E->getType()->castAs<ComplexType>()->getElementType()); 1279*0b57cec5SDimitry Andric llvm::Value *U = llvm::UndefValue::get(EltTy); 1280*0b57cec5SDimitry Andric return ComplexPairTy(U, U); 1281*0b57cec5SDimitry Andric } 1282*0b57cec5SDimitry Andric 1283*0b57cec5SDimitry Andric return EmitLoadOfLValue(CGF.MakeAddrLValue(ArgPtr, E->getType()), 1284*0b57cec5SDimitry Andric E->getExprLoc()); 1285*0b57cec5SDimitry Andric } 1286*0b57cec5SDimitry Andric 1287*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1288*0b57cec5SDimitry Andric // Entry Point into this File 1289*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1290*0b57cec5SDimitry Andric 1291*0b57cec5SDimitry Andric /// EmitComplexExpr - Emit the computation of the specified expression of 1292*0b57cec5SDimitry Andric /// complex type, ignoring the result. 1293*0b57cec5SDimitry Andric ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E, bool IgnoreReal, 1294*0b57cec5SDimitry Andric bool IgnoreImag) { 1295*0b57cec5SDimitry Andric assert(E && getComplexType(E->getType()) && 1296*0b57cec5SDimitry Andric "Invalid complex expression to emit"); 1297*0b57cec5SDimitry Andric 1298*0b57cec5SDimitry Andric return ComplexExprEmitter(*this, IgnoreReal, IgnoreImag) 1299*0b57cec5SDimitry Andric .Visit(const_cast<Expr *>(E)); 1300*0b57cec5SDimitry Andric } 1301*0b57cec5SDimitry Andric 1302*0b57cec5SDimitry Andric void CodeGenFunction::EmitComplexExprIntoLValue(const Expr *E, LValue dest, 1303*0b57cec5SDimitry Andric bool isInit) { 1304*0b57cec5SDimitry Andric assert(E && getComplexType(E->getType()) && 1305*0b57cec5SDimitry Andric "Invalid complex expression to emit"); 1306*0b57cec5SDimitry Andric ComplexExprEmitter Emitter(*this); 1307*0b57cec5SDimitry Andric ComplexPairTy Val = Emitter.Visit(const_cast<Expr*>(E)); 1308*0b57cec5SDimitry Andric Emitter.EmitStoreOfComplex(Val, dest, isInit); 1309*0b57cec5SDimitry Andric } 1310*0b57cec5SDimitry Andric 1311*0b57cec5SDimitry Andric /// EmitStoreOfComplex - Store a complex number into the specified l-value. 1312*0b57cec5SDimitry Andric void CodeGenFunction::EmitStoreOfComplex(ComplexPairTy V, LValue dest, 1313*0b57cec5SDimitry Andric bool isInit) { 1314*0b57cec5SDimitry Andric ComplexExprEmitter(*this).EmitStoreOfComplex(V, dest, isInit); 1315*0b57cec5SDimitry Andric } 1316*0b57cec5SDimitry Andric 1317*0b57cec5SDimitry Andric /// EmitLoadOfComplex - Load a complex number from the specified address. 1318*0b57cec5SDimitry Andric ComplexPairTy CodeGenFunction::EmitLoadOfComplex(LValue src, 1319*0b57cec5SDimitry Andric SourceLocation loc) { 1320*0b57cec5SDimitry Andric return ComplexExprEmitter(*this).EmitLoadOfLValue(src, loc); 1321*0b57cec5SDimitry Andric } 1322*0b57cec5SDimitry Andric 1323*0b57cec5SDimitry Andric LValue CodeGenFunction::EmitComplexAssignmentLValue(const BinaryOperator *E) { 1324*0b57cec5SDimitry Andric assert(E->getOpcode() == BO_Assign); 1325*0b57cec5SDimitry Andric ComplexPairTy Val; // ignored 1326480093f4SDimitry Andric LValue LVal = ComplexExprEmitter(*this).EmitBinAssignLValue(E, Val); 1327480093f4SDimitry Andric if (getLangOpts().OpenMP) 1328480093f4SDimitry Andric CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(*this, 1329480093f4SDimitry Andric E->getLHS()); 1330480093f4SDimitry Andric return LVal; 1331*0b57cec5SDimitry Andric } 1332*0b57cec5SDimitry Andric 1333*0b57cec5SDimitry Andric typedef ComplexPairTy (ComplexExprEmitter::*CompoundFunc)( 1334*0b57cec5SDimitry Andric const ComplexExprEmitter::BinOpInfo &); 1335*0b57cec5SDimitry Andric 1336*0b57cec5SDimitry Andric static CompoundFunc getComplexOp(BinaryOperatorKind Op) { 1337*0b57cec5SDimitry Andric switch (Op) { 1338*0b57cec5SDimitry Andric case BO_MulAssign: return &ComplexExprEmitter::EmitBinMul; 1339*0b57cec5SDimitry Andric case BO_DivAssign: return &ComplexExprEmitter::EmitBinDiv; 1340*0b57cec5SDimitry Andric case BO_SubAssign: return &ComplexExprEmitter::EmitBinSub; 1341*0b57cec5SDimitry Andric case BO_AddAssign: return &ComplexExprEmitter::EmitBinAdd; 1342*0b57cec5SDimitry Andric default: 1343*0b57cec5SDimitry Andric llvm_unreachable("unexpected complex compound assignment"); 1344*0b57cec5SDimitry Andric } 1345*0b57cec5SDimitry Andric } 1346*0b57cec5SDimitry Andric 1347*0b57cec5SDimitry Andric LValue CodeGenFunction:: 1348*0b57cec5SDimitry Andric EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E) { 1349*0b57cec5SDimitry Andric CompoundFunc Op = getComplexOp(E->getOpcode()); 1350*0b57cec5SDimitry Andric RValue Val; 1351*0b57cec5SDimitry Andric return ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val); 1352*0b57cec5SDimitry Andric } 1353*0b57cec5SDimitry Andric 1354*0b57cec5SDimitry Andric LValue CodeGenFunction:: 1355*0b57cec5SDimitry Andric EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, 1356*0b57cec5SDimitry Andric llvm::Value *&Result) { 1357*0b57cec5SDimitry Andric CompoundFunc Op = getComplexOp(E->getOpcode()); 1358*0b57cec5SDimitry Andric RValue Val; 1359*0b57cec5SDimitry Andric LValue Ret = ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val); 1360*0b57cec5SDimitry Andric Result = Val.getScalarVal(); 1361*0b57cec5SDimitry Andric return Ret; 1362*0b57cec5SDimitry Andric } 1363