xref: /src/contrib/llvm-project/clang/lib/CodeGen/CGExprComplex.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1ec2b103cSEd Schouten //===--- CGExprComplex.cpp - Emit LLVM Code for Complex Exprs -------------===//
2ec2b103cSEd Schouten //
322989816SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
422989816SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
522989816SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ec2b103cSEd Schouten //
7ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
8ec2b103cSEd Schouten //
9ec2b103cSEd Schouten // This contains code to emit Expr nodes with complex types as LLVM code.
10ec2b103cSEd Schouten //
11ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
12ec2b103cSEd Schouten 
13706b4fc4SDimitry Andric #include "CGOpenMPRuntime.h"
14ec2b103cSEd Schouten #include "CodeGenFunction.h"
15ec2b103cSEd Schouten #include "CodeGenModule.h"
16cfca06d7SDimitry Andric #include "ConstantEmitter.h"
17ec2b103cSEd Schouten #include "clang/AST/StmtVisitor.h"
1806d4ba38SDimitry Andric #include "llvm/ADT/STLExtras.h"
19809500fcSDimitry Andric #include "llvm/IR/Constants.h"
2006d4ba38SDimitry Andric #include "llvm/IR/Instructions.h"
2106d4ba38SDimitry Andric #include "llvm/IR/MDBuilder.h"
2206d4ba38SDimitry Andric #include "llvm/IR/Metadata.h"
23bfef3995SDimitry Andric #include <algorithm>
24ec2b103cSEd Schouten using namespace clang;
25ec2b103cSEd Schouten using namespace CodeGen;
26ec2b103cSEd Schouten 
27ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
28ec2b103cSEd Schouten //                        Complex Expression Emitter
29ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
30ec2b103cSEd Schouten 
31ac9a064cSDimitry Andric namespace llvm {
32ac9a064cSDimitry Andric extern cl::opt<bool> EnableSingleByteCoverage;
33ac9a064cSDimitry Andric } // namespace llvm
34ac9a064cSDimitry Andric 
35ec2b103cSEd Schouten typedef CodeGenFunction::ComplexPairTy ComplexPairTy;
36ec2b103cSEd Schouten 
37809500fcSDimitry Andric /// Return the complex type that we are meant to emit.
getComplexType(QualType type)38809500fcSDimitry Andric static const ComplexType *getComplexType(QualType type) {
39809500fcSDimitry Andric   type = type.getCanonicalType();
40809500fcSDimitry Andric   if (const ComplexType *comp = dyn_cast<ComplexType>(type)) {
41809500fcSDimitry Andric     return comp;
42809500fcSDimitry Andric   } else {
43809500fcSDimitry Andric     return cast<ComplexType>(cast<AtomicType>(type)->getValueType());
44809500fcSDimitry Andric   }
45809500fcSDimitry Andric }
46809500fcSDimitry Andric 
47ec2b103cSEd Schouten namespace  {
481569ce68SRoman Divacky class ComplexExprEmitter
49ec2b103cSEd Schouten   : public StmtVisitor<ComplexExprEmitter, ComplexPairTy> {
50ec2b103cSEd Schouten   CodeGenFunction &CGF;
51ec2b103cSEd Schouten   CGBuilderTy &Builder;
52ec2b103cSEd Schouten   bool IgnoreReal;
53ec2b103cSEd Schouten   bool IgnoreImag;
54ac9a064cSDimitry Andric   bool FPHasBeenPromoted;
55ac9a064cSDimitry Andric 
56ec2b103cSEd Schouten public:
ComplexExprEmitter(CodeGenFunction & cgf,bool ir=false,bool ii=false)57bca07a45SDimitry Andric   ComplexExprEmitter(CodeGenFunction &cgf, bool ir = false, bool ii = false)
58ac9a064cSDimitry Andric       : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii),
59ac9a064cSDimitry Andric         FPHasBeenPromoted(false) {}
60ec2b103cSEd Schouten 
61ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
62ec2b103cSEd Schouten   //                               Utilities
63ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
64ec2b103cSEd Schouten 
TestAndClearIgnoreReal()65ec2b103cSEd Schouten   bool TestAndClearIgnoreReal() {
66ec2b103cSEd Schouten     bool I = IgnoreReal;
67ec2b103cSEd Schouten     IgnoreReal = false;
68ec2b103cSEd Schouten     return I;
69ec2b103cSEd Schouten   }
TestAndClearIgnoreImag()70ec2b103cSEd Schouten   bool TestAndClearIgnoreImag() {
71ec2b103cSEd Schouten     bool I = IgnoreImag;
72ec2b103cSEd Schouten     IgnoreImag = false;
73ec2b103cSEd Schouten     return I;
74ec2b103cSEd Schouten   }
75ec2b103cSEd Schouten 
76ec2b103cSEd Schouten   /// EmitLoadOfLValue - Given an expression with complex type that represents a
77ec2b103cSEd Schouten   /// value l-value, this method emits the address of the l-value, then loads
78ec2b103cSEd Schouten   /// and returns the result.
EmitLoadOfLValue(const Expr * E)79ec2b103cSEd Schouten   ComplexPairTy EmitLoadOfLValue(const Expr *E) {
80bfef3995SDimitry Andric     return EmitLoadOfLValue(CGF.EmitLValue(E), E->getExprLoc());
81bca07a45SDimitry Andric   }
82bca07a45SDimitry Andric 
83bfef3995SDimitry Andric   ComplexPairTy EmitLoadOfLValue(LValue LV, SourceLocation Loc);
84bca07a45SDimitry Andric 
85ec2b103cSEd Schouten   /// EmitStoreOfComplex - Store the specified real/imag parts into the
86ec2b103cSEd Schouten   /// specified value pointer.
87809500fcSDimitry Andric   void EmitStoreOfComplex(ComplexPairTy Val, LValue LV, bool isInit);
88ec2b103cSEd Schouten 
8945b53394SDimitry Andric   /// Emit a cast from complex value Val to DestType.
90ec2b103cSEd Schouten   ComplexPairTy EmitComplexToComplexCast(ComplexPairTy Val, QualType SrcType,
9145b53394SDimitry Andric                                          QualType DestType, SourceLocation Loc);
9245b53394SDimitry Andric   /// Emit a cast from scalar value Val to DestType.
93bfef3995SDimitry Andric   ComplexPairTy EmitScalarToComplexCast(llvm::Value *Val, QualType SrcType,
9445b53394SDimitry Andric                                         QualType DestType, SourceLocation Loc);
95ec2b103cSEd Schouten 
96ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
97ec2b103cSEd Schouten   //                            Visitor Methods
98ec2b103cSEd Schouten   //===--------------------------------------------------------------------===//
99ec2b103cSEd Schouten 
Visit(Expr * E)100bca07a45SDimitry Andric   ComplexPairTy Visit(Expr *E) {
1015e20cdd8SDimitry Andric     ApplyDebugLocation DL(CGF, E);
102bca07a45SDimitry Andric     return StmtVisitor<ComplexExprEmitter, ComplexPairTy>::Visit(E);
103bca07a45SDimitry Andric   }
104bca07a45SDimitry Andric 
VisitStmt(Stmt * S)105ec2b103cSEd Schouten   ComplexPairTy VisitStmt(Stmt *S) {
106cfca06d7SDimitry Andric     S->dump(llvm::errs(), CGF.getContext());
10736981b17SDimitry Andric     llvm_unreachable("Stmt can't have complex result type!");
108ec2b103cSEd Schouten   }
109ec2b103cSEd Schouten   ComplexPairTy VisitExpr(Expr *S);
VisitConstantExpr(ConstantExpr * E)110676fbe81SDimitry Andric   ComplexPairTy VisitConstantExpr(ConstantExpr *E) {
111cfca06d7SDimitry Andric     if (llvm::Constant *Result = ConstantEmitter(CGF).tryEmitConstantExpr(E))
112cfca06d7SDimitry Andric       return ComplexPairTy(Result->getAggregateElement(0U),
113cfca06d7SDimitry Andric                            Result->getAggregateElement(1U));
114676fbe81SDimitry Andric     return Visit(E->getSubExpr());
115676fbe81SDimitry Andric   }
VisitParenExpr(ParenExpr * PE)116ec2b103cSEd Schouten   ComplexPairTy VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr());}
VisitGenericSelectionExpr(GenericSelectionExpr * GE)11701af97d3SDimitry Andric   ComplexPairTy VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
11801af97d3SDimitry Andric     return Visit(GE->getResultExpr());
11901af97d3SDimitry Andric   }
120ec2b103cSEd Schouten   ComplexPairTy VisitImaginaryLiteral(const ImaginaryLiteral *IL);
121180abc3dSDimitry Andric   ComplexPairTy
VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr * PE)122180abc3dSDimitry Andric   VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *PE) {
123180abc3dSDimitry Andric     return Visit(PE->getReplacement());
124180abc3dSDimitry Andric   }
VisitCoawaitExpr(CoawaitExpr * S)1257442d6faSDimitry Andric   ComplexPairTy VisitCoawaitExpr(CoawaitExpr *S) {
1267442d6faSDimitry Andric     return CGF.EmitCoawaitExpr(*S).getComplexVal();
1277442d6faSDimitry Andric   }
VisitCoyieldExpr(CoyieldExpr * S)1287442d6faSDimitry Andric   ComplexPairTy VisitCoyieldExpr(CoyieldExpr *S) {
1297442d6faSDimitry Andric     return CGF.EmitCoyieldExpr(*S).getComplexVal();
1307442d6faSDimitry Andric   }
VisitUnaryCoawait(const UnaryOperator * E)1317442d6faSDimitry Andric   ComplexPairTy VisitUnaryCoawait(const UnaryOperator *E) {
1327442d6faSDimitry Andric     return Visit(E->getSubExpr());
1337442d6faSDimitry Andric   }
1347442d6faSDimitry Andric 
emitConstant(const CodeGenFunction::ConstantEmission & Constant,Expr * E)135461a67faSDimitry Andric   ComplexPairTy emitConstant(const CodeGenFunction::ConstantEmission &Constant,
136461a67faSDimitry Andric                              Expr *E) {
137461a67faSDimitry Andric     assert(Constant && "not a constant");
138461a67faSDimitry Andric     if (Constant.isReference())
139461a67faSDimitry Andric       return EmitLoadOfLValue(Constant.getReferenceLValue(CGF, E),
140bfef3995SDimitry Andric                               E->getExprLoc());
141dbe13110SDimitry Andric 
142461a67faSDimitry Andric     llvm::Constant *pair = Constant.getValue();
143bfef3995SDimitry Andric     return ComplexPairTy(pair->getAggregateElement(0U),
144bfef3995SDimitry Andric                          pair->getAggregateElement(1U));
145dbe13110SDimitry Andric   }
146461a67faSDimitry Andric 
147461a67faSDimitry Andric   // l-values.
VisitDeclRefExpr(DeclRefExpr * E)148461a67faSDimitry Andric   ComplexPairTy VisitDeclRefExpr(DeclRefExpr *E) {
149461a67faSDimitry Andric     if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E))
150461a67faSDimitry Andric       return emitConstant(Constant, E);
1517ef7bab7SEd Schouten     return EmitLoadOfLValue(E);
1527ef7bab7SEd Schouten   }
VisitObjCIvarRefExpr(ObjCIvarRefExpr * E)153dbe13110SDimitry Andric   ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
1547ef7bab7SEd Schouten     return EmitLoadOfLValue(E);
1557ef7bab7SEd Schouten   }
VisitObjCMessageExpr(ObjCMessageExpr * E)1567ef7bab7SEd Schouten   ComplexPairTy VisitObjCMessageExpr(ObjCMessageExpr *E) {
1577ef7bab7SEd Schouten     return CGF.EmitObjCMessageExpr(E).getComplexVal();
1587ef7bab7SEd Schouten   }
VisitArraySubscriptExpr(Expr * E)159ec2b103cSEd Schouten   ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); }
VisitMemberExpr(MemberExpr * ME)160461a67faSDimitry Andric   ComplexPairTy VisitMemberExpr(MemberExpr *ME) {
161461a67faSDimitry Andric     if (CodeGenFunction::ConstantEmission Constant =
162461a67faSDimitry Andric             CGF.tryEmitAsConstant(ME)) {
163461a67faSDimitry Andric       CGF.EmitIgnoredExpr(ME->getBase());
164461a67faSDimitry Andric       return emitConstant(Constant, ME);
165461a67faSDimitry Andric     }
166461a67faSDimitry Andric     return EmitLoadOfLValue(ME);
167461a67faSDimitry Andric   }
VisitOpaqueValueExpr(OpaqueValueExpr * E)168bca07a45SDimitry Andric   ComplexPairTy VisitOpaqueValueExpr(OpaqueValueExpr *E) {
169bca07a45SDimitry Andric     if (E->isGLValue())
17048675466SDimitry Andric       return EmitLoadOfLValue(CGF.getOrCreateOpaqueLValueMapping(E),
17148675466SDimitry Andric                               E->getExprLoc());
17248675466SDimitry Andric     return CGF.getOrCreateOpaqueRValueMapping(E).getComplexVal();
173bca07a45SDimitry Andric   }
174ec2b103cSEd Schouten 
VisitPseudoObjectExpr(PseudoObjectExpr * E)175dbe13110SDimitry Andric   ComplexPairTy VisitPseudoObjectExpr(PseudoObjectExpr *E) {
176dbe13110SDimitry Andric     return CGF.EmitPseudoObjectRValue(E).getComplexVal();
177dbe13110SDimitry Andric   }
178dbe13110SDimitry Andric 
179ec2b103cSEd Schouten   // FIXME: CompoundLiteralExpr
180ec2b103cSEd Schouten 
18106d4ba38SDimitry Andric   ComplexPairTy EmitCast(CastKind CK, Expr *Op, QualType DestTy);
VisitImplicitCastExpr(ImplicitCastExpr * E)182ec2b103cSEd Schouten   ComplexPairTy VisitImplicitCastExpr(ImplicitCastExpr *E) {
183ec2b103cSEd Schouten     // Unlike for scalars, we don't have to worry about function->ptr demotion
184ec2b103cSEd Schouten     // here.
185b1c73532SDimitry Andric     if (E->changesVolatileQualification())
186b1c73532SDimitry Andric       return EmitLoadOfLValue(E);
1874e58654bSRoman Divacky     return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType());
188ec2b103cSEd Schouten   }
VisitCastExpr(CastExpr * E)189ec2b103cSEd Schouten   ComplexPairTy VisitCastExpr(CastExpr *E) {
19045b53394SDimitry Andric     if (const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
19145b53394SDimitry Andric       CGF.CGM.EmitExplicitCastExprType(ECE, &CGF);
192b1c73532SDimitry Andric     if (E->changesVolatileQualification())
193b1c73532SDimitry Andric        return EmitLoadOfLValue(E);
1944e58654bSRoman Divacky     return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType());
195ec2b103cSEd Schouten   }
196ec2b103cSEd Schouten   ComplexPairTy VisitCallExpr(const CallExpr *E);
197ec2b103cSEd Schouten   ComplexPairTy VisitStmtExpr(const StmtExpr *E);
198ec2b103cSEd Schouten 
199ec2b103cSEd Schouten   // Operators.
VisitPrePostIncDec(const UnaryOperator * E,bool isInc,bool isPre)200ec2b103cSEd Schouten   ComplexPairTy VisitPrePostIncDec(const UnaryOperator *E,
201ee791ddeSRoman Divacky                                    bool isInc, bool isPre) {
202ee791ddeSRoman Divacky     LValue LV = CGF.EmitLValue(E->getSubExpr());
203ee791ddeSRoman Divacky     return CGF.EmitComplexPrePostIncDec(E, LV, isInc, isPre);
204ee791ddeSRoman Divacky   }
VisitUnaryPostDec(const UnaryOperator * E)205ec2b103cSEd Schouten   ComplexPairTy VisitUnaryPostDec(const UnaryOperator *E) {
206ec2b103cSEd Schouten     return VisitPrePostIncDec(E, false, false);
207ec2b103cSEd Schouten   }
VisitUnaryPostInc(const UnaryOperator * E)208ec2b103cSEd Schouten   ComplexPairTy VisitUnaryPostInc(const UnaryOperator *E) {
209ec2b103cSEd Schouten     return VisitPrePostIncDec(E, true, false);
210ec2b103cSEd Schouten   }
VisitUnaryPreDec(const UnaryOperator * E)211ec2b103cSEd Schouten   ComplexPairTy VisitUnaryPreDec(const UnaryOperator *E) {
212ec2b103cSEd Schouten     return VisitPrePostIncDec(E, false, true);
213ec2b103cSEd Schouten   }
VisitUnaryPreInc(const UnaryOperator * E)214ec2b103cSEd Schouten   ComplexPairTy VisitUnaryPreInc(const UnaryOperator *E) {
215ec2b103cSEd Schouten     return VisitPrePostIncDec(E, true, true);
216ec2b103cSEd Schouten   }
VisitUnaryDeref(const Expr * E)217ec2b103cSEd Schouten   ComplexPairTy VisitUnaryDeref(const Expr *E) { return EmitLoadOfLValue(E); }
218e3b55780SDimitry Andric 
219e3b55780SDimitry Andric   ComplexPairTy VisitUnaryPlus(const UnaryOperator *E,
220e3b55780SDimitry Andric                                QualType PromotionType = QualType());
221e3b55780SDimitry Andric   ComplexPairTy VisitPlus(const UnaryOperator *E, QualType PromotionType);
222e3b55780SDimitry Andric   ComplexPairTy VisitUnaryMinus(const UnaryOperator *E,
223e3b55780SDimitry Andric                                 QualType PromotionType = QualType());
224e3b55780SDimitry Andric   ComplexPairTy VisitMinus(const UnaryOperator *E, QualType PromotionType);
225ec2b103cSEd Schouten   ComplexPairTy VisitUnaryNot      (const UnaryOperator *E);
226ec2b103cSEd Schouten   // LNot,Real,Imag never return complex.
VisitUnaryExtension(const UnaryOperator * E)227ec2b103cSEd Schouten   ComplexPairTy VisitUnaryExtension(const UnaryOperator *E) {
228ec2b103cSEd Schouten     return Visit(E->getSubExpr());
229ec2b103cSEd Schouten   }
VisitCXXDefaultArgExpr(CXXDefaultArgExpr * DAE)230ec2b103cSEd Schouten   ComplexPairTy VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
23122989816SDimitry Andric     CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
232ec2b103cSEd Schouten     return Visit(DAE->getExpr());
233ec2b103cSEd Schouten   }
VisitCXXDefaultInitExpr(CXXDefaultInitExpr * DIE)2346a037251SDimitry Andric   ComplexPairTy VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
23522989816SDimitry Andric     CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
2366a037251SDimitry Andric     return Visit(DIE->getExpr());
2376a037251SDimitry Andric   }
VisitExprWithCleanups(ExprWithCleanups * E)238bca07a45SDimitry Andric   ComplexPairTy VisitExprWithCleanups(ExprWithCleanups *E) {
239dbe13110SDimitry Andric     CodeGenFunction::RunCleanupsScope Scope(CGF);
2407442d6faSDimitry Andric     ComplexPairTy Vals = Visit(E->getSubExpr());
2417442d6faSDimitry Andric     // Defend against dominance problems caused by jumps out of expression
2427442d6faSDimitry Andric     // evaluation through the shared cleanup block.
2437442d6faSDimitry Andric     Scope.ForceCleanup({&Vals.first, &Vals.second});
2447442d6faSDimitry Andric     return Vals;
245ec2b103cSEd Schouten   }
VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr * E)2464ba67500SRoman Divacky   ComplexPairTy VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
247ec2b103cSEd Schouten     assert(E->getType()->isAnyComplexType() && "Expected complex type!");
248809500fcSDimitry Andric     QualType Elem = E->getType()->castAs<ComplexType>()->getElementType();
249ec2b103cSEd Schouten     llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem));
250ec2b103cSEd Schouten     return ComplexPairTy(Null, Null);
251ec2b103cSEd Schouten   }
VisitImplicitValueInitExpr(ImplicitValueInitExpr * E)252ec2b103cSEd Schouten   ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
253ec2b103cSEd Schouten     assert(E->getType()->isAnyComplexType() && "Expected complex type!");
254809500fcSDimitry Andric     QualType Elem = E->getType()->castAs<ComplexType>()->getElementType();
2554c8b2481SRoman Divacky     llvm::Constant *Null =
2564c8b2481SRoman Divacky                        llvm::Constant::getNullValue(CGF.ConvertType(Elem));
257ec2b103cSEd Schouten     return ComplexPairTy(Null, Null);
258ec2b103cSEd Schouten   }
259ec2b103cSEd Schouten 
260ec2b103cSEd Schouten   struct BinOpInfo {
261ec2b103cSEd Schouten     ComplexPairTy LHS;
262ec2b103cSEd Schouten     ComplexPairTy RHS;
263ec2b103cSEd Schouten     QualType Ty;  // Computation Type.
264e3b55780SDimitry Andric     FPOptions FPFeatures;
265ec2b103cSEd Schouten   };
266ec2b103cSEd Schouten 
267e3b55780SDimitry Andric   BinOpInfo EmitBinOps(const BinaryOperator *E,
268e3b55780SDimitry Andric                        QualType PromotionTy = QualType());
269e3b55780SDimitry Andric   ComplexPairTy EmitPromoted(const Expr *E, QualType PromotionTy);
270e3b55780SDimitry Andric   ComplexPairTy EmitPromotedComplexOperand(const Expr *E, QualType PromotionTy);
271bca07a45SDimitry Andric   LValue EmitCompoundAssignLValue(const CompoundAssignOperator *E,
272bca07a45SDimitry Andric                                   ComplexPairTy (ComplexExprEmitter::*Func)
273bca07a45SDimitry Andric                                   (const BinOpInfo &),
274bfef3995SDimitry Andric                                   RValue &Val);
275ec2b103cSEd Schouten   ComplexPairTy EmitCompoundAssign(const CompoundAssignOperator *E,
276ec2b103cSEd Schouten                                    ComplexPairTy (ComplexExprEmitter::*Func)
277ec2b103cSEd Schouten                                    (const BinOpInfo &));
278ec2b103cSEd Schouten 
279ec2b103cSEd Schouten   ComplexPairTy EmitBinAdd(const BinOpInfo &Op);
280ec2b103cSEd Schouten   ComplexPairTy EmitBinSub(const BinOpInfo &Op);
281ec2b103cSEd Schouten   ComplexPairTy EmitBinMul(const BinOpInfo &Op);
282ec2b103cSEd Schouten   ComplexPairTy EmitBinDiv(const BinOpInfo &Op);
283312c0ed1SDimitry Andric   ComplexPairTy EmitAlgebraicDiv(llvm::Value *A, llvm::Value *B, llvm::Value *C,
284312c0ed1SDimitry Andric                                  llvm::Value *D);
285312c0ed1SDimitry Andric   ComplexPairTy EmitRangeReductionDiv(llvm::Value *A, llvm::Value *B,
286312c0ed1SDimitry Andric                                       llvm::Value *C, llvm::Value *D);
287ec2b103cSEd Schouten 
28806d4ba38SDimitry Andric   ComplexPairTy EmitComplexBinOpLibCall(StringRef LibCallName,
28906d4ba38SDimitry Andric                                         const BinOpInfo &Op);
29006d4ba38SDimitry Andric 
GetHigherPrecisionFPType(QualType ElementType)291ac9a064cSDimitry Andric   QualType GetHigherPrecisionFPType(QualType ElementType) {
292ac9a064cSDimitry Andric     const auto *CurrentBT = cast<BuiltinType>(ElementType);
293ac9a064cSDimitry Andric     switch (CurrentBT->getKind()) {
294ac9a064cSDimitry Andric     case BuiltinType::Kind::Float16:
295ac9a064cSDimitry Andric       return CGF.getContext().FloatTy;
296ac9a064cSDimitry Andric     case BuiltinType::Kind::Float:
297ac9a064cSDimitry Andric     case BuiltinType::Kind::BFloat16:
298ac9a064cSDimitry Andric       return CGF.getContext().DoubleTy;
299ac9a064cSDimitry Andric     case BuiltinType::Kind::Double:
300ac9a064cSDimitry Andric       return CGF.getContext().LongDoubleTy;
301ac9a064cSDimitry Andric     default:
302ac9a064cSDimitry Andric       return ElementType;
303ac9a064cSDimitry Andric     }
304ac9a064cSDimitry Andric   }
305ac9a064cSDimitry Andric 
HigherPrecisionTypeForComplexArithmetic(QualType ElementType,bool IsDivOpCode)306ac9a064cSDimitry Andric   QualType HigherPrecisionTypeForComplexArithmetic(QualType ElementType,
307ac9a064cSDimitry Andric                                                    bool IsDivOpCode) {
308ac9a064cSDimitry Andric     QualType HigherElementType = GetHigherPrecisionFPType(ElementType);
309ac9a064cSDimitry Andric     const llvm::fltSemantics &ElementTypeSemantics =
310ac9a064cSDimitry Andric         CGF.getContext().getFloatTypeSemantics(ElementType);
311ac9a064cSDimitry Andric     const llvm::fltSemantics &HigherElementTypeSemantics =
312ac9a064cSDimitry Andric         CGF.getContext().getFloatTypeSemantics(HigherElementType);
313ac9a064cSDimitry Andric     // Check that the promoted type can handle the intermediate values without
314ac9a064cSDimitry Andric     // overflowing. This can be interpreted as:
315ac9a064cSDimitry Andric     // (SmallerType.LargestFiniteVal * SmallerType.LargestFiniteVal) * 2 <=
316ac9a064cSDimitry Andric     // LargerType.LargestFiniteVal.
317ac9a064cSDimitry Andric     // In terms of exponent it gives this formula:
318ac9a064cSDimitry Andric     // (SmallerType.LargestFiniteVal * SmallerType.LargestFiniteVal
319ac9a064cSDimitry Andric     // doubles the exponent of SmallerType.LargestFiniteVal)
320ac9a064cSDimitry Andric     if (llvm::APFloat::semanticsMaxExponent(ElementTypeSemantics) * 2 + 1 <=
321ac9a064cSDimitry Andric         llvm::APFloat::semanticsMaxExponent(HigherElementTypeSemantics)) {
322ac9a064cSDimitry Andric       FPHasBeenPromoted = true;
323ac9a064cSDimitry Andric       return CGF.getContext().getComplexType(HigherElementType);
324ac9a064cSDimitry Andric     } else {
325ac9a064cSDimitry Andric       DiagnosticsEngine &Diags = CGF.CGM.getDiags();
326ac9a064cSDimitry Andric       Diags.Report(diag::warn_next_larger_fp_type_same_size_than_fp);
327ac9a064cSDimitry Andric       return QualType();
328ac9a064cSDimitry Andric     }
329ac9a064cSDimitry Andric   }
330ac9a064cSDimitry Andric 
getPromotionType(FPOptionsOverride Features,QualType Ty,bool IsDivOpCode=false)331ac9a064cSDimitry Andric   QualType getPromotionType(FPOptionsOverride Features, QualType Ty,
332ac9a064cSDimitry Andric                             bool IsDivOpCode = false) {
333e3b55780SDimitry Andric     if (auto *CT = Ty->getAs<ComplexType>()) {
334e3b55780SDimitry Andric       QualType ElementType = CT->getElementType();
335ac9a064cSDimitry Andric       bool IsFloatingType = ElementType->isFloatingType();
336ac9a064cSDimitry Andric       bool IsComplexRangePromoted = CGF.getLangOpts().getComplexRange() ==
337ac9a064cSDimitry Andric                                     LangOptions::ComplexRangeKind::CX_Promoted;
338ac9a064cSDimitry Andric       bool HasNoComplexRangeOverride = !Features.hasComplexRangeOverride();
339ac9a064cSDimitry Andric       bool HasMatchingComplexRange = Features.hasComplexRangeOverride() &&
340ac9a064cSDimitry Andric                                      Features.getComplexRangeOverride() ==
341ac9a064cSDimitry Andric                                          CGF.getLangOpts().getComplexRange();
342ac9a064cSDimitry Andric 
343ac9a064cSDimitry Andric       if (IsDivOpCode && IsFloatingType && IsComplexRangePromoted &&
344ac9a064cSDimitry Andric           (HasNoComplexRangeOverride || HasMatchingComplexRange))
345ac9a064cSDimitry Andric         return HigherPrecisionTypeForComplexArithmetic(ElementType,
346ac9a064cSDimitry Andric                                                        IsDivOpCode);
347e3b55780SDimitry Andric       if (ElementType.UseExcessPrecision(CGF.getContext()))
348e3b55780SDimitry Andric         return CGF.getContext().getComplexType(CGF.getContext().FloatTy);
349ec2b103cSEd Schouten     }
350e3b55780SDimitry Andric     if (Ty.UseExcessPrecision(CGF.getContext()))
351e3b55780SDimitry Andric       return CGF.getContext().FloatTy;
352e3b55780SDimitry Andric     return QualType();
353ec2b103cSEd Schouten   }
354e3b55780SDimitry Andric 
355e3b55780SDimitry Andric #define HANDLEBINOP(OP)                                                        \
356e3b55780SDimitry Andric   ComplexPairTy VisitBin##OP(const BinaryOperator *E) {                        \
357ac9a064cSDimitry Andric     QualType promotionTy = getPromotionType(                                   \
358ac9a064cSDimitry Andric         E->getStoredFPFeaturesOrDefault(), E->getType(),                       \
359ac9a064cSDimitry Andric         (E->getOpcode() == BinaryOperatorKind::BO_Div) ? true : false);        \
360e3b55780SDimitry Andric     ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy));            \
361e3b55780SDimitry Andric     if (!promotionTy.isNull())                                                 \
362ac9a064cSDimitry Andric       result = CGF.EmitUnPromotedValue(result, E->getType());                  \
363e3b55780SDimitry Andric     return result;                                                             \
364bca07a45SDimitry Andric   }
365e3b55780SDimitry Andric 
366e3b55780SDimitry Andric   HANDLEBINOP(Mul)
HANDLEBINOP(Div)367e3b55780SDimitry Andric   HANDLEBINOP(Div)
368e3b55780SDimitry Andric   HANDLEBINOP(Add)
369e3b55780SDimitry Andric   HANDLEBINOP(Sub)
370e3b55780SDimitry Andric #undef HANDLEBINOP
371ec2b103cSEd Schouten 
372519fc96cSDimitry Andric   ComplexPairTy VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
373519fc96cSDimitry Andric     return Visit(E->getSemanticForm());
374519fc96cSDimitry Andric   }
375519fc96cSDimitry Andric 
376ec2b103cSEd Schouten   // Compound assignments.
VisitBinAddAssign(const CompoundAssignOperator * E)377ec2b103cSEd Schouten   ComplexPairTy VisitBinAddAssign(const CompoundAssignOperator *E) {
378ec2b103cSEd Schouten     return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd);
379ec2b103cSEd Schouten   }
VisitBinSubAssign(const CompoundAssignOperator * E)380ec2b103cSEd Schouten   ComplexPairTy VisitBinSubAssign(const CompoundAssignOperator *E) {
381ec2b103cSEd Schouten     return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub);
382ec2b103cSEd Schouten   }
VisitBinMulAssign(const CompoundAssignOperator * E)383ec2b103cSEd Schouten   ComplexPairTy VisitBinMulAssign(const CompoundAssignOperator *E) {
384ec2b103cSEd Schouten     return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul);
385ec2b103cSEd Schouten   }
VisitBinDivAssign(const CompoundAssignOperator * E)386ec2b103cSEd Schouten   ComplexPairTy VisitBinDivAssign(const CompoundAssignOperator *E) {
387ec2b103cSEd Schouten     return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv);
388ec2b103cSEd Schouten   }
389ec2b103cSEd Schouten 
390ec2b103cSEd Schouten   // GCC rejects rem/and/or/xor for integer complex.
391ec2b103cSEd Schouten   // Logical and/or always return int, never complex.
392ec2b103cSEd Schouten 
393ec2b103cSEd Schouten   // No comparisons produce a complex result.
394bca07a45SDimitry Andric 
395bca07a45SDimitry Andric   LValue EmitBinAssignLValue(const BinaryOperator *E,
396bca07a45SDimitry Andric                              ComplexPairTy &Val);
397ec2b103cSEd Schouten   ComplexPairTy VisitBinAssign     (const BinaryOperator *E);
398ec2b103cSEd Schouten   ComplexPairTy VisitBinComma      (const BinaryOperator *E);
399ec2b103cSEd Schouten 
400ec2b103cSEd Schouten 
401bca07a45SDimitry Andric   ComplexPairTy
402bca07a45SDimitry Andric   VisitAbstractConditionalOperator(const AbstractConditionalOperator *CO);
403ec2b103cSEd Schouten   ComplexPairTy VisitChooseExpr(ChooseExpr *CE);
404ec2b103cSEd Schouten 
405ec2b103cSEd Schouten   ComplexPairTy VisitInitListExpr(InitListExpr *E);
406ec2b103cSEd Schouten 
VisitCompoundLiteralExpr(CompoundLiteralExpr * E)407dbe13110SDimitry Andric   ComplexPairTy VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
408dbe13110SDimitry Andric     return EmitLoadOfLValue(E);
409dbe13110SDimitry Andric   }
410dbe13110SDimitry Andric 
411ec2b103cSEd Schouten   ComplexPairTy VisitVAArgExpr(VAArgExpr *E);
41236981b17SDimitry Andric 
VisitAtomicExpr(AtomicExpr * E)41336981b17SDimitry Andric   ComplexPairTy VisitAtomicExpr(AtomicExpr *E) {
41436981b17SDimitry Andric     return CGF.EmitAtomicExpr(E).getComplexVal();
41536981b17SDimitry Andric   }
416ac9a064cSDimitry Andric 
VisitPackIndexingExpr(PackIndexingExpr * E)417ac9a064cSDimitry Andric   ComplexPairTy VisitPackIndexingExpr(PackIndexingExpr *E) {
418ac9a064cSDimitry Andric     return Visit(E->getSelectedExpr());
419ac9a064cSDimitry Andric   }
420ec2b103cSEd Schouten };
421ec2b103cSEd Schouten }  // end anonymous namespace.
422ec2b103cSEd Schouten 
423ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
424ec2b103cSEd Schouten //                                Utilities
425ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
426ec2b103cSEd Schouten 
emitAddrOfRealComponent(Address addr,QualType complexType)42745b53394SDimitry Andric Address CodeGenFunction::emitAddrOfRealComponent(Address addr,
42845b53394SDimitry Andric                                                  QualType complexType) {
42922989816SDimitry Andric   return Builder.CreateStructGEP(addr, 0, addr.getName() + ".realp");
43045b53394SDimitry Andric }
43145b53394SDimitry Andric 
emitAddrOfImagComponent(Address addr,QualType complexType)43245b53394SDimitry Andric Address CodeGenFunction::emitAddrOfImagComponent(Address addr,
43345b53394SDimitry Andric                                                  QualType complexType) {
43422989816SDimitry Andric   return Builder.CreateStructGEP(addr, 1, addr.getName() + ".imagp");
43545b53394SDimitry Andric }
43645b53394SDimitry Andric 
437809500fcSDimitry Andric /// EmitLoadOfLValue - Given an RValue reference for a complex, emit code to
438ec2b103cSEd Schouten /// load the real and imaginary pieces, returning them as Real/Imag.
EmitLoadOfLValue(LValue lvalue,SourceLocation loc)439bfef3995SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitLoadOfLValue(LValue lvalue,
440bfef3995SDimitry Andric                                                    SourceLocation loc) {
441809500fcSDimitry Andric   assert(lvalue.isSimple() && "non-simple complex l-value?");
442809500fcSDimitry Andric   if (lvalue.getType()->isAtomicType())
443bfef3995SDimitry Andric     return CGF.EmitAtomicLoad(lvalue, loc).getComplexVal();
444809500fcSDimitry Andric 
445ac9a064cSDimitry Andric   Address SrcPtr = lvalue.getAddress();
446809500fcSDimitry Andric   bool isVolatile = lvalue.isVolatileQualified();
447809500fcSDimitry Andric 
4489f4dbff6SDimitry Andric   llvm::Value *Real = nullptr, *Imag = nullptr;
449ec2b103cSEd Schouten 
450bca07a45SDimitry Andric   if (!IgnoreReal || isVolatile) {
45145b53394SDimitry Andric     Address RealP = CGF.emitAddrOfRealComponent(SrcPtr, lvalue.getType());
45245b53394SDimitry Andric     Real = Builder.CreateLoad(RealP, isVolatile, SrcPtr.getName() + ".real");
453ec2b103cSEd Schouten   }
454ec2b103cSEd Schouten 
455bca07a45SDimitry Andric   if (!IgnoreImag || isVolatile) {
45645b53394SDimitry Andric     Address ImagP = CGF.emitAddrOfImagComponent(SrcPtr, lvalue.getType());
45745b53394SDimitry Andric     Imag = Builder.CreateLoad(ImagP, isVolatile, SrcPtr.getName() + ".imag");
458ec2b103cSEd Schouten   }
45945b53394SDimitry Andric 
460ec2b103cSEd Schouten   return ComplexPairTy(Real, Imag);
461ec2b103cSEd Schouten }
462ec2b103cSEd Schouten 
463ec2b103cSEd Schouten /// EmitStoreOfComplex - Store the specified real/imag parts into the
464ec2b103cSEd Schouten /// specified value pointer.
EmitStoreOfComplex(ComplexPairTy Val,LValue lvalue,bool isInit)46506d4ba38SDimitry Andric void ComplexExprEmitter::EmitStoreOfComplex(ComplexPairTy Val, LValue lvalue,
466809500fcSDimitry Andric                                             bool isInit) {
4675e20cdd8SDimitry Andric   if (lvalue.getType()->isAtomicType() ||
4685e20cdd8SDimitry Andric       (!isInit && CGF.LValueIsSuitableForInlineAtomic(lvalue)))
469809500fcSDimitry Andric     return CGF.EmitAtomicStore(RValue::getComplex(Val), lvalue, isInit);
470809500fcSDimitry Andric 
471ac9a064cSDimitry Andric   Address Ptr = lvalue.getAddress();
47245b53394SDimitry Andric   Address RealPtr = CGF.emitAddrOfRealComponent(Ptr, lvalue.getType());
47345b53394SDimitry Andric   Address ImagPtr = CGF.emitAddrOfImagComponent(Ptr, lvalue.getType());
474ec2b103cSEd Schouten 
47545b53394SDimitry Andric   Builder.CreateStore(Val.first, RealPtr, lvalue.isVolatileQualified());
47645b53394SDimitry Andric   Builder.CreateStore(Val.second, ImagPtr, lvalue.isVolatileQualified());
477ec2b103cSEd Schouten }
478ec2b103cSEd Schouten 
479ec2b103cSEd Schouten 
480ec2b103cSEd Schouten 
481ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
482ec2b103cSEd Schouten //                            Visitor Methods
483ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
484ec2b103cSEd Schouten 
VisitExpr(Expr * E)485ec2b103cSEd Schouten ComplexPairTy ComplexExprEmitter::VisitExpr(Expr *E) {
486ec2b103cSEd Schouten   CGF.ErrorUnsupported(E, "complex expression");
48736981b17SDimitry Andric   llvm::Type *EltTy =
488809500fcSDimitry Andric     CGF.ConvertType(getComplexType(E->getType())->getElementType());
489ec2b103cSEd Schouten   llvm::Value *U = llvm::UndefValue::get(EltTy);
490ec2b103cSEd Schouten   return ComplexPairTy(U, U);
491ec2b103cSEd Schouten }
492ec2b103cSEd Schouten 
493ec2b103cSEd Schouten ComplexPairTy ComplexExprEmitter::
VisitImaginaryLiteral(const ImaginaryLiteral * IL)494ec2b103cSEd Schouten VisitImaginaryLiteral(const ImaginaryLiteral *IL) {
495ec2b103cSEd Schouten   llvm::Value *Imag = CGF.EmitScalarExpr(IL->getSubExpr());
496bca07a45SDimitry Andric   return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag);
497ec2b103cSEd Schouten }
498ec2b103cSEd Schouten 
499ec2b103cSEd Schouten 
VisitCallExpr(const CallExpr * E)500ec2b103cSEd Schouten ComplexPairTy ComplexExprEmitter::VisitCallExpr(const CallExpr *E) {
5015e20cdd8SDimitry Andric   if (E->getCallReturnType(CGF.getContext())->isReferenceType())
502ec2b103cSEd Schouten     return EmitLoadOfLValue(E);
503ec2b103cSEd Schouten 
504ec2b103cSEd Schouten   return CGF.EmitCallExpr(E).getComplexVal();
505ec2b103cSEd Schouten }
506ec2b103cSEd Schouten 
VisitStmtExpr(const StmtExpr * E)507ec2b103cSEd Schouten ComplexPairTy ComplexExprEmitter::VisitStmtExpr(const StmtExpr *E) {
508bca07a45SDimitry Andric   CodeGenFunction::StmtExprEvaluation eval(CGF);
50945b53394SDimitry Andric   Address RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(), true);
51045b53394SDimitry Andric   assert(RetAlloca.isValid() && "Expected complex return value");
511bfef3995SDimitry Andric   return EmitLoadOfLValue(CGF.MakeAddrLValue(RetAlloca, E->getType()),
512bfef3995SDimitry Andric                           E->getExprLoc());
513ec2b103cSEd Schouten }
514ec2b103cSEd Schouten 
51545b53394SDimitry Andric /// Emit a cast from complex value Val to DestType.
EmitComplexToComplexCast(ComplexPairTy Val,QualType SrcType,QualType DestType,SourceLocation Loc)516ec2b103cSEd Schouten ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,
517ec2b103cSEd Schouten                                                            QualType SrcType,
51845b53394SDimitry Andric                                                            QualType DestType,
51945b53394SDimitry Andric                                                            SourceLocation Loc) {
520ec2b103cSEd Schouten   // Get the src/dest element type.
521809500fcSDimitry Andric   SrcType = SrcType->castAs<ComplexType>()->getElementType();
522809500fcSDimitry Andric   DestType = DestType->castAs<ComplexType>()->getElementType();
523ec2b103cSEd Schouten 
524ec2b103cSEd Schouten   // C99 6.3.1.6: When a value of complex type is converted to another
525ec2b103cSEd Schouten   // complex type, both the real and imaginary parts follow the conversion
526ec2b103cSEd Schouten   // rules for the corresponding real types.
527cfca06d7SDimitry Andric   if (Val.first)
52845b53394SDimitry Andric     Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType, Loc);
529cfca06d7SDimitry Andric   if (Val.second)
53045b53394SDimitry Andric     Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType, Loc);
531ec2b103cSEd Schouten   return Val;
532ec2b103cSEd Schouten }
533ec2b103cSEd Schouten 
EmitScalarToComplexCast(llvm::Value * Val,QualType SrcType,QualType DestType,SourceLocation Loc)534bfef3995SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val,
535bfef3995SDimitry Andric                                                           QualType SrcType,
53645b53394SDimitry Andric                                                           QualType DestType,
53745b53394SDimitry Andric                                                           SourceLocation Loc) {
538bfef3995SDimitry Andric   // Convert the input element to the element type of the complex.
539bfef3995SDimitry Andric   DestType = DestType->castAs<ComplexType>()->getElementType();
54045b53394SDimitry Andric   Val = CGF.EmitScalarConversion(Val, SrcType, DestType, Loc);
541bfef3995SDimitry Andric 
542bfef3995SDimitry Andric   // Return (realval, 0).
543bfef3995SDimitry Andric   return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType()));
544bfef3995SDimitry Andric }
545bfef3995SDimitry Andric 
EmitCast(CastKind CK,Expr * Op,QualType DestTy)54606d4ba38SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op,
5474e58654bSRoman Divacky                                            QualType DestTy) {
548bca07a45SDimitry Andric   switch (CK) {
549180abc3dSDimitry Andric   case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!");
550180abc3dSDimitry Andric 
551dbe13110SDimitry Andric   // Atomic to non-atomic casts may be more than a no-op for some platforms and
552dbe13110SDimitry Andric   // for some types.
553dbe13110SDimitry Andric   case CK_AtomicToNonAtomic:
554dbe13110SDimitry Andric   case CK_NonAtomicToAtomic:
555bca07a45SDimitry Andric   case CK_NoOp:
556bca07a45SDimitry Andric   case CK_LValueToRValue:
557180abc3dSDimitry Andric   case CK_UserDefinedConversion:
558bca07a45SDimitry Andric     return Visit(Op);
559bca07a45SDimitry Andric 
560180abc3dSDimitry Andric   case CK_LValueBitCast: {
561809500fcSDimitry Andric     LValue origLV = CGF.EmitLValue(Op);
562ac9a064cSDimitry Andric     Address V = origLV.getAddress().withElementType(CGF.ConvertType(DestTy));
56345b53394SDimitry Andric     return EmitLoadOfLValue(CGF.MakeAddrLValue(V, DestTy), Op->getExprLoc());
5644e58654bSRoman Divacky   }
5654e58654bSRoman Divacky 
56622989816SDimitry Andric   case CK_LValueToRValueBitCast: {
56722989816SDimitry Andric     LValue SourceLVal = CGF.EmitLValue(Op);
568ac9a064cSDimitry Andric     Address Addr =
569ac9a064cSDimitry Andric         SourceLVal.getAddress().withElementType(CGF.ConvertTypeForMem(DestTy));
57022989816SDimitry Andric     LValue DestLV = CGF.MakeAddrLValue(Addr, DestTy);
57122989816SDimitry Andric     DestLV.setTBAAInfo(TBAAAccessInfo::getMayAliasInfo());
57222989816SDimitry Andric     return EmitLoadOfLValue(DestLV, Op->getExprLoc());
57322989816SDimitry Andric   }
57422989816SDimitry Andric 
575180abc3dSDimitry Andric   case CK_BitCast:
576180abc3dSDimitry Andric   case CK_BaseToDerived:
577180abc3dSDimitry Andric   case CK_DerivedToBase:
578180abc3dSDimitry Andric   case CK_UncheckedDerivedToBase:
579180abc3dSDimitry Andric   case CK_Dynamic:
580180abc3dSDimitry Andric   case CK_ToUnion:
581180abc3dSDimitry Andric   case CK_ArrayToPointerDecay:
582180abc3dSDimitry Andric   case CK_FunctionToPointerDecay:
583180abc3dSDimitry Andric   case CK_NullToPointer:
584180abc3dSDimitry Andric   case CK_NullToMemberPointer:
585180abc3dSDimitry Andric   case CK_BaseToDerivedMemberPointer:
586180abc3dSDimitry Andric   case CK_DerivedToBaseMemberPointer:
587180abc3dSDimitry Andric   case CK_MemberPointerToBoolean:
588dbe13110SDimitry Andric   case CK_ReinterpretMemberPointer:
589180abc3dSDimitry Andric   case CK_ConstructorConversion:
590180abc3dSDimitry Andric   case CK_IntegralToPointer:
591180abc3dSDimitry Andric   case CK_PointerToIntegral:
592180abc3dSDimitry Andric   case CK_PointerToBoolean:
593180abc3dSDimitry Andric   case CK_ToVoid:
594180abc3dSDimitry Andric   case CK_VectorSplat:
595180abc3dSDimitry Andric   case CK_IntegralCast:
5960414e226SDimitry Andric   case CK_BooleanToSignedIntegral:
597180abc3dSDimitry Andric   case CK_IntegralToBoolean:
598180abc3dSDimitry Andric   case CK_IntegralToFloating:
599180abc3dSDimitry Andric   case CK_FloatingToIntegral:
600180abc3dSDimitry Andric   case CK_FloatingToBoolean:
601180abc3dSDimitry Andric   case CK_FloatingCast:
60236981b17SDimitry Andric   case CK_CPointerToObjCPointerCast:
60336981b17SDimitry Andric   case CK_BlockPointerToObjCPointerCast:
604180abc3dSDimitry Andric   case CK_AnyPointerToBlockPointerCast:
605180abc3dSDimitry Andric   case CK_ObjCObjectLValueCast:
606180abc3dSDimitry Andric   case CK_FloatingComplexToReal:
607180abc3dSDimitry Andric   case CK_FloatingComplexToBoolean:
608180abc3dSDimitry Andric   case CK_IntegralComplexToReal:
609180abc3dSDimitry Andric   case CK_IntegralComplexToBoolean:
61036981b17SDimitry Andric   case CK_ARCProduceObject:
61136981b17SDimitry Andric   case CK_ARCConsumeObject:
61236981b17SDimitry Andric   case CK_ARCReclaimReturnedObject:
61336981b17SDimitry Andric   case CK_ARCExtendBlockObject:
614dbe13110SDimitry Andric   case CK_CopyAndAutoreleaseBlockObject:
61513cc256eSDimitry Andric   case CK_BuiltinFnToFnPtr:
616676fbe81SDimitry Andric   case CK_ZeroToOCLOpaqueType:
6179f4dbff6SDimitry Andric   case CK_AddressSpaceConversion:
618bab175ecSDimitry Andric   case CK_IntToOCLSampler:
619b60736ecSDimitry Andric   case CK_FloatingToFixedPoint:
620b60736ecSDimitry Andric   case CK_FixedPointToFloating:
621676fbe81SDimitry Andric   case CK_FixedPointCast:
622676fbe81SDimitry Andric   case CK_FixedPointToBoolean:
62322989816SDimitry Andric   case CK_FixedPointToIntegral:
62422989816SDimitry Andric   case CK_IntegralToFixedPoint:
625344a3780SDimitry Andric   case CK_MatrixCast:
626ac9a064cSDimitry Andric   case CK_HLSLVectorTruncation:
627ac9a064cSDimitry Andric   case CK_HLSLArrayRValue:
628180abc3dSDimitry Andric     llvm_unreachable("invalid cast kind for complex value");
629180abc3dSDimitry Andric 
630180abc3dSDimitry Andric   case CK_FloatingRealToComplex:
631b60736ecSDimitry Andric   case CK_IntegralRealToComplex: {
632b60736ecSDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op);
63345b53394SDimitry Andric     return EmitScalarToComplexCast(CGF.EmitScalarExpr(Op), Op->getType(),
63445b53394SDimitry Andric                                    DestTy, Op->getExprLoc());
635b60736ecSDimitry Andric   }
636ec2b103cSEd Schouten 
637180abc3dSDimitry Andric   case CK_FloatingComplexCast:
638180abc3dSDimitry Andric   case CK_FloatingComplexToIntegralComplex:
639180abc3dSDimitry Andric   case CK_IntegralComplexCast:
640b60736ecSDimitry Andric   case CK_IntegralComplexToFloatingComplex: {
641b60736ecSDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op);
64245b53394SDimitry Andric     return EmitComplexToComplexCast(Visit(Op), Op->getType(), DestTy,
64345b53394SDimitry Andric                                     Op->getExprLoc());
644180abc3dSDimitry Andric   }
645b60736ecSDimitry Andric   }
646180abc3dSDimitry Andric 
647180abc3dSDimitry Andric   llvm_unreachable("unknown cast resulting in complex value");
648180abc3dSDimitry Andric }
649180abc3dSDimitry Andric 
VisitUnaryPlus(const UnaryOperator * E,QualType PromotionType)650e3b55780SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitUnaryPlus(const UnaryOperator *E,
651e3b55780SDimitry Andric                                                  QualType PromotionType) {
652ac9a064cSDimitry Andric   E->hasStoredFPFeatures();
653ac9a064cSDimitry Andric   QualType promotionTy =
654ac9a064cSDimitry Andric       PromotionType.isNull()
655ac9a064cSDimitry Andric           ? getPromotionType(E->getStoredFPFeaturesOrDefault(),
656ac9a064cSDimitry Andric                              E->getSubExpr()->getType())
657e3b55780SDimitry Andric           : PromotionType;
658e3b55780SDimitry Andric   ComplexPairTy result = VisitPlus(E, promotionTy);
659e3b55780SDimitry Andric   if (!promotionTy.isNull())
660e3b55780SDimitry Andric     return CGF.EmitUnPromotedValue(result, E->getSubExpr()->getType());
661e3b55780SDimitry Andric   return result;
662e3b55780SDimitry Andric }
663e3b55780SDimitry Andric 
VisitPlus(const UnaryOperator * E,QualType PromotionType)664e3b55780SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitPlus(const UnaryOperator *E,
665e3b55780SDimitry Andric                                             QualType PromotionType) {
666ec2b103cSEd Schouten   TestAndClearIgnoreReal();
667ec2b103cSEd Schouten   TestAndClearIgnoreImag();
668e3b55780SDimitry Andric   if (!PromotionType.isNull())
669e3b55780SDimitry Andric     return CGF.EmitPromotedComplexExpr(E->getSubExpr(), PromotionType);
670e3b55780SDimitry Andric   return Visit(E->getSubExpr());
671e3b55780SDimitry Andric }
672e3b55780SDimitry Andric 
VisitUnaryMinus(const UnaryOperator * E,QualType PromotionType)673e3b55780SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E,
674e3b55780SDimitry Andric                                                   QualType PromotionType) {
675ac9a064cSDimitry Andric   QualType promotionTy =
676ac9a064cSDimitry Andric       PromotionType.isNull()
677ac9a064cSDimitry Andric           ? getPromotionType(E->getStoredFPFeaturesOrDefault(),
678ac9a064cSDimitry Andric                              E->getSubExpr()->getType())
679e3b55780SDimitry Andric           : PromotionType;
680e3b55780SDimitry Andric   ComplexPairTy result = VisitMinus(E, promotionTy);
681e3b55780SDimitry Andric   if (!promotionTy.isNull())
682e3b55780SDimitry Andric     return CGF.EmitUnPromotedValue(result, E->getSubExpr()->getType());
683e3b55780SDimitry Andric   return result;
684e3b55780SDimitry Andric }
VisitMinus(const UnaryOperator * E,QualType PromotionType)685e3b55780SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitMinus(const UnaryOperator *E,
686e3b55780SDimitry Andric                                              QualType PromotionType) {
687e3b55780SDimitry Andric   TestAndClearIgnoreReal();
688e3b55780SDimitry Andric   TestAndClearIgnoreImag();
689e3b55780SDimitry Andric   ComplexPairTy Op;
690e3b55780SDimitry Andric   if (!PromotionType.isNull())
691e3b55780SDimitry Andric     Op = CGF.EmitPromotedComplexExpr(E->getSubExpr(), PromotionType);
692e3b55780SDimitry Andric   else
693e3b55780SDimitry Andric     Op = Visit(E->getSubExpr());
694b897c866SEd Schouten 
695b897c866SEd Schouten   llvm::Value *ResR, *ResI;
696ecb7e5c8SRoman Divacky   if (Op.first->getType()->isFloatingPointTy()) {
697b897c866SEd Schouten     ResR = Builder.CreateFNeg(Op.first,  "neg.r");
698b897c866SEd Schouten     ResI = Builder.CreateFNeg(Op.second, "neg.i");
699b897c866SEd Schouten   } else {
700b897c866SEd Schouten     ResR = Builder.CreateNeg(Op.first,  "neg.r");
701b897c866SEd Schouten     ResI = Builder.CreateNeg(Op.second, "neg.i");
702b897c866SEd Schouten   }
703ec2b103cSEd Schouten   return ComplexPairTy(ResR, ResI);
704ec2b103cSEd Schouten }
705ec2b103cSEd Schouten 
VisitUnaryNot(const UnaryOperator * E)706ec2b103cSEd Schouten ComplexPairTy ComplexExprEmitter::VisitUnaryNot(const UnaryOperator *E) {
707ec2b103cSEd Schouten   TestAndClearIgnoreReal();
708ec2b103cSEd Schouten   TestAndClearIgnoreImag();
709ec2b103cSEd Schouten   // ~(a+ib) = a + i*-b
710ec2b103cSEd Schouten   ComplexPairTy Op = Visit(E->getSubExpr());
711b897c866SEd Schouten   llvm::Value *ResI;
712ecb7e5c8SRoman Divacky   if (Op.second->getType()->isFloatingPointTy())
713b897c866SEd Schouten     ResI = Builder.CreateFNeg(Op.second, "conj.i");
714b897c866SEd Schouten   else
715b897c866SEd Schouten     ResI = Builder.CreateNeg(Op.second, "conj.i");
716b897c866SEd Schouten 
717ec2b103cSEd Schouten   return ComplexPairTy(Op.first, ResI);
718ec2b103cSEd Schouten }
719ec2b103cSEd Schouten 
EmitBinAdd(const BinOpInfo & Op)720ec2b103cSEd Schouten ComplexPairTy ComplexExprEmitter::EmitBinAdd(const BinOpInfo &Op) {
721b897c866SEd Schouten   llvm::Value *ResR, *ResI;
722b897c866SEd Schouten 
723ecb7e5c8SRoman Divacky   if (Op.LHS.first->getType()->isFloatingPointTy()) {
724e3b55780SDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
725b897c866SEd Schouten     ResR = Builder.CreateFAdd(Op.LHS.first,  Op.RHS.first,  "add.r");
72606d4ba38SDimitry Andric     if (Op.LHS.second && Op.RHS.second)
727b897c866SEd Schouten       ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second, "add.i");
72806d4ba38SDimitry Andric     else
72906d4ba38SDimitry Andric       ResI = Op.LHS.second ? Op.LHS.second : Op.RHS.second;
73006d4ba38SDimitry Andric     assert(ResI && "Only one operand may be real!");
731b897c866SEd Schouten   } else {
732b897c866SEd Schouten     ResR = Builder.CreateAdd(Op.LHS.first,  Op.RHS.first,  "add.r");
73306d4ba38SDimitry Andric     assert(Op.LHS.second && Op.RHS.second &&
73406d4ba38SDimitry Andric            "Both operands of integer complex operators must be complex!");
735b897c866SEd Schouten     ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second, "add.i");
736b897c866SEd Schouten   }
737ec2b103cSEd Schouten   return ComplexPairTy(ResR, ResI);
738ec2b103cSEd Schouten }
739ec2b103cSEd Schouten 
EmitBinSub(const BinOpInfo & Op)740ec2b103cSEd Schouten ComplexPairTy ComplexExprEmitter::EmitBinSub(const BinOpInfo &Op) {
741b897c866SEd Schouten   llvm::Value *ResR, *ResI;
742ecb7e5c8SRoman Divacky   if (Op.LHS.first->getType()->isFloatingPointTy()) {
743e3b55780SDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
744b897c866SEd Schouten     ResR = Builder.CreateFSub(Op.LHS.first, Op.RHS.first, "sub.r");
74506d4ba38SDimitry Andric     if (Op.LHS.second && Op.RHS.second)
746b897c866SEd Schouten       ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second, "sub.i");
74706d4ba38SDimitry Andric     else
74806d4ba38SDimitry Andric       ResI = Op.LHS.second ? Op.LHS.second
74906d4ba38SDimitry Andric                            : Builder.CreateFNeg(Op.RHS.second, "sub.i");
75006d4ba38SDimitry Andric     assert(ResI && "Only one operand may be real!");
751b897c866SEd Schouten   } else {
752b897c866SEd Schouten     ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first, "sub.r");
75306d4ba38SDimitry Andric     assert(Op.LHS.second && Op.RHS.second &&
75406d4ba38SDimitry Andric            "Both operands of integer complex operators must be complex!");
755b897c866SEd Schouten     ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second, "sub.i");
756b897c866SEd Schouten   }
757ec2b103cSEd Schouten   return ComplexPairTy(ResR, ResI);
758ec2b103cSEd Schouten }
759ec2b103cSEd Schouten 
76048675466SDimitry Andric /// Emit a libcall for a binary operation on complex types.
EmitComplexBinOpLibCall(StringRef LibCallName,const BinOpInfo & Op)76106d4ba38SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName,
76206d4ba38SDimitry Andric                                                           const BinOpInfo &Op) {
76306d4ba38SDimitry Andric   CallArgList Args;
76406d4ba38SDimitry Andric   Args.add(RValue::get(Op.LHS.first),
76506d4ba38SDimitry Andric            Op.Ty->castAs<ComplexType>()->getElementType());
76606d4ba38SDimitry Andric   Args.add(RValue::get(Op.LHS.second),
76706d4ba38SDimitry Andric            Op.Ty->castAs<ComplexType>()->getElementType());
76806d4ba38SDimitry Andric   Args.add(RValue::get(Op.RHS.first),
76906d4ba38SDimitry Andric            Op.Ty->castAs<ComplexType>()->getElementType());
77006d4ba38SDimitry Andric   Args.add(RValue::get(Op.RHS.second),
77106d4ba38SDimitry Andric            Op.Ty->castAs<ComplexType>()->getElementType());
772ec2b103cSEd Schouten 
77306d4ba38SDimitry Andric   // We *must* use the full CG function call building logic here because the
77406d4ba38SDimitry Andric   // complex type has special ABI handling. We also should not forget about
77506d4ba38SDimitry Andric   // special calling convention which may be used for compiler builtins.
77645b53394SDimitry Andric 
77745b53394SDimitry Andric   // We create a function qualified type to state that this call does not have
77845b53394SDimitry Andric   // any exceptions.
77945b53394SDimitry Andric   FunctionProtoType::ExtProtoInfo EPI;
78045b53394SDimitry Andric   EPI = EPI.withExceptionSpec(
78145b53394SDimitry Andric       FunctionProtoType::ExceptionSpecInfo(EST_BasicNoexcept));
78245b53394SDimitry Andric   SmallVector<QualType, 4> ArgsQTys(
78345b53394SDimitry Andric       4, Op.Ty->castAs<ComplexType>()->getElementType());
78445b53394SDimitry Andric   QualType FQTy = CGF.getContext().getFunctionType(Op.Ty, ArgsQTys, EPI);
78545b53394SDimitry Andric   const CGFunctionInfo &FuncInfo = CGF.CGM.getTypes().arrangeFreeFunctionCall(
78645b53394SDimitry Andric       Args, cast<FunctionType>(FQTy.getTypePtr()), false);
78745b53394SDimitry Andric 
78806d4ba38SDimitry Andric   llvm::FunctionType *FTy = CGF.CGM.getTypes().GetFunctionType(FuncInfo);
78922989816SDimitry Andric   llvm::FunctionCallee Func = CGF.CGM.CreateRuntimeFunction(
79022989816SDimitry Andric       FTy, LibCallName, llvm::AttributeList(), true);
791bab175ecSDimitry Andric   CGCallee Callee = CGCallee::forDirect(Func, FQTy->getAs<FunctionProtoType>());
79206d4ba38SDimitry Andric 
79322989816SDimitry Andric   llvm::CallBase *Call;
794bab175ecSDimitry Andric   RValue Res = CGF.EmitCall(FuncInfo, Callee, ReturnValueSlot(), Args, &Call);
79522989816SDimitry Andric   Call->setCallingConv(CGF.CGM.getRuntimeCC());
79606d4ba38SDimitry Andric   return Res.getComplexVal();
79706d4ba38SDimitry Andric }
79806d4ba38SDimitry Andric 
79948675466SDimitry Andric /// Lookup the libcall name for a given floating point type complex
80006d4ba38SDimitry Andric /// multiply.
getComplexMultiplyLibCallName(llvm::Type * Ty)80106d4ba38SDimitry Andric static StringRef getComplexMultiplyLibCallName(llvm::Type *Ty) {
80206d4ba38SDimitry Andric   switch (Ty->getTypeID()) {
80306d4ba38SDimitry Andric   default:
80406d4ba38SDimitry Andric     llvm_unreachable("Unsupported floating point type!");
80506d4ba38SDimitry Andric   case llvm::Type::HalfTyID:
80606d4ba38SDimitry Andric     return "__mulhc3";
80706d4ba38SDimitry Andric   case llvm::Type::FloatTyID:
80806d4ba38SDimitry Andric     return "__mulsc3";
80906d4ba38SDimitry Andric   case llvm::Type::DoubleTyID:
81006d4ba38SDimitry Andric     return "__muldc3";
81106d4ba38SDimitry Andric   case llvm::Type::PPC_FP128TyID:
81206d4ba38SDimitry Andric     return "__multc3";
81306d4ba38SDimitry Andric   case llvm::Type::X86_FP80TyID:
81406d4ba38SDimitry Andric     return "__mulxc3";
81506d4ba38SDimitry Andric   case llvm::Type::FP128TyID:
81606d4ba38SDimitry Andric     return "__multc3";
81706d4ba38SDimitry Andric   }
81806d4ba38SDimitry Andric }
81906d4ba38SDimitry Andric 
82006d4ba38SDimitry Andric // See C11 Annex G.5.1 for the semantics of multiplicative operators on complex
82106d4ba38SDimitry Andric // typed values.
EmitBinMul(const BinOpInfo & Op)822ec2b103cSEd Schouten ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) {
823b897c866SEd Schouten   using llvm::Value;
824b897c866SEd Schouten   Value *ResR, *ResI;
82506d4ba38SDimitry Andric   llvm::MDBuilder MDHelper(CGF.getLLVMContext());
826ec2b103cSEd Schouten 
827ecb7e5c8SRoman Divacky   if (Op.LHS.first->getType()->isFloatingPointTy()) {
82806d4ba38SDimitry Andric     // The general formulation is:
82906d4ba38SDimitry Andric     // (a + ib) * (c + id) = (a * c - b * d) + i(a * d + b * c)
83006d4ba38SDimitry Andric     //
83106d4ba38SDimitry Andric     // But we can fold away components which would be zero due to a real
83206d4ba38SDimitry Andric     // operand according to C11 Annex G.5.1p2.
833b897c866SEd Schouten 
834e3b55780SDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
83506d4ba38SDimitry Andric     if (Op.LHS.second && Op.RHS.second) {
83606d4ba38SDimitry Andric       // If both operands are complex, emit the core math directly, and then
83706d4ba38SDimitry Andric       // test for NaNs. If we find NaNs in the result, we delegate to a libcall
83806d4ba38SDimitry Andric       // to carefully re-compute the correct infinity representation if
83906d4ba38SDimitry Andric       // possible. The expectation is that the presence of NaNs here is
84006d4ba38SDimitry Andric       // *extremely* rare, and so the cost of the libcall is almost irrelevant.
84106d4ba38SDimitry Andric       // This is good, because the libcall re-computes the core multiplication
84206d4ba38SDimitry Andric       // exactly the same as we do here and re-tests for NaNs in order to be
84306d4ba38SDimitry Andric       // a generic complex*complex libcall.
84406d4ba38SDimitry Andric 
84506d4ba38SDimitry Andric       // First compute the four products.
84606d4ba38SDimitry Andric       Value *AC = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul_ac");
84706d4ba38SDimitry Andric       Value *BD = Builder.CreateFMul(Op.LHS.second, Op.RHS.second, "mul_bd");
84806d4ba38SDimitry Andric       Value *AD = Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul_ad");
84906d4ba38SDimitry Andric       Value *BC = Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul_bc");
85006d4ba38SDimitry Andric 
85106d4ba38SDimitry Andric       // The real part is the difference of the first two, the imaginary part is
85206d4ba38SDimitry Andric       // the sum of the second.
85306d4ba38SDimitry Andric       ResR = Builder.CreateFSub(AC, BD, "mul_r");
85406d4ba38SDimitry Andric       ResI = Builder.CreateFAdd(AD, BC, "mul_i");
85506d4ba38SDimitry Andric 
856ac9a064cSDimitry Andric       if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Basic ||
857ac9a064cSDimitry Andric           Op.FPFeatures.getComplexRange() == LangOptions::CX_Improved ||
858ac9a064cSDimitry Andric           Op.FPFeatures.getComplexRange() == LangOptions::CX_Promoted)
859312c0ed1SDimitry Andric         return ComplexPairTy(ResR, ResI);
860312c0ed1SDimitry Andric 
86106d4ba38SDimitry Andric       // Emit the test for the real part becoming NaN and create a branch to
86206d4ba38SDimitry Andric       // handle it. We test for NaN by comparing the number to itself.
86306d4ba38SDimitry Andric       Value *IsRNaN = Builder.CreateFCmpUNO(ResR, ResR, "isnan_cmp");
86406d4ba38SDimitry Andric       llvm::BasicBlock *ContBB = CGF.createBasicBlock("complex_mul_cont");
86506d4ba38SDimitry Andric       llvm::BasicBlock *INaNBB = CGF.createBasicBlock("complex_mul_imag_nan");
86606d4ba38SDimitry Andric       llvm::Instruction *Branch = Builder.CreateCondBr(IsRNaN, INaNBB, ContBB);
86706d4ba38SDimitry Andric       llvm::BasicBlock *OrigBB = Branch->getParent();
86806d4ba38SDimitry Andric 
86906d4ba38SDimitry Andric       // Give hint that we very much don't expect to see NaNs.
870ac9a064cSDimitry Andric       llvm::MDNode *BrWeight = MDHelper.createUnlikelyBranchWeights();
87106d4ba38SDimitry Andric       Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight);
87206d4ba38SDimitry Andric 
87306d4ba38SDimitry Andric       // Now test the imaginary part and create its branch.
87406d4ba38SDimitry Andric       CGF.EmitBlock(INaNBB);
87506d4ba38SDimitry Andric       Value *IsINaN = Builder.CreateFCmpUNO(ResI, ResI, "isnan_cmp");
87606d4ba38SDimitry Andric       llvm::BasicBlock *LibCallBB = CGF.createBasicBlock("complex_mul_libcall");
87706d4ba38SDimitry Andric       Branch = Builder.CreateCondBr(IsINaN, LibCallBB, ContBB);
87806d4ba38SDimitry Andric       Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight);
87906d4ba38SDimitry Andric 
88006d4ba38SDimitry Andric       // Now emit the libcall on this slowest of the slow paths.
88106d4ba38SDimitry Andric       CGF.EmitBlock(LibCallBB);
88206d4ba38SDimitry Andric       Value *LibCallR, *LibCallI;
88306d4ba38SDimitry Andric       std::tie(LibCallR, LibCallI) = EmitComplexBinOpLibCall(
88406d4ba38SDimitry Andric           getComplexMultiplyLibCallName(Op.LHS.first->getType()), Op);
88506d4ba38SDimitry Andric       Builder.CreateBr(ContBB);
88606d4ba38SDimitry Andric 
88706d4ba38SDimitry Andric       // Finally continue execution by phi-ing together the different
88806d4ba38SDimitry Andric       // computation paths.
88906d4ba38SDimitry Andric       CGF.EmitBlock(ContBB);
89006d4ba38SDimitry Andric       llvm::PHINode *RealPHI = Builder.CreatePHI(ResR->getType(), 3, "real_mul_phi");
89106d4ba38SDimitry Andric       RealPHI->addIncoming(ResR, OrigBB);
89206d4ba38SDimitry Andric       RealPHI->addIncoming(ResR, INaNBB);
89306d4ba38SDimitry Andric       RealPHI->addIncoming(LibCallR, LibCallBB);
89406d4ba38SDimitry Andric       llvm::PHINode *ImagPHI = Builder.CreatePHI(ResI->getType(), 3, "imag_mul_phi");
89506d4ba38SDimitry Andric       ImagPHI->addIncoming(ResI, OrigBB);
89606d4ba38SDimitry Andric       ImagPHI->addIncoming(ResI, INaNBB);
89706d4ba38SDimitry Andric       ImagPHI->addIncoming(LibCallI, LibCallBB);
89806d4ba38SDimitry Andric       return ComplexPairTy(RealPHI, ImagPHI);
89906d4ba38SDimitry Andric     }
90006d4ba38SDimitry Andric     assert((Op.LHS.second || Op.RHS.second) &&
90106d4ba38SDimitry Andric            "At least one operand must be complex!");
90206d4ba38SDimitry Andric 
90306d4ba38SDimitry Andric     // If either of the operands is a real rather than a complex, the
90406d4ba38SDimitry Andric     // imaginary component is ignored when computing the real component of the
90506d4ba38SDimitry Andric     // result.
90606d4ba38SDimitry Andric     ResR = Builder.CreateFMul(Op.LHS.first, Op.RHS.first, "mul.rl");
90706d4ba38SDimitry Andric 
90806d4ba38SDimitry Andric     ResI = Op.LHS.second
90906d4ba38SDimitry Andric                ? Builder.CreateFMul(Op.LHS.second, Op.RHS.first, "mul.il")
91006d4ba38SDimitry Andric                : Builder.CreateFMul(Op.LHS.first, Op.RHS.second, "mul.ir");
911b897c866SEd Schouten   } else {
91206d4ba38SDimitry Andric     assert(Op.LHS.second && Op.RHS.second &&
91306d4ba38SDimitry Andric            "Both operands of integer complex operators must be complex!");
914b897c866SEd Schouten     Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first, "mul.rl");
915b897c866SEd Schouten     Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second, "mul.rr");
916b897c866SEd Schouten     ResR = Builder.CreateSub(ResRl, ResRr, "mul.r");
917b897c866SEd Schouten 
918b897c866SEd Schouten     Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first, "mul.il");
919b897c866SEd Schouten     Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second, "mul.ir");
920b897c866SEd Schouten     ResI = Builder.CreateAdd(ResIl, ResIr, "mul.i");
921b897c866SEd Schouten   }
922ec2b103cSEd Schouten   return ComplexPairTy(ResR, ResI);
923ec2b103cSEd Schouten }
924ec2b103cSEd Schouten 
EmitAlgebraicDiv(llvm::Value * LHSr,llvm::Value * LHSi,llvm::Value * RHSr,llvm::Value * RHSi)925312c0ed1SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitAlgebraicDiv(llvm::Value *LHSr,
926312c0ed1SDimitry Andric                                                    llvm::Value *LHSi,
927312c0ed1SDimitry Andric                                                    llvm::Value *RHSr,
928312c0ed1SDimitry Andric                                                    llvm::Value *RHSi) {
929312c0ed1SDimitry Andric   // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
930312c0ed1SDimitry Andric   llvm::Value *DSTr, *DSTi;
931312c0ed1SDimitry Andric 
932312c0ed1SDimitry Andric   llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr); // a*c
933312c0ed1SDimitry Andric   llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi); // b*d
934312c0ed1SDimitry Andric   llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD);  // ac+bd
935312c0ed1SDimitry Andric 
936312c0ed1SDimitry Andric   llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr); // c*c
937312c0ed1SDimitry Andric   llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi); // d*d
938312c0ed1SDimitry Andric   llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD);  // cc+dd
939312c0ed1SDimitry Andric 
940312c0ed1SDimitry Andric   llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr); // b*c
941312c0ed1SDimitry Andric   llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi); // a*d
942312c0ed1SDimitry Andric   llvm::Value *BCmAD = Builder.CreateFSub(BC, AD);  // bc-ad
943312c0ed1SDimitry Andric 
944312c0ed1SDimitry Andric   DSTr = Builder.CreateFDiv(ACpBD, CCpDD);
945312c0ed1SDimitry Andric   DSTi = Builder.CreateFDiv(BCmAD, CCpDD);
946312c0ed1SDimitry Andric   return ComplexPairTy(DSTr, DSTi);
947312c0ed1SDimitry Andric }
948312c0ed1SDimitry Andric 
949312c0ed1SDimitry Andric // EmitFAbs - Emit a call to @llvm.fabs.
EmitllvmFAbs(CodeGenFunction & CGF,llvm::Value * Value)950312c0ed1SDimitry Andric static llvm::Value *EmitllvmFAbs(CodeGenFunction &CGF, llvm::Value *Value) {
951312c0ed1SDimitry Andric   llvm::Function *Func =
952312c0ed1SDimitry Andric       CGF.CGM.getIntrinsic(llvm::Intrinsic::fabs, Value->getType());
953312c0ed1SDimitry Andric   llvm::Value *Call = CGF.Builder.CreateCall(Func, Value);
954312c0ed1SDimitry Andric   return Call;
955312c0ed1SDimitry Andric }
956312c0ed1SDimitry Andric 
957312c0ed1SDimitry Andric // EmitRangeReductionDiv - Implements Smith's algorithm for complex division.
958312c0ed1SDimitry Andric // SMITH, R. L. Algorithm 116: Complex division. Commun. ACM 5, 8 (1962).
EmitRangeReductionDiv(llvm::Value * LHSr,llvm::Value * LHSi,llvm::Value * RHSr,llvm::Value * RHSi)959312c0ed1SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitRangeReductionDiv(llvm::Value *LHSr,
960312c0ed1SDimitry Andric                                                         llvm::Value *LHSi,
961312c0ed1SDimitry Andric                                                         llvm::Value *RHSr,
962312c0ed1SDimitry Andric                                                         llvm::Value *RHSi) {
9634df029ccSDimitry Andric   // FIXME: This could eventually be replaced by an LLVM intrinsic to
9644df029ccSDimitry Andric   // avoid this long IR sequence.
9654df029ccSDimitry Andric 
966312c0ed1SDimitry Andric   // (a + ib) / (c + id) = (e + if)
967312c0ed1SDimitry Andric   llvm::Value *FAbsRHSr = EmitllvmFAbs(CGF, RHSr); // |c|
968312c0ed1SDimitry Andric   llvm::Value *FAbsRHSi = EmitllvmFAbs(CGF, RHSi); // |d|
969312c0ed1SDimitry Andric   // |c| >= |d|
970312c0ed1SDimitry Andric   llvm::Value *IsR = Builder.CreateFCmpUGT(FAbsRHSr, FAbsRHSi, "abs_cmp");
971312c0ed1SDimitry Andric 
972312c0ed1SDimitry Andric   llvm::BasicBlock *TrueBB =
973312c0ed1SDimitry Andric       CGF.createBasicBlock("abs_rhsr_greater_or_equal_abs_rhsi");
974312c0ed1SDimitry Andric   llvm::BasicBlock *FalseBB =
975312c0ed1SDimitry Andric       CGF.createBasicBlock("abs_rhsr_less_than_abs_rhsi");
976312c0ed1SDimitry Andric   llvm::BasicBlock *ContBB = CGF.createBasicBlock("complex_div");
977312c0ed1SDimitry Andric   Builder.CreateCondBr(IsR, TrueBB, FalseBB);
978312c0ed1SDimitry Andric 
979312c0ed1SDimitry Andric   CGF.EmitBlock(TrueBB);
980312c0ed1SDimitry Andric   // abs(c) >= abs(d)
981312c0ed1SDimitry Andric   // r = d/c
982312c0ed1SDimitry Andric   // tmp = c + rd
983312c0ed1SDimitry Andric   // e = (a + br)/tmp
984312c0ed1SDimitry Andric   // f = (b - ar)/tmp
985312c0ed1SDimitry Andric   llvm::Value *DdC = Builder.CreateFDiv(RHSi, RHSr); // r=d/c
986312c0ed1SDimitry Andric 
987312c0ed1SDimitry Andric   llvm::Value *RD = Builder.CreateFMul(DdC, RHSi);  // rd
988312c0ed1SDimitry Andric   llvm::Value *CpRD = Builder.CreateFAdd(RHSr, RD); // tmp=c+rd
989312c0ed1SDimitry Andric 
990312c0ed1SDimitry Andric   llvm::Value *T3 = Builder.CreateFMul(LHSi, DdC);   // br
991312c0ed1SDimitry Andric   llvm::Value *T4 = Builder.CreateFAdd(LHSr, T3);    // a+br
992312c0ed1SDimitry Andric   llvm::Value *DSTTr = Builder.CreateFDiv(T4, CpRD); // (a+br)/tmp
993312c0ed1SDimitry Andric 
994312c0ed1SDimitry Andric   llvm::Value *T5 = Builder.CreateFMul(LHSr, DdC);   // ar
995312c0ed1SDimitry Andric   llvm::Value *T6 = Builder.CreateFSub(LHSi, T5);    // b-ar
996312c0ed1SDimitry Andric   llvm::Value *DSTTi = Builder.CreateFDiv(T6, CpRD); // (b-ar)/tmp
997312c0ed1SDimitry Andric   Builder.CreateBr(ContBB);
998312c0ed1SDimitry Andric 
999312c0ed1SDimitry Andric   CGF.EmitBlock(FalseBB);
1000312c0ed1SDimitry Andric   // abs(c) < abs(d)
1001312c0ed1SDimitry Andric   // r = c/d
1002312c0ed1SDimitry Andric   // tmp = d + rc
1003312c0ed1SDimitry Andric   // e = (ar + b)/tmp
1004312c0ed1SDimitry Andric   // f = (br - a)/tmp
1005312c0ed1SDimitry Andric   llvm::Value *CdD = Builder.CreateFDiv(RHSr, RHSi); // r=c/d
1006312c0ed1SDimitry Andric 
1007312c0ed1SDimitry Andric   llvm::Value *RC = Builder.CreateFMul(CdD, RHSr);  // rc
1008312c0ed1SDimitry Andric   llvm::Value *DpRC = Builder.CreateFAdd(RHSi, RC); // tmp=d+rc
1009312c0ed1SDimitry Andric 
10104df029ccSDimitry Andric   llvm::Value *T7 = Builder.CreateFMul(LHSr, CdD);   // ar
1011312c0ed1SDimitry Andric   llvm::Value *T8 = Builder.CreateFAdd(T7, LHSi);    // ar+b
1012312c0ed1SDimitry Andric   llvm::Value *DSTFr = Builder.CreateFDiv(T8, DpRC); // (ar+b)/tmp
1013312c0ed1SDimitry Andric 
1014312c0ed1SDimitry Andric   llvm::Value *T9 = Builder.CreateFMul(LHSi, CdD);    // br
1015312c0ed1SDimitry Andric   llvm::Value *T10 = Builder.CreateFSub(T9, LHSr);    // br-a
1016312c0ed1SDimitry Andric   llvm::Value *DSTFi = Builder.CreateFDiv(T10, DpRC); // (br-a)/tmp
1017312c0ed1SDimitry Andric   Builder.CreateBr(ContBB);
1018312c0ed1SDimitry Andric 
1019312c0ed1SDimitry Andric   // Phi together the computation paths.
1020312c0ed1SDimitry Andric   CGF.EmitBlock(ContBB);
1021312c0ed1SDimitry Andric   llvm::PHINode *VALr = Builder.CreatePHI(DSTTr->getType(), 2);
1022312c0ed1SDimitry Andric   VALr->addIncoming(DSTTr, TrueBB);
1023312c0ed1SDimitry Andric   VALr->addIncoming(DSTFr, FalseBB);
1024312c0ed1SDimitry Andric   llvm::PHINode *VALi = Builder.CreatePHI(DSTTi->getType(), 2);
1025312c0ed1SDimitry Andric   VALi->addIncoming(DSTTi, TrueBB);
1026312c0ed1SDimitry Andric   VALi->addIncoming(DSTFi, FalseBB);
1027312c0ed1SDimitry Andric   return ComplexPairTy(VALr, VALi);
1028312c0ed1SDimitry Andric }
1029312c0ed1SDimitry Andric 
103006d4ba38SDimitry Andric // See C11 Annex G.5.1 for the semantics of multiplicative operators on complex
103106d4ba38SDimitry Andric // typed values.
EmitBinDiv(const BinOpInfo & Op)1032ec2b103cSEd Schouten ComplexPairTy ComplexExprEmitter::EmitBinDiv(const BinOpInfo &Op) {
1033ec2b103cSEd Schouten   llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second;
1034ec2b103cSEd Schouten   llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second;
1035b897c866SEd Schouten   llvm::Value *DSTr, *DSTi;
103606d4ba38SDimitry Andric   if (LHSr->getType()->isFloatingPointTy()) {
1037312c0ed1SDimitry Andric     CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
1038312c0ed1SDimitry Andric     if (!RHSi) {
1039312c0ed1SDimitry Andric       assert(LHSi && "Can have at most one non-complex operand!");
1040312c0ed1SDimitry Andric 
1041312c0ed1SDimitry Andric       DSTr = Builder.CreateFDiv(LHSr, RHSr);
1042312c0ed1SDimitry Andric       DSTi = Builder.CreateFDiv(LHSi, RHSr);
1043312c0ed1SDimitry Andric       return ComplexPairTy(DSTr, DSTi);
1044312c0ed1SDimitry Andric     }
1045312c0ed1SDimitry Andric     llvm::Value *OrigLHSi = LHSi;
1046312c0ed1SDimitry Andric     if (!LHSi)
1047312c0ed1SDimitry Andric       LHSi = llvm::Constant::getNullValue(RHSi->getType());
1048ac9a064cSDimitry Andric     if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Improved ||
1049ac9a064cSDimitry Andric         (Op.FPFeatures.getComplexRange() == LangOptions::CX_Promoted &&
1050ac9a064cSDimitry Andric          !FPHasBeenPromoted))
1051312c0ed1SDimitry Andric       return EmitRangeReductionDiv(LHSr, LHSi, RHSr, RHSi);
1052ac9a064cSDimitry Andric     else if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Basic ||
1053ac9a064cSDimitry Andric              Op.FPFeatures.getComplexRange() == LangOptions::CX_Promoted)
1054312c0ed1SDimitry Andric       return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi);
10554df029ccSDimitry Andric     // '-ffast-math' is used in the command line but followed by an
1056ac9a064cSDimitry Andric     // '-fno-cx-limited-range' or '-fcomplex-arithmetic=full'.
1057ac9a064cSDimitry Andric     else if (Op.FPFeatures.getComplexRange() == LangOptions::CX_Full) {
1058312c0ed1SDimitry Andric       LHSi = OrigLHSi;
10596252156dSDimitry Andric       // If we have a complex operand on the RHS and FastMath is not allowed, we
10606252156dSDimitry Andric       // delegate to a libcall to handle all of the complexities and minimize
10616252156dSDimitry Andric       // underflow/overflow cases. When FastMath is allowed we construct the
10626252156dSDimitry Andric       // divide inline using the same algorithm as for integer operands.
106306d4ba38SDimitry Andric       BinOpInfo LibCallOp = Op;
106406d4ba38SDimitry Andric       // If LHS was a real, supply a null imaginary part.
106506d4ba38SDimitry Andric       if (!LHSi)
106606d4ba38SDimitry Andric         LibCallOp.LHS.second = llvm::Constant::getNullValue(LHSr->getType());
1067b897c866SEd Schouten 
106806d4ba38SDimitry Andric       switch (LHSr->getType()->getTypeID()) {
106906d4ba38SDimitry Andric       default:
107006d4ba38SDimitry Andric         llvm_unreachable("Unsupported floating point type!");
107106d4ba38SDimitry Andric       case llvm::Type::HalfTyID:
107206d4ba38SDimitry Andric         return EmitComplexBinOpLibCall("__divhc3", LibCallOp);
107306d4ba38SDimitry Andric       case llvm::Type::FloatTyID:
107406d4ba38SDimitry Andric         return EmitComplexBinOpLibCall("__divsc3", LibCallOp);
107506d4ba38SDimitry Andric       case llvm::Type::DoubleTyID:
107606d4ba38SDimitry Andric         return EmitComplexBinOpLibCall("__divdc3", LibCallOp);
107706d4ba38SDimitry Andric       case llvm::Type::PPC_FP128TyID:
107806d4ba38SDimitry Andric         return EmitComplexBinOpLibCall("__divtc3", LibCallOp);
107906d4ba38SDimitry Andric       case llvm::Type::X86_FP80TyID:
108006d4ba38SDimitry Andric         return EmitComplexBinOpLibCall("__divxc3", LibCallOp);
108106d4ba38SDimitry Andric       case llvm::Type::FP128TyID:
108206d4ba38SDimitry Andric         return EmitComplexBinOpLibCall("__divtc3", LibCallOp);
108306d4ba38SDimitry Andric       }
10846252156dSDimitry Andric     } else {
1085312c0ed1SDimitry Andric       return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi);
10866252156dSDimitry Andric     }
1087b897c866SEd Schouten   } else {
108806d4ba38SDimitry Andric     assert(Op.LHS.second && Op.RHS.second &&
108906d4ba38SDimitry Andric            "Both operands of integer complex operators must be complex!");
1090ec2b103cSEd Schouten     // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
109136981b17SDimitry Andric     llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr); // a*c
109236981b17SDimitry Andric     llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi); // b*d
109336981b17SDimitry Andric     llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2); // ac+bd
1094ec2b103cSEd Schouten 
109536981b17SDimitry Andric     llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr); // c*c
109636981b17SDimitry Andric     llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi); // d*d
109736981b17SDimitry Andric     llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5); // cc+dd
1098ec2b103cSEd Schouten 
109936981b17SDimitry Andric     llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr); // b*c
110036981b17SDimitry Andric     llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi); // a*d
110136981b17SDimitry Andric     llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8); // bc-ad
1102ec2b103cSEd Schouten 
1103809500fcSDimitry Andric     if (Op.Ty->castAs<ComplexType>()->getElementType()->isUnsignedIntegerType()) {
110436981b17SDimitry Andric       DSTr = Builder.CreateUDiv(Tmp3, Tmp6);
110536981b17SDimitry Andric       DSTi = Builder.CreateUDiv(Tmp9, Tmp6);
1106ec2b103cSEd Schouten     } else {
110736981b17SDimitry Andric       DSTr = Builder.CreateSDiv(Tmp3, Tmp6);
110836981b17SDimitry Andric       DSTi = Builder.CreateSDiv(Tmp9, Tmp6);
1109ec2b103cSEd Schouten     }
1110ec2b103cSEd Schouten   }
1111ec2b103cSEd Schouten 
1112ec2b103cSEd Schouten   return ComplexPairTy(DSTr, DSTi);
1113ec2b103cSEd Schouten }
1114ec2b103cSEd Schouten 
EmitUnPromotedValue(ComplexPairTy result,QualType UnPromotionType)1115e3b55780SDimitry Andric ComplexPairTy CodeGenFunction::EmitUnPromotedValue(ComplexPairTy result,
1116e3b55780SDimitry Andric                                                    QualType UnPromotionType) {
1117e3b55780SDimitry Andric   llvm::Type *ComplexElementTy =
1118e3b55780SDimitry Andric       ConvertType(UnPromotionType->castAs<ComplexType>()->getElementType());
1119e3b55780SDimitry Andric   if (result.first)
1120e3b55780SDimitry Andric     result.first =
1121e3b55780SDimitry Andric         Builder.CreateFPTrunc(result.first, ComplexElementTy, "unpromotion");
1122e3b55780SDimitry Andric   if (result.second)
1123e3b55780SDimitry Andric     result.second =
1124e3b55780SDimitry Andric         Builder.CreateFPTrunc(result.second, ComplexElementTy, "unpromotion");
1125e3b55780SDimitry Andric   return result;
1126e3b55780SDimitry Andric }
1127e3b55780SDimitry Andric 
EmitPromotedValue(ComplexPairTy result,QualType PromotionType)1128e3b55780SDimitry Andric ComplexPairTy CodeGenFunction::EmitPromotedValue(ComplexPairTy result,
1129e3b55780SDimitry Andric                                                  QualType PromotionType) {
1130e3b55780SDimitry Andric   llvm::Type *ComplexElementTy =
1131e3b55780SDimitry Andric       ConvertType(PromotionType->castAs<ComplexType>()->getElementType());
1132e3b55780SDimitry Andric   if (result.first)
1133e3b55780SDimitry Andric     result.first = Builder.CreateFPExt(result.first, ComplexElementTy, "ext");
1134e3b55780SDimitry Andric   if (result.second)
1135e3b55780SDimitry Andric     result.second = Builder.CreateFPExt(result.second, ComplexElementTy, "ext");
1136e3b55780SDimitry Andric 
1137e3b55780SDimitry Andric   return result;
1138e3b55780SDimitry Andric }
1139e3b55780SDimitry Andric 
EmitPromoted(const Expr * E,QualType PromotionType)1140e3b55780SDimitry Andric ComplexPairTy ComplexExprEmitter::EmitPromoted(const Expr *E,
1141e3b55780SDimitry Andric                                                QualType PromotionType) {
1142e3b55780SDimitry Andric   E = E->IgnoreParens();
1143e3b55780SDimitry Andric   if (auto BO = dyn_cast<BinaryOperator>(E)) {
1144e3b55780SDimitry Andric     switch (BO->getOpcode()) {
1145e3b55780SDimitry Andric #define HANDLE_BINOP(OP)                                                       \
1146e3b55780SDimitry Andric   case BO_##OP:                                                                \
1147e3b55780SDimitry Andric     return EmitBin##OP(EmitBinOps(BO, PromotionType));
1148e3b55780SDimitry Andric       HANDLE_BINOP(Add)
1149e3b55780SDimitry Andric       HANDLE_BINOP(Sub)
1150e3b55780SDimitry Andric       HANDLE_BINOP(Mul)
1151e3b55780SDimitry Andric       HANDLE_BINOP(Div)
1152e3b55780SDimitry Andric #undef HANDLE_BINOP
1153e3b55780SDimitry Andric     default:
1154e3b55780SDimitry Andric       break;
1155e3b55780SDimitry Andric     }
1156e3b55780SDimitry Andric   } else if (auto UO = dyn_cast<UnaryOperator>(E)) {
1157e3b55780SDimitry Andric     switch (UO->getOpcode()) {
1158e3b55780SDimitry Andric     case UO_Minus:
1159e3b55780SDimitry Andric       return VisitMinus(UO, PromotionType);
1160e3b55780SDimitry Andric     case UO_Plus:
1161e3b55780SDimitry Andric       return VisitPlus(UO, PromotionType);
1162e3b55780SDimitry Andric     default:
1163e3b55780SDimitry Andric       break;
1164e3b55780SDimitry Andric     }
1165e3b55780SDimitry Andric   }
1166e3b55780SDimitry Andric   auto result = Visit(const_cast<Expr *>(E));
1167e3b55780SDimitry Andric   if (!PromotionType.isNull())
1168e3b55780SDimitry Andric     return CGF.EmitPromotedValue(result, PromotionType);
1169e3b55780SDimitry Andric   else
1170e3b55780SDimitry Andric     return result;
1171e3b55780SDimitry Andric }
1172e3b55780SDimitry Andric 
EmitPromotedComplexExpr(const Expr * E,QualType DstTy)1173e3b55780SDimitry Andric ComplexPairTy CodeGenFunction::EmitPromotedComplexExpr(const Expr *E,
1174e3b55780SDimitry Andric                                                        QualType DstTy) {
1175e3b55780SDimitry Andric   return ComplexExprEmitter(*this).EmitPromoted(E, DstTy);
1176e3b55780SDimitry Andric }
1177e3b55780SDimitry Andric 
1178e3b55780SDimitry Andric ComplexPairTy
EmitPromotedComplexOperand(const Expr * E,QualType OverallPromotionType)1179e3b55780SDimitry Andric ComplexExprEmitter::EmitPromotedComplexOperand(const Expr *E,
1180e3b55780SDimitry Andric                                                QualType OverallPromotionType) {
1181e3b55780SDimitry Andric   if (E->getType()->isAnyComplexType()) {
1182e3b55780SDimitry Andric     if (!OverallPromotionType.isNull())
1183e3b55780SDimitry Andric       return CGF.EmitPromotedComplexExpr(E, OverallPromotionType);
1184e3b55780SDimitry Andric     else
1185e3b55780SDimitry Andric       return Visit(const_cast<Expr *>(E));
1186e3b55780SDimitry Andric   } else {
1187e3b55780SDimitry Andric     if (!OverallPromotionType.isNull()) {
1188e3b55780SDimitry Andric       QualType ComplexElementTy =
1189e3b55780SDimitry Andric           OverallPromotionType->castAs<ComplexType>()->getElementType();
1190e3b55780SDimitry Andric       return ComplexPairTy(CGF.EmitPromotedScalarExpr(E, ComplexElementTy),
1191e3b55780SDimitry Andric                            nullptr);
1192e3b55780SDimitry Andric     } else {
1193e3b55780SDimitry Andric       return ComplexPairTy(CGF.EmitScalarExpr(E), nullptr);
1194e3b55780SDimitry Andric     }
1195e3b55780SDimitry Andric   }
1196e3b55780SDimitry Andric }
1197e3b55780SDimitry Andric 
1198ec2b103cSEd Schouten ComplexExprEmitter::BinOpInfo
EmitBinOps(const BinaryOperator * E,QualType PromotionType)1199e3b55780SDimitry Andric ComplexExprEmitter::EmitBinOps(const BinaryOperator *E,
1200e3b55780SDimitry Andric                                QualType PromotionType) {
1201ec2b103cSEd Schouten   TestAndClearIgnoreReal();
1202ec2b103cSEd Schouten   TestAndClearIgnoreImag();
1203ec2b103cSEd Schouten   BinOpInfo Ops;
120406d4ba38SDimitry Andric 
1205e3b55780SDimitry Andric   Ops.LHS = EmitPromotedComplexOperand(E->getLHS(), PromotionType);
1206e3b55780SDimitry Andric   Ops.RHS = EmitPromotedComplexOperand(E->getRHS(), PromotionType);
1207e3b55780SDimitry Andric   if (!PromotionType.isNull())
1208e3b55780SDimitry Andric     Ops.Ty = PromotionType;
1209e3b55780SDimitry Andric   else
1210ec2b103cSEd Schouten     Ops.Ty = E->getType();
1211e3b55780SDimitry Andric   Ops.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts());
1212ec2b103cSEd Schouten   return Ops;
1213ec2b103cSEd Schouten }
1214ec2b103cSEd Schouten 
1215ec2b103cSEd Schouten 
1216bca07a45SDimitry Andric LValue ComplexExprEmitter::
EmitCompoundAssignLValue(const CompoundAssignOperator * E,ComplexPairTy (ComplexExprEmitter::* Func)(const BinOpInfo &),RValue & Val)1217bca07a45SDimitry Andric EmitCompoundAssignLValue(const CompoundAssignOperator *E,
1218bca07a45SDimitry Andric           ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&),
1219bfef3995SDimitry Andric                          RValue &Val) {
1220ec2b103cSEd Schouten   TestAndClearIgnoreReal();
1221ec2b103cSEd Schouten   TestAndClearIgnoreImag();
1222bca07a45SDimitry Andric   QualType LHSTy = E->getLHS()->getType();
12235e20cdd8SDimitry Andric   if (const AtomicType *AT = LHSTy->getAs<AtomicType>())
12245e20cdd8SDimitry Andric     LHSTy = AT->getValueType();
1225ec2b103cSEd Schouten 
1226ec2b103cSEd Schouten   BinOpInfo OpInfo;
1227e3b55780SDimitry Andric   OpInfo.FPFeatures = E->getFPFeaturesInEffect(CGF.getLangOpts());
1228e3b55780SDimitry Andric   CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
1229ec2b103cSEd Schouten 
1230ec2b103cSEd Schouten   // Load the RHS and LHS operands.
1231ec2b103cSEd Schouten   // __block variables need to have the rhs evaluated first, plus this should
1232bca07a45SDimitry Andric   // improve codegen a little.
1233e3b55780SDimitry Andric   QualType PromotionTypeCR;
1234ac9a064cSDimitry Andric   PromotionTypeCR = getPromotionType(E->getStoredFPFeaturesOrDefault(),
1235ac9a064cSDimitry Andric                                      E->getComputationResultType());
1236e3b55780SDimitry Andric   if (PromotionTypeCR.isNull())
1237e3b55780SDimitry Andric     PromotionTypeCR = E->getComputationResultType();
1238e3b55780SDimitry Andric   OpInfo.Ty = PromotionTypeCR;
1239e3b55780SDimitry Andric   QualType ComplexElementTy =
1240e3b55780SDimitry Andric       OpInfo.Ty->castAs<ComplexType>()->getElementType();
1241ac9a064cSDimitry Andric   QualType PromotionTypeRHS = getPromotionType(
1242ac9a064cSDimitry Andric       E->getStoredFPFeaturesOrDefault(), E->getRHS()->getType());
1243bca07a45SDimitry Andric 
1244bca07a45SDimitry Andric   // The RHS should have been converted to the computation type.
124506d4ba38SDimitry Andric   if (E->getRHS()->getType()->isRealFloatingType()) {
1246e3b55780SDimitry Andric     if (!PromotionTypeRHS.isNull())
1247e3b55780SDimitry Andric       OpInfo.RHS = ComplexPairTy(
1248e3b55780SDimitry Andric           CGF.EmitPromotedScalarExpr(E->getRHS(), PromotionTypeRHS), nullptr);
1249e3b55780SDimitry Andric     else {
1250e3b55780SDimitry Andric       assert(CGF.getContext().hasSameUnqualifiedType(ComplexElementTy,
1251e3b55780SDimitry Andric                                                      E->getRHS()->getType()));
1252e3b55780SDimitry Andric 
125306d4ba38SDimitry Andric       OpInfo.RHS = ComplexPairTy(CGF.EmitScalarExpr(E->getRHS()), nullptr);
1254e3b55780SDimitry Andric     }
125506d4ba38SDimitry Andric   } else {
1256e3b55780SDimitry Andric     if (!PromotionTypeRHS.isNull()) {
1257e3b55780SDimitry Andric       OpInfo.RHS = ComplexPairTy(
1258e3b55780SDimitry Andric           CGF.EmitPromotedComplexExpr(E->getRHS(), PromotionTypeRHS));
1259e3b55780SDimitry Andric     } else {
1260e3b55780SDimitry Andric       assert(CGF.getContext().hasSameUnqualifiedType(OpInfo.Ty,
1261e3b55780SDimitry Andric                                                      E->getRHS()->getType()));
1262bca07a45SDimitry Andric       OpInfo.RHS = Visit(E->getRHS());
126306d4ba38SDimitry Andric     }
1264e3b55780SDimitry Andric   }
1265ec2b103cSEd Schouten 
12664ba67500SRoman Divacky   LValue LHS = CGF.EmitLValue(E->getLHS());
1267bca07a45SDimitry Andric 
1268bfef3995SDimitry Andric   // Load from the l-value and convert it.
126945b53394SDimitry Andric   SourceLocation Loc = E->getExprLoc();
1270ac9a064cSDimitry Andric   QualType PromotionTypeLHS = getPromotionType(
1271ac9a064cSDimitry Andric       E->getStoredFPFeaturesOrDefault(), E->getComputationLHSType());
1272bfef3995SDimitry Andric   if (LHSTy->isAnyComplexType()) {
127345b53394SDimitry Andric     ComplexPairTy LHSVal = EmitLoadOfLValue(LHS, Loc);
1274e3b55780SDimitry Andric     if (!PromotionTypeLHS.isNull())
1275e3b55780SDimitry Andric       OpInfo.LHS =
1276e3b55780SDimitry Andric           EmitComplexToComplexCast(LHSVal, LHSTy, PromotionTypeLHS, Loc);
1277e3b55780SDimitry Andric     else
127845b53394SDimitry Andric       OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc);
1279bfef3995SDimitry Andric   } else {
128045b53394SDimitry Andric     llvm::Value *LHSVal = CGF.EmitLoadOfScalar(LHS, Loc);
128106d4ba38SDimitry Andric     // For floating point real operands we can directly pass the scalar form
128206d4ba38SDimitry Andric     // to the binary operator emission and potentially get more efficient code.
128306d4ba38SDimitry Andric     if (LHSTy->isRealFloatingType()) {
1284e3b55780SDimitry Andric       QualType PromotedComplexElementTy;
1285e3b55780SDimitry Andric       if (!PromotionTypeLHS.isNull()) {
1286e3b55780SDimitry Andric         PromotedComplexElementTy =
1287e3b55780SDimitry Andric             cast<ComplexType>(PromotionTypeLHS)->getElementType();
1288e3b55780SDimitry Andric         if (!CGF.getContext().hasSameUnqualifiedType(PromotedComplexElementTy,
1289e3b55780SDimitry Andric                                                      PromotionTypeLHS))
1290e3b55780SDimitry Andric           LHSVal = CGF.EmitScalarConversion(LHSVal, LHSTy,
1291e3b55780SDimitry Andric                                             PromotedComplexElementTy, Loc);
1292e3b55780SDimitry Andric       } else {
129306d4ba38SDimitry Andric         if (!CGF.getContext().hasSameUnqualifiedType(ComplexElementTy, LHSTy))
1294e3b55780SDimitry Andric           LHSVal =
1295e3b55780SDimitry Andric               CGF.EmitScalarConversion(LHSVal, LHSTy, ComplexElementTy, Loc);
1296e3b55780SDimitry Andric       }
129706d4ba38SDimitry Andric       OpInfo.LHS = ComplexPairTy(LHSVal, nullptr);
129806d4ba38SDimitry Andric     } else {
129945b53394SDimitry Andric       OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc);
1300bfef3995SDimitry Andric     }
130106d4ba38SDimitry Andric   }
1302ec2b103cSEd Schouten 
1303ec2b103cSEd Schouten   // Expand the binary operator.
1304ec2b103cSEd Schouten   ComplexPairTy Result = (this->*Func)(OpInfo);
1305ec2b103cSEd Schouten 
1306bfef3995SDimitry Andric   // Truncate the result and store it into the LHS lvalue.
1307bfef3995SDimitry Andric   if (LHSTy->isAnyComplexType()) {
130845b53394SDimitry Andric     ComplexPairTy ResVal =
130945b53394SDimitry Andric         EmitComplexToComplexCast(Result, OpInfo.Ty, LHSTy, Loc);
1310bfef3995SDimitry Andric     EmitStoreOfComplex(ResVal, LHS, /*isInit*/ false);
1311bfef3995SDimitry Andric     Val = RValue::getComplex(ResVal);
1312bfef3995SDimitry Andric   } else {
1313bfef3995SDimitry Andric     llvm::Value *ResVal =
131445b53394SDimitry Andric         CGF.EmitComplexToScalarConversion(Result, OpInfo.Ty, LHSTy, Loc);
1315bfef3995SDimitry Andric     CGF.EmitStoreOfScalar(ResVal, LHS, /*isInit*/ false);
1316bfef3995SDimitry Andric     Val = RValue::get(ResVal);
1317bfef3995SDimitry Andric   }
13184ba67500SRoman Divacky 
1319bca07a45SDimitry Andric   return LHS;
1320ec2b103cSEd Schouten }
1321ec2b103cSEd Schouten 
1322bca07a45SDimitry Andric // Compound assignments.
1323bca07a45SDimitry Andric ComplexPairTy ComplexExprEmitter::
EmitCompoundAssign(const CompoundAssignOperator * E,ComplexPairTy (ComplexExprEmitter::* Func)(const BinOpInfo &))1324bca07a45SDimitry Andric EmitCompoundAssign(const CompoundAssignOperator *E,
1325bca07a45SDimitry Andric                    ComplexPairTy (ComplexExprEmitter::*Func)(const BinOpInfo&)){
1326bfef3995SDimitry Andric   RValue Val;
1327bca07a45SDimitry Andric   LValue LV = EmitCompoundAssignLValue(E, Func, Val);
1328bca07a45SDimitry Andric 
1329bca07a45SDimitry Andric   // The result of an assignment in C is the assigned r-value.
133013cc256eSDimitry Andric   if (!CGF.getLangOpts().CPlusPlus)
1331bfef3995SDimitry Andric     return Val.getComplexVal();
1332bca07a45SDimitry Andric 
1333bca07a45SDimitry Andric   // If the lvalue is non-volatile, return the computed value of the assignment.
1334bca07a45SDimitry Andric   if (!LV.isVolatileQualified())
1335bfef3995SDimitry Andric     return Val.getComplexVal();
1336bca07a45SDimitry Andric 
1337bfef3995SDimitry Andric   return EmitLoadOfLValue(LV, E->getExprLoc());
1338bca07a45SDimitry Andric }
1339bca07a45SDimitry Andric 
EmitBinAssignLValue(const BinaryOperator * E,ComplexPairTy & Val)1340bca07a45SDimitry Andric LValue ComplexExprEmitter::EmitBinAssignLValue(const BinaryOperator *E,
1341bca07a45SDimitry Andric                                                ComplexPairTy &Val) {
13424e58654bSRoman Divacky   assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(),
13434e58654bSRoman Divacky                                                  E->getRHS()->getType()) &&
1344ec2b103cSEd Schouten          "Invalid assignment");
1345bca07a45SDimitry Andric   TestAndClearIgnoreReal();
1346bca07a45SDimitry Andric   TestAndClearIgnoreImag();
1347bca07a45SDimitry Andric 
1348bca07a45SDimitry Andric   // Emit the RHS.  __block variables need the RHS evaluated first.
1349bca07a45SDimitry Andric   Val = Visit(E->getRHS());
1350ec2b103cSEd Schouten 
1351ec2b103cSEd Schouten   // Compute the address to store into.
1352ec2b103cSEd Schouten   LValue LHS = CGF.EmitLValue(E->getLHS());
1353ec2b103cSEd Schouten 
13544ba67500SRoman Divacky   // Store the result value into the LHS lvalue.
1355809500fcSDimitry Andric   EmitStoreOfComplex(Val, LHS, /*isInit*/ false);
13567ef7bab7SEd Schouten 
1357bca07a45SDimitry Andric   return LHS;
1358bca07a45SDimitry Andric }
13594ba67500SRoman Divacky 
VisitBinAssign(const BinaryOperator * E)1360bca07a45SDimitry Andric ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
1361bca07a45SDimitry Andric   ComplexPairTy Val;
1362bca07a45SDimitry Andric   LValue LV = EmitBinAssignLValue(E, Val);
1363bca07a45SDimitry Andric 
1364bca07a45SDimitry Andric   // The result of an assignment in C is the assigned r-value.
136513cc256eSDimitry Andric   if (!CGF.getLangOpts().CPlusPlus)
1366bca07a45SDimitry Andric     return Val;
1367bca07a45SDimitry Andric 
1368bca07a45SDimitry Andric   // If the lvalue is non-volatile, return the computed value of the assignment.
1369bca07a45SDimitry Andric   if (!LV.isVolatileQualified())
1370bca07a45SDimitry Andric     return Val;
1371bca07a45SDimitry Andric 
1372bfef3995SDimitry Andric   return EmitLoadOfLValue(LV, E->getExprLoc());
13737ef7bab7SEd Schouten }
13747ef7bab7SEd Schouten 
VisitBinComma(const BinaryOperator * E)1375ec2b103cSEd Schouten ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) {
1376bca07a45SDimitry Andric   CGF.EmitIgnoredExpr(E->getLHS());
1377ec2b103cSEd Schouten   return Visit(E->getRHS());
1378ec2b103cSEd Schouten }
1379ec2b103cSEd Schouten 
1380ec2b103cSEd Schouten ComplexPairTy ComplexExprEmitter::
VisitAbstractConditionalOperator(const AbstractConditionalOperator * E)1381bca07a45SDimitry Andric VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
1382ec2b103cSEd Schouten   TestAndClearIgnoreReal();
1383ec2b103cSEd Schouten   TestAndClearIgnoreImag();
1384ec2b103cSEd Schouten   llvm::BasicBlock *LHSBlock = CGF.createBasicBlock("cond.true");
1385ec2b103cSEd Schouten   llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
1386ec2b103cSEd Schouten   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
1387ec2b103cSEd Schouten 
1388bca07a45SDimitry Andric   // Bind the common expression if necessary.
1389bca07a45SDimitry Andric   CodeGenFunction::OpaqueValueMapping binding(CGF, E);
1390bca07a45SDimitry Andric 
13915e20cdd8SDimitry Andric 
1392bca07a45SDimitry Andric   CodeGenFunction::ConditionalEvaluation eval(CGF);
13935e20cdd8SDimitry Andric   CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock,
13945e20cdd8SDimitry Andric                            CGF.getProfileCount(E));
1395ec2b103cSEd Schouten 
1396bca07a45SDimitry Andric   eval.begin(CGF);
1397ec2b103cSEd Schouten   CGF.EmitBlock(LHSBlock);
1398ac9a064cSDimitry Andric   if (llvm::EnableSingleByteCoverage)
1399ac9a064cSDimitry Andric     CGF.incrementProfileCounter(E->getTrueExpr());
1400ac9a064cSDimitry Andric   else
14015e20cdd8SDimitry Andric     CGF.incrementProfileCounter(E);
1402ac9a064cSDimitry Andric 
1403bca07a45SDimitry Andric   ComplexPairTy LHS = Visit(E->getTrueExpr());
1404ec2b103cSEd Schouten   LHSBlock = Builder.GetInsertBlock();
1405ec2b103cSEd Schouten   CGF.EmitBranch(ContBlock);
1406bca07a45SDimitry Andric   eval.end(CGF);
1407ec2b103cSEd Schouten 
1408bca07a45SDimitry Andric   eval.begin(CGF);
1409ec2b103cSEd Schouten   CGF.EmitBlock(RHSBlock);
1410ac9a064cSDimitry Andric   if (llvm::EnableSingleByteCoverage)
1411ac9a064cSDimitry Andric     CGF.incrementProfileCounter(E->getFalseExpr());
1412bca07a45SDimitry Andric   ComplexPairTy RHS = Visit(E->getFalseExpr());
1413ec2b103cSEd Schouten   RHSBlock = Builder.GetInsertBlock();
1414ec2b103cSEd Schouten   CGF.EmitBlock(ContBlock);
1415ac9a064cSDimitry Andric   if (llvm::EnableSingleByteCoverage)
1416ac9a064cSDimitry Andric     CGF.incrementProfileCounter(E);
1417bca07a45SDimitry Andric   eval.end(CGF);
1418ec2b103cSEd Schouten 
1419ec2b103cSEd Schouten   // Create a PHI node for the real part.
142001af97d3SDimitry Andric   llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), 2, "cond.r");
1421ec2b103cSEd Schouten   RealPN->addIncoming(LHS.first, LHSBlock);
1422ec2b103cSEd Schouten   RealPN->addIncoming(RHS.first, RHSBlock);
1423ec2b103cSEd Schouten 
1424ec2b103cSEd Schouten   // Create a PHI node for the imaginary part.
142501af97d3SDimitry Andric   llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), 2, "cond.i");
1426ec2b103cSEd Schouten   ImagPN->addIncoming(LHS.second, LHSBlock);
1427ec2b103cSEd Schouten   ImagPN->addIncoming(RHS.second, RHSBlock);
1428ec2b103cSEd Schouten 
1429ec2b103cSEd Schouten   return ComplexPairTy(RealPN, ImagPN);
1430ec2b103cSEd Schouten }
1431ec2b103cSEd Schouten 
VisitChooseExpr(ChooseExpr * E)1432ec2b103cSEd Schouten ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) {
1433bfef3995SDimitry Andric   return Visit(E->getChosenSubExpr());
1434ec2b103cSEd Schouten }
1435ec2b103cSEd Schouten 
VisitInitListExpr(InitListExpr * E)1436ec2b103cSEd Schouten ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) {
1437ec2b103cSEd Schouten     bool Ignore = TestAndClearIgnoreReal();
1438ec2b103cSEd Schouten     (void)Ignore;
1439ec2b103cSEd Schouten     assert (Ignore == false && "init list ignored");
1440ec2b103cSEd Schouten     Ignore = TestAndClearIgnoreImag();
1441ec2b103cSEd Schouten     (void)Ignore;
1442ec2b103cSEd Schouten     assert (Ignore == false && "init list ignored");
144336981b17SDimitry Andric 
144436981b17SDimitry Andric   if (E->getNumInits() == 2) {
144536981b17SDimitry Andric     llvm::Value *Real = CGF.EmitScalarExpr(E->getInit(0));
144636981b17SDimitry Andric     llvm::Value *Imag = CGF.EmitScalarExpr(E->getInit(1));
144736981b17SDimitry Andric     return ComplexPairTy(Real, Imag);
144836981b17SDimitry Andric   } else if (E->getNumInits() == 1) {
1449ec2b103cSEd Schouten     return Visit(E->getInit(0));
145036981b17SDimitry Andric   }
1451ec2b103cSEd Schouten 
145248675466SDimitry Andric   // Empty init list initializes to null
145336981b17SDimitry Andric   assert(E->getNumInits() == 0 && "Unexpected number of inits");
1454809500fcSDimitry Andric   QualType Ty = E->getType()->castAs<ComplexType>()->getElementType();
145536981b17SDimitry Andric   llvm::Type* LTy = CGF.ConvertType(Ty);
1456ec2b103cSEd Schouten   llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy);
1457ec2b103cSEd Schouten   return ComplexPairTy(zeroConstant, zeroConstant);
1458ec2b103cSEd Schouten }
1459ec2b103cSEd Schouten 
VisitVAArgExpr(VAArgExpr * E)1460ec2b103cSEd Schouten ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) {
146145b53394SDimitry Andric   Address ArgValue = Address::invalid();
1462ac9a064cSDimitry Andric   RValue RV = CGF.EmitVAArg(E, ArgValue);
1463ec2b103cSEd Schouten 
1464ac9a064cSDimitry Andric   if (!ArgValue.isValid()) {
1465ec2b103cSEd Schouten     CGF.ErrorUnsupported(E, "complex va_arg expression");
146636981b17SDimitry Andric     llvm::Type *EltTy =
1467809500fcSDimitry Andric       CGF.ConvertType(E->getType()->castAs<ComplexType>()->getElementType());
1468ec2b103cSEd Schouten     llvm::Value *U = llvm::UndefValue::get(EltTy);
1469ec2b103cSEd Schouten     return ComplexPairTy(U, U);
1470ec2b103cSEd Schouten   }
1471ec2b103cSEd Schouten 
1472ac9a064cSDimitry Andric   return RV.getComplexVal();
1473ec2b103cSEd Schouten }
1474ec2b103cSEd Schouten 
1475ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
1476ec2b103cSEd Schouten //                         Entry Point into this File
1477ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
1478ec2b103cSEd Schouten 
1479ec2b103cSEd Schouten /// EmitComplexExpr - Emit the computation of the specified expression of
1480ec2b103cSEd Schouten /// complex type, ignoring the result.
EmitComplexExpr(const Expr * E,bool IgnoreReal,bool IgnoreImag)1481ec2b103cSEd Schouten ComplexPairTy CodeGenFunction::EmitComplexExpr(const Expr *E, bool IgnoreReal,
1482bca07a45SDimitry Andric                                                bool IgnoreImag) {
1483809500fcSDimitry Andric   assert(E && getComplexType(E->getType()) &&
1484ec2b103cSEd Schouten          "Invalid complex expression to emit");
1485ec2b103cSEd Schouten 
1486bca07a45SDimitry Andric   return ComplexExprEmitter(*this, IgnoreReal, IgnoreImag)
1487ec2b103cSEd Schouten       .Visit(const_cast<Expr *>(E));
1488ec2b103cSEd Schouten }
1489ec2b103cSEd Schouten 
EmitComplexExprIntoLValue(const Expr * E,LValue dest,bool isInit)1490809500fcSDimitry Andric void CodeGenFunction::EmitComplexExprIntoLValue(const Expr *E, LValue dest,
1491809500fcSDimitry Andric                                                 bool isInit) {
1492809500fcSDimitry Andric   assert(E && getComplexType(E->getType()) &&
1493ec2b103cSEd Schouten          "Invalid complex expression to emit");
1494ec2b103cSEd Schouten   ComplexExprEmitter Emitter(*this);
1495ec2b103cSEd Schouten   ComplexPairTy Val = Emitter.Visit(const_cast<Expr*>(E));
1496809500fcSDimitry Andric   Emitter.EmitStoreOfComplex(Val, dest, isInit);
1497ec2b103cSEd Schouten }
1498ec2b103cSEd Schouten 
1499809500fcSDimitry Andric /// EmitStoreOfComplex - Store a complex number into the specified l-value.
EmitStoreOfComplex(ComplexPairTy V,LValue dest,bool isInit)1500809500fcSDimitry Andric void CodeGenFunction::EmitStoreOfComplex(ComplexPairTy V, LValue dest,
1501809500fcSDimitry Andric                                          bool isInit) {
1502809500fcSDimitry Andric   ComplexExprEmitter(*this).EmitStoreOfComplex(V, dest, isInit);
1503ec2b103cSEd Schouten }
1504ec2b103cSEd Schouten 
1505809500fcSDimitry Andric /// EmitLoadOfComplex - Load a complex number from the specified address.
EmitLoadOfComplex(LValue src,SourceLocation loc)1506bfef3995SDimitry Andric ComplexPairTy CodeGenFunction::EmitLoadOfComplex(LValue src,
1507bfef3995SDimitry Andric                                                  SourceLocation loc) {
1508bfef3995SDimitry Andric   return ComplexExprEmitter(*this).EmitLoadOfLValue(src, loc);
1509ec2b103cSEd Schouten }
1510bca07a45SDimitry Andric 
EmitComplexAssignmentLValue(const BinaryOperator * E)1511bca07a45SDimitry Andric LValue CodeGenFunction::EmitComplexAssignmentLValue(const BinaryOperator *E) {
1512bca07a45SDimitry Andric   assert(E->getOpcode() == BO_Assign);
1513bca07a45SDimitry Andric   ComplexPairTy Val; // ignored
1514706b4fc4SDimitry Andric   LValue LVal = ComplexExprEmitter(*this).EmitBinAssignLValue(E, Val);
1515706b4fc4SDimitry Andric   if (getLangOpts().OpenMP)
1516706b4fc4SDimitry Andric     CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(*this,
1517706b4fc4SDimitry Andric                                                               E->getLHS());
1518706b4fc4SDimitry Andric   return LVal;
1519bca07a45SDimitry Andric }
1520bca07a45SDimitry Andric 
1521bfef3995SDimitry Andric typedef ComplexPairTy (ComplexExprEmitter::*CompoundFunc)(
1522bfef3995SDimitry Andric     const ComplexExprEmitter::BinOpInfo &);
1523bca07a45SDimitry Andric 
getComplexOp(BinaryOperatorKind Op)1524bfef3995SDimitry Andric static CompoundFunc getComplexOp(BinaryOperatorKind Op) {
1525bfef3995SDimitry Andric   switch (Op) {
1526bfef3995SDimitry Andric   case BO_MulAssign: return &ComplexExprEmitter::EmitBinMul;
1527bfef3995SDimitry Andric   case BO_DivAssign: return &ComplexExprEmitter::EmitBinDiv;
1528bfef3995SDimitry Andric   case BO_SubAssign: return &ComplexExprEmitter::EmitBinSub;
1529bfef3995SDimitry Andric   case BO_AddAssign: return &ComplexExprEmitter::EmitBinAdd;
1530bca07a45SDimitry Andric   default:
1531bca07a45SDimitry Andric     llvm_unreachable("unexpected complex compound assignment");
1532bca07a45SDimitry Andric   }
1533bfef3995SDimitry Andric }
1534bca07a45SDimitry Andric 
1535bfef3995SDimitry Andric LValue CodeGenFunction::
EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator * E)1536bfef3995SDimitry Andric EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E) {
1537bfef3995SDimitry Andric   CompoundFunc Op = getComplexOp(E->getOpcode());
1538bfef3995SDimitry Andric   RValue Val;
1539bca07a45SDimitry Andric   return ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);
1540bca07a45SDimitry Andric }
1541bfef3995SDimitry Andric 
1542bfef3995SDimitry Andric LValue CodeGenFunction::
EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator * E,llvm::Value * & Result)15435e20cdd8SDimitry Andric EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E,
1544bfef3995SDimitry Andric                                     llvm::Value *&Result) {
1545bfef3995SDimitry Andric   CompoundFunc Op = getComplexOp(E->getOpcode());
1546bfef3995SDimitry Andric   RValue Val;
1547bfef3995SDimitry Andric   LValue Ret = ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);
1548bfef3995SDimitry Andric   Result = Val.getScalarVal();
1549bfef3995SDimitry Andric   return Ret;
1550bfef3995SDimitry Andric }
1551