18#include "llvm/IR/Constants.h"
19#include "llvm/IR/Instructions.h"
20#include "llvm/IR/MDBuilder.h"
21#include "llvm/IR/Metadata.h"
23using namespace CodeGen;
41 return cast<ComplexType>(cast<AtomicType>(
type)->getValueType());
46class ComplexExprEmitter
47 :
public StmtVisitor<ComplexExprEmitter, ComplexPairTy> {
52 bool FPHasBeenPromoted;
55 ComplexExprEmitter(
CodeGenFunction &cgf,
bool ir =
false,
bool ii =
false)
56 : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii),
57 FPHasBeenPromoted(
false) {}
63 bool TestAndClearIgnoreReal() {
68 bool TestAndClearIgnoreImag() {
105 llvm_unreachable(
"Stmt can't have complex result type!");
111 Result->getAggregateElement(1U));
112 return Visit(
E->getSubExpr());
116 return Visit(
GE->getResultExpr());
130 return Visit(
E->getSubExpr());
133 ComplexPairTy emitConstant(
const CodeGenFunction::ConstantEmission &Constant,
135 assert(Constant &&
"not a constant");
136 if (Constant.isReference())
137 return EmitLoadOfLValue(Constant.getReferenceLValue(CGF,
E),
140 llvm::Constant *pair = Constant.getValue();
142 pair->getAggregateElement(1U));
148 return emitConstant(Constant,
E);
149 return EmitLoadOfLValue(
E);
152 return EmitLoadOfLValue(
E);
159 if (CodeGenFunction::ConstantEmission Constant =
162 return emitConstant(Constant, ME);
164 return EmitLoadOfLValue(ME);
183 if (
E->changesVolatileQualification())
184 return EmitLoadOfLValue(
E);
185 return EmitCast(
E->getCastKind(),
E->getSubExpr(),
E->
getType());
188 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(
E))
190 if (
E->changesVolatileQualification())
191 return EmitLoadOfLValue(
E);
192 return EmitCast(
E->getCastKind(),
E->getSubExpr(),
E->
getType());
199 bool isInc,
bool isPre) {
204 return VisitPrePostIncDec(
E,
false,
false);
207 return VisitPrePostIncDec(
E,
true,
false);
210 return VisitPrePostIncDec(
E,
false,
true);
213 return VisitPrePostIncDec(
E,
true,
true);
226 return Visit(
E->getSubExpr());
229 CodeGenFunction::CXXDefaultArgExprScope
Scope(CGF, DAE);
233 CodeGenFunction::CXXDefaultInitExprScope
Scope(CGF, DIE);
237 CodeGenFunction::RunCleanupsScope
Scope(CGF);
241 Scope.ForceCleanup({&Vals.first, &Vals.second});
247 llvm::Constant *
Null = llvm::Constant::getNullValue(CGF.
ConvertType(Elem));
253 llvm::Constant *
Null =
254 llvm::Constant::getNullValue(CGF.
ConvertType(Elem));
275 (
const BinOpInfo &));
281 ComplexPairTy EmitAlgebraicDiv(llvm::Value *A, llvm::Value *B, llvm::Value *
C,
283 ComplexPairTy EmitRangeReductionDiv(llvm::Value *A, llvm::Value *B,
284 llvm::Value *
C, llvm::Value *
D);
287 const BinOpInfo &Op);
294 const llvm::fltSemantics &ElementTypeSemantics =
296 const llvm::fltSemantics &HigherElementTypeSemantics =
305 if (llvm::APFloat::semanticsMaxExponent(ElementTypeSemantics) * 2 + 1 <=
306 llvm::APFloat::semanticsMaxExponent(HigherElementTypeSemantics)) {
307 FPHasBeenPromoted =
true;
317 bool IsDivOpCode =
false) {
319 QualType ElementType = CT->getElementType();
321 bool IsComplexRangePromoted = CGF.
getLangOpts().getComplexRange() ==
322 LangOptions::ComplexRangeKind::CX_Promoted;
323 bool HasNoComplexRangeOverride = !Features.hasComplexRangeOverride();
324 bool HasMatchingComplexRange = Features.hasComplexRangeOverride() &&
325 Features.getComplexRangeOverride() ==
328 if (IsDivOpCode && IsFloatingType && IsComplexRangePromoted &&
329 (HasNoComplexRangeOverride || HasMatchingComplexRange))
330 return HigherPrecisionTypeForComplexArithmetic(ElementType,
340#define HANDLEBINOP(OP) \
341 ComplexPairTy VisitBin##OP(const BinaryOperator *E) { \
342 QualType promotionTy = getPromotionType( \
343 E->getStoredFPFeaturesOrDefault(), E->getType(), \
344 (E->getOpcode() == BinaryOperatorKind::BO_Div) ? true : false); \
345 ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy)); \
346 if (!promotionTy.isNull()) \
347 result = CGF.EmitUnPromotedValue(result, E->getType()); \
358 return Visit(
E->getSemanticForm());
363 return EmitCompoundAssign(
E, &ComplexExprEmitter::EmitBinAdd);
366 return EmitCompoundAssign(
E, &ComplexExprEmitter::EmitBinSub);
369 return EmitCompoundAssign(
E, &ComplexExprEmitter::EmitBinMul);
372 return EmitCompoundAssign(
E, &ComplexExprEmitter::EmitBinDiv);
393 return EmitLoadOfLValue(
E);
403 return Visit(
E->getSelectedExpr());
426 assert(lvalue.
isSimple() &&
"non-simple complex l-value?");
433 llvm::Value *Real =
nullptr, *Imag =
nullptr;
435 if (!IgnoreReal || isVolatile) {
437 Real = Builder.CreateLoad(RealP, isVolatile, SrcPtr.
getName() +
".real");
440 if (!IgnoreImag || isVolatile) {
442 Imag = Builder.CreateLoad(ImagP, isVolatile, SrcPtr.
getName() +
".imag");
474 llvm::Value *
U = llvm::PoisonValue::get(EltTy);
481 return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag);
486 if (
E->getCallReturnType(CGF.
getContext())->isReferenceType())
487 return EmitLoadOfLValue(
E);
493 CodeGenFunction::StmtExprEvaluation eval(CGF);
495 assert(RetAlloca.
isValid() &&
"Expected complex return value");
519ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val,
528 return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType()));
534 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
538 case CK_AtomicToNonAtomic:
539 case CK_NonAtomicToAtomic:
541 case CK_LValueToRValue:
542 case CK_UserDefinedConversion:
545 case CK_LValueBitCast: {
551 case CK_LValueToRValueBitCast: {
557 return EmitLoadOfLValue(DestLV, Op->
getExprLoc());
561 case CK_BaseToDerived:
562 case CK_DerivedToBase:
563 case CK_UncheckedDerivedToBase:
566 case CK_ArrayToPointerDecay:
567 case CK_FunctionToPointerDecay:
568 case CK_NullToPointer:
569 case CK_NullToMemberPointer:
570 case CK_BaseToDerivedMemberPointer:
571 case CK_DerivedToBaseMemberPointer:
572 case CK_MemberPointerToBoolean:
573 case CK_ReinterpretMemberPointer:
574 case CK_ConstructorConversion:
575 case CK_IntegralToPointer:
576 case CK_PointerToIntegral:
577 case CK_PointerToBoolean:
580 case CK_IntegralCast:
581 case CK_BooleanToSignedIntegral:
582 case CK_IntegralToBoolean:
583 case CK_IntegralToFloating:
584 case CK_FloatingToIntegral:
585 case CK_FloatingToBoolean:
586 case CK_FloatingCast:
587 case CK_CPointerToObjCPointerCast:
588 case CK_BlockPointerToObjCPointerCast:
589 case CK_AnyPointerToBlockPointerCast:
590 case CK_ObjCObjectLValueCast:
591 case CK_FloatingComplexToReal:
592 case CK_FloatingComplexToBoolean:
593 case CK_IntegralComplexToReal:
594 case CK_IntegralComplexToBoolean:
595 case CK_ARCProduceObject:
596 case CK_ARCConsumeObject:
597 case CK_ARCReclaimReturnedObject:
598 case CK_ARCExtendBlockObject:
599 case CK_CopyAndAutoreleaseBlockObject:
600 case CK_BuiltinFnToFnPtr:
601 case CK_ZeroToOCLOpaqueType:
602 case CK_AddressSpaceConversion:
603 case CK_IntToOCLSampler:
604 case CK_FloatingToFixedPoint:
605 case CK_FixedPointToFloating:
606 case CK_FixedPointCast:
607 case CK_FixedPointToBoolean:
608 case CK_FixedPointToIntegral:
609 case CK_IntegralToFixedPoint:
611 case CK_HLSLVectorTruncation:
612 case CK_HLSLArrayRValue:
613 llvm_unreachable(
"invalid cast kind for complex value");
615 case CK_FloatingRealToComplex:
616 case CK_IntegralRealToComplex: {
617 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op);
622 case CK_FloatingComplexCast:
623 case CK_FloatingComplexToIntegralComplex:
624 case CK_IntegralComplexCast:
625 case CK_IntegralComplexToFloatingComplex: {
626 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op);
627 return EmitComplexToComplexCast(Visit(Op), Op->
getType(), DestTy,
632 llvm_unreachable(
"unknown cast resulting in complex value");
639 ? getPromotionType(
E->getStoredFPFeaturesOrDefault(),
643 if (!promotionTy.
isNull())
650 TestAndClearIgnoreReal();
651 TestAndClearIgnoreImag();
652 if (!PromotionType.
isNull())
654 return Visit(
E->getSubExpr());
661 ? getPromotionType(
E->getStoredFPFeaturesOrDefault(),
665 if (!promotionTy.
isNull())
671 TestAndClearIgnoreReal();
672 TestAndClearIgnoreImag();
674 if (!PromotionType.
isNull())
677 Op = Visit(
E->getSubExpr());
679 llvm::Value *ResR, *ResI;
680 if (Op.first->getType()->isFloatingPointTy()) {
681 ResR = Builder.CreateFNeg(Op.first,
"neg.r");
682 ResI = Builder.CreateFNeg(Op.second,
"neg.i");
684 ResR = Builder.CreateNeg(Op.first,
"neg.r");
685 ResI = Builder.CreateNeg(Op.second,
"neg.i");
691 TestAndClearIgnoreReal();
692 TestAndClearIgnoreImag();
696 if (Op.second->getType()->isFloatingPointTy())
697 ResI = Builder.CreateFNeg(Op.second,
"conj.i");
699 ResI = Builder.CreateNeg(Op.second,
"conj.i");
704ComplexPairTy ComplexExprEmitter::EmitBinAdd(
const BinOpInfo &Op) {
705 llvm::Value *ResR, *ResI;
707 if (Op.LHS.first->getType()->isFloatingPointTy()) {
708 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
709 ResR = Builder.CreateFAdd(Op.LHS.first, Op.RHS.first,
"add.r");
710 if (Op.LHS.second && Op.RHS.second)
711 ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second,
"add.i");
713 ResI = Op.LHS.second ? Op.LHS.second : Op.RHS.second;
714 assert(ResI &&
"Only one operand may be real!");
716 ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first,
"add.r");
717 assert(Op.LHS.second && Op.RHS.second &&
718 "Both operands of integer complex operators must be complex!");
719 ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second,
"add.i");
724ComplexPairTy ComplexExprEmitter::EmitBinSub(
const BinOpInfo &Op) {
725 llvm::Value *ResR, *ResI;
726 if (Op.LHS.first->getType()->isFloatingPointTy()) {
727 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
728 ResR = Builder.CreateFSub(Op.LHS.first, Op.RHS.first,
"sub.r");
729 if (Op.LHS.second && Op.RHS.second)
730 ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second,
"sub.i");
732 ResI = Op.LHS.second ? Op.LHS.second
733 : Builder.CreateFNeg(Op.RHS.second,
"sub.i");
734 assert(ResI &&
"Only one operand may be real!");
736 ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first,
"sub.r");
737 assert(Op.LHS.second && Op.RHS.second &&
738 "Both operands of integer complex operators must be complex!");
739 ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second,
"sub.i");
745ComplexPairTy ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName,
746 const BinOpInfo &Op) {
770 Args, cast<FunctionType>(FQTy.
getTypePtr()),
false);
774 FTy, LibCallName, llvm::AttributeList(),
true);
777 llvm::CallBase *
Call;
786 switch (Ty->getTypeID()) {
788 llvm_unreachable(
"Unsupported floating point type!");
789 case llvm::Type::HalfTyID:
791 case llvm::Type::FloatTyID:
793 case llvm::Type::DoubleTyID:
795 case llvm::Type::PPC_FP128TyID:
797 case llvm::Type::X86_FP80TyID:
799 case llvm::Type::FP128TyID:
806ComplexPairTy ComplexExprEmitter::EmitBinMul(
const BinOpInfo &Op) {
811 if (Op.LHS.first->getType()->isFloatingPointTy()) {
818 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
819 if (Op.LHS.second && Op.RHS.second) {
830 Value *AC = Builder.CreateFMul(Op.LHS.first, Op.RHS.first,
"mul_ac");
831 Value *BD = Builder.CreateFMul(Op.LHS.second, Op.RHS.second,
"mul_bd");
832 Value *AD = Builder.CreateFMul(Op.LHS.first, Op.RHS.second,
"mul_ad");
833 Value *BC = Builder.CreateFMul(Op.LHS.second, Op.RHS.first,
"mul_bc");
837 ResR = Builder.CreateFSub(AC, BD,
"mul_r");
838 ResI = Builder.CreateFAdd(AD, BC,
"mul_i");
847 Value *IsRNaN = Builder.CreateFCmpUNO(ResR, ResR,
"isnan_cmp");
850 llvm::Instruction *Branch = Builder.CreateCondBr(IsRNaN, INaNBB, ContBB);
851 llvm::BasicBlock *OrigBB = Branch->getParent();
854 llvm::MDNode *BrWeight = MDHelper.createUnlikelyBranchWeights();
855 Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight);
859 Value *IsINaN = Builder.CreateFCmpUNO(ResI, ResI,
"isnan_cmp");
861 Branch = Builder.CreateCondBr(IsINaN, LibCallBB, ContBB);
862 Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight);
866 Value *LibCallR, *LibCallI;
867 std::tie(LibCallR, LibCallI) = EmitComplexBinOpLibCall(
869 Builder.CreateBr(ContBB);
874 llvm::PHINode *RealPHI = Builder.CreatePHI(ResR->
getType(), 3,
"real_mul_phi");
875 RealPHI->addIncoming(ResR, OrigBB);
876 RealPHI->addIncoming(ResR, INaNBB);
877 RealPHI->addIncoming(LibCallR, LibCallBB);
878 llvm::PHINode *ImagPHI = Builder.CreatePHI(ResI->
getType(), 3,
"imag_mul_phi");
879 ImagPHI->addIncoming(ResI, OrigBB);
880 ImagPHI->addIncoming(ResI, INaNBB);
881 ImagPHI->addIncoming(LibCallI, LibCallBB);
884 assert((Op.LHS.second || Op.RHS.second) &&
885 "At least one operand must be complex!");
890 ResR = Builder.CreateFMul(Op.LHS.first, Op.RHS.first,
"mul.rl");
893 ? Builder.CreateFMul(Op.LHS.second, Op.RHS.first,
"mul.il")
894 : Builder.CreateFMul(Op.LHS.first, Op.RHS.second,
"mul.ir");
896 assert(Op.LHS.second && Op.RHS.second &&
897 "Both operands of integer complex operators must be complex!");
898 Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first,
"mul.rl");
899 Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second,
"mul.rr");
900 ResR = Builder.CreateSub(ResRl, ResRr,
"mul.r");
902 Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first,
"mul.il");
903 Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second,
"mul.ir");
904 ResI = Builder.CreateAdd(ResIl, ResIr,
"mul.i");
909ComplexPairTy ComplexExprEmitter::EmitAlgebraicDiv(llvm::Value *LHSr,
914 llvm::Value *DSTr, *DSTi;
916 llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr);
917 llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi);
918 llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD);
920 llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr);
921 llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi);
922 llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD);
924 llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr);
925 llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi);
926 llvm::Value *BCmAD = Builder.CreateFSub(BC, AD);
928 DSTr = Builder.CreateFDiv(ACpBD, CCpDD);
929 DSTi = Builder.CreateFDiv(BCmAD, CCpDD);
935 llvm::Function *
Func =
943ComplexPairTy ComplexExprEmitter::EmitRangeReductionDiv(llvm::Value *LHSr,
954 llvm::Value *IsR = Builder.CreateFCmpUGT(FAbsRHSr, FAbsRHSi,
"abs_cmp");
956 llvm::BasicBlock *TrueBB =
958 llvm::BasicBlock *FalseBB =
961 Builder.CreateCondBr(IsR, TrueBB, FalseBB);
969 llvm::Value *DdC = Builder.CreateFDiv(RHSi, RHSr);
971 llvm::Value *RD = Builder.CreateFMul(DdC, RHSi);
972 llvm::Value *CpRD = Builder.CreateFAdd(RHSr, RD);
974 llvm::Value *T3 = Builder.CreateFMul(LHSi, DdC);
975 llvm::Value *T4 = Builder.CreateFAdd(LHSr, T3);
976 llvm::Value *DSTTr = Builder.CreateFDiv(T4, CpRD);
978 llvm::Value *T5 = Builder.CreateFMul(LHSr, DdC);
979 llvm::Value *T6 = Builder.CreateFSub(LHSi, T5);
980 llvm::Value *DSTTi = Builder.CreateFDiv(T6, CpRD);
981 Builder.CreateBr(ContBB);
989 llvm::Value *CdD = Builder.CreateFDiv(RHSr, RHSi);
991 llvm::Value *RC = Builder.CreateFMul(CdD, RHSr);
992 llvm::Value *DpRC = Builder.CreateFAdd(RHSi, RC);
994 llvm::Value *T7 = Builder.CreateFMul(LHSr, CdD);
995 llvm::Value *T8 = Builder.CreateFAdd(T7, LHSi);
996 llvm::Value *DSTFr = Builder.CreateFDiv(T8, DpRC);
998 llvm::Value *T9 = Builder.CreateFMul(LHSi, CdD);
999 llvm::Value *T10 = Builder.CreateFSub(T9, LHSr);
1000 llvm::Value *DSTFi = Builder.CreateFDiv(T10, DpRC);
1001 Builder.CreateBr(ContBB);
1005 llvm::PHINode *VALr = Builder.CreatePHI(DSTTr->getType(), 2);
1006 VALr->addIncoming(DSTTr, TrueBB);
1007 VALr->addIncoming(DSTFr, FalseBB);
1008 llvm::PHINode *VALi = Builder.CreatePHI(DSTTi->getType(), 2);
1009 VALi->addIncoming(DSTTi, TrueBB);
1010 VALi->addIncoming(DSTFi, FalseBB);
1016ComplexPairTy ComplexExprEmitter::EmitBinDiv(
const BinOpInfo &Op) {
1017 llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second;
1018 llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second;
1019 llvm::Value *DSTr, *DSTi;
1020 if (LHSr->getType()->isFloatingPointTy()) {
1021 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
1023 assert(LHSi &&
"Can have at most one non-complex operand!");
1025 DSTr = Builder.CreateFDiv(LHSr, RHSr);
1026 DSTi = Builder.CreateFDiv(LHSi, RHSr);
1029 llvm::Value *OrigLHSi = LHSi;
1031 LHSi = llvm::Constant::getNullValue(RHSi->getType());
1034 !FPHasBeenPromoted))
1035 return EmitRangeReductionDiv(LHSr, LHSi, RHSr, RHSi);
1038 return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi);
1047 BinOpInfo LibCallOp = Op;
1050 LibCallOp.LHS.second = llvm::Constant::getNullValue(LHSr->getType());
1052 switch (LHSr->getType()->getTypeID()) {
1054 llvm_unreachable(
"Unsupported floating point type!");
1055 case llvm::Type::HalfTyID:
1056 return EmitComplexBinOpLibCall(
"__divhc3", LibCallOp);
1057 case llvm::Type::FloatTyID:
1058 return EmitComplexBinOpLibCall(
"__divsc3", LibCallOp);
1059 case llvm::Type::DoubleTyID:
1060 return EmitComplexBinOpLibCall(
"__divdc3", LibCallOp);
1061 case llvm::Type::PPC_FP128TyID:
1062 return EmitComplexBinOpLibCall(
"__divtc3", LibCallOp);
1063 case llvm::Type::X86_FP80TyID:
1064 return EmitComplexBinOpLibCall(
"__divxc3", LibCallOp);
1065 case llvm::Type::FP128TyID:
1066 return EmitComplexBinOpLibCall(
"__divtc3", LibCallOp);
1069 return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi);
1072 assert(Op.LHS.second && Op.RHS.second &&
1073 "Both operands of integer complex operators must be complex!");
1075 llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr);
1076 llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi);
1077 llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2);
1079 llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr);
1080 llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi);
1081 llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5);
1083 llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr);
1084 llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi);
1085 llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8);
1088 DSTr = Builder.CreateUDiv(Tmp3, Tmp6);
1089 DSTi = Builder.CreateUDiv(Tmp9, Tmp6);
1091 DSTr = Builder.CreateSDiv(Tmp3, Tmp6);
1092 DSTi = Builder.CreateSDiv(Tmp9, Tmp6);
1101 llvm::Type *ComplexElementTy =
1105 Builder.CreateFPTrunc(result.first, ComplexElementTy,
"unpromotion");
1108 Builder.CreateFPTrunc(result.second, ComplexElementTy,
"unpromotion");
1114 llvm::Type *ComplexElementTy =
1117 result.first =
Builder.CreateFPExt(result.first, ComplexElementTy,
"ext");
1119 result.second =
Builder.CreateFPExt(result.second, ComplexElementTy,
"ext");
1127 if (
auto BO = dyn_cast<BinaryOperator>(
E)) {
1128 switch (BO->getOpcode()) {
1129#define HANDLE_BINOP(OP) \
1131 return EmitBin##OP(EmitBinOps(BO, PromotionType));
1140 }
else if (
auto UO = dyn_cast<UnaryOperator>(
E)) {
1141 switch (UO->getOpcode()) {
1143 return VisitMinus(UO, PromotionType);
1145 return VisitPlus(UO, PromotionType);
1150 auto result = Visit(
const_cast<Expr *
>(
E));
1151 if (!PromotionType.
isNull())
1159 return ComplexExprEmitter(*this).EmitPromoted(
E, DstTy);
1163ComplexExprEmitter::EmitPromotedComplexOperand(
const Expr *
E,
1166 if (!OverallPromotionType.
isNull())
1169 return Visit(
const_cast<Expr *
>(
E));
1171 if (!OverallPromotionType.
isNull()) {
1182ComplexExprEmitter::BinOpInfo
1185 TestAndClearIgnoreReal();
1186 TestAndClearIgnoreImag();
1189 Ops.LHS = EmitPromotedComplexOperand(
E->getLHS(), PromotionType);
1190 Ops.RHS = EmitPromotedComplexOperand(
E->getRHS(), PromotionType);
1191 if (!PromotionType.
isNull())
1192 Ops.Ty = PromotionType;
1200LValue ComplexExprEmitter::
1204 TestAndClearIgnoreReal();
1205 TestAndClearIgnoreImag();
1208 LHSTy = AT->getValueType();
1212 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
1218 PromotionTypeCR = getPromotionType(
E->getStoredFPFeaturesOrDefault(),
1219 E->getComputationResultType());
1220 if (PromotionTypeCR.
isNull())
1221 PromotionTypeCR =
E->getComputationResultType();
1222 OpInfo.Ty = PromotionTypeCR;
1225 QualType PromotionTypeRHS = getPromotionType(
1226 E->getStoredFPFeaturesOrDefault(),
E->getRHS()->
getType());
1230 if (!PromotionTypeRHS.
isNull())
1240 if (!PromotionTypeRHS.
isNull()) {
1246 OpInfo.RHS = Visit(
E->getRHS());
1254 QualType PromotionTypeLHS = getPromotionType(
1255 E->getStoredFPFeaturesOrDefault(),
E->getComputationLHSType());
1258 if (!PromotionTypeLHS.
isNull())
1260 EmitComplexToComplexCast(LHSVal, LHSTy, PromotionTypeLHS,
Loc);
1262 OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty,
Loc);
1269 if (!PromotionTypeLHS.
isNull()) {
1270 PromotedComplexElementTy =
1271 cast<ComplexType>(PromotionTypeLHS)->getElementType();
1275 PromotedComplexElementTy,
Loc);
1283 OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty,
Loc);
1293 EmitComplexToComplexCast(
Result, OpInfo.Ty, LHSTy,
Loc);
1294 EmitStoreOfComplex(ResVal, LHS,
false);
1297 llvm::Value *ResVal =
1311 LValue LV = EmitCompoundAssignLValue(
E,
Func, Val);
1328 "Invalid assignment");
1329 TestAndClearIgnoreReal();
1330 TestAndClearIgnoreImag();
1333 Val = Visit(
E->getRHS());
1339 EmitStoreOfComplex(Val, LHS,
false);
1346 LValue LV = EmitBinAssignLValue(
E, Val);
1361 return Visit(
E->getRHS());
1366 TestAndClearIgnoreReal();
1367 TestAndClearIgnoreImag();
1373 CodeGenFunction::OpaqueValueMapping binding(CGF,
E);
1376 CodeGenFunction::ConditionalEvaluation eval(CGF);
1388 LHSBlock = Builder.GetInsertBlock();
1397 RHSBlock = Builder.GetInsertBlock();
1404 llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), 2,
"cond.r");
1405 RealPN->addIncoming(LHS.first, LHSBlock);
1406 RealPN->addIncoming(RHS.first, RHSBlock);
1409 llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), 2,
"cond.i");
1410 ImagPN->addIncoming(LHS.second, LHSBlock);
1411 ImagPN->addIncoming(RHS.second, RHSBlock);
1417 return Visit(
E->getChosenSubExpr());
1421 bool Ignore = TestAndClearIgnoreReal();
1423 assert (Ignore ==
false &&
"init list ignored");
1424 Ignore = TestAndClearIgnoreImag();
1426 assert (Ignore ==
false &&
"init list ignored");
1428 if (
E->getNumInits() == 2) {
1432 }
else if (
E->getNumInits() == 1) {
1433 return Visit(
E->getInit(0));
1437 assert(
E->getNumInits() == 0 &&
"Unexpected number of inits");
1440 llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy);
1452 llvm::Value *
U = llvm::PoisonValue::get(EltTy);
1468 "Invalid complex expression to emit");
1470 return ComplexExprEmitter(*
this, IgnoreReal, IgnoreImag)
1471 .Visit(
const_cast<Expr *
>(
E));
1477 "Invalid complex expression to emit");
1478 ComplexExprEmitter
Emitter(*
this);
1480 Emitter.EmitStoreOfComplex(Val, dest, isInit);
1486 ComplexExprEmitter(*this).EmitStoreOfComplex(
V, dest, isInit);
1492 return ComplexExprEmitter(*this).EmitLoadOfLValue(src, loc);
1496 assert(
E->getOpcode() == BO_Assign);
1498 LValue LVal = ComplexExprEmitter(*this).EmitBinAssignLValue(
E, Val);
1506 const ComplexExprEmitter::BinOpInfo &);
1510 case BO_MulAssign:
return &ComplexExprEmitter::EmitBinMul;
1511 case BO_DivAssign:
return &ComplexExprEmitter::EmitBinDiv;
1512 case BO_SubAssign:
return &ComplexExprEmitter::EmitBinSub;
1513 case BO_AddAssign:
return &ComplexExprEmitter::EmitBinAdd;
1515 llvm_unreachable(
"unexpected complex compound assignment");
1523 return ComplexExprEmitter(*this).EmitCompoundAssignLValue(
E, Op, Val);
1531 LValue Ret = ComplexExprEmitter(*this).EmitCompoundAssignLValue(
E, Op, Val);
ComplexPairTy(ComplexExprEmitter::* CompoundFunc)(const ComplexExprEmitter::BinOpInfo &)
static const ComplexType * getComplexType(QualType type)
Return the complex type that we are meant to emit.
CodeGenFunction::ComplexPairTy ComplexPairTy
static llvm::Value * EmitllvmFAbs(CodeGenFunction &CGF, llvm::Value *Value)
static StringRef getComplexMultiplyLibCallName(llvm::Type *Ty)
Lookup the libcall name for a given floating point type complex multiply.
static CompoundFunc getComplexOp(BinaryOperatorKind Op)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
const QualType GetHigherPrecisionFPType(QualType ElementType) const
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
A builtin binary operation expression such as "x + y" or "x <= y".
A default argument (C++ [dcl.fct.default]).
A use of a default initializer in a constructor or in aggregate initialization.
Expr * getExpr()
Get the initialization expression that will be used.
A rewritten comparison expression that was originally written using operator syntax.
An expression "T()" which creates an rvalue of a non-class type T.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Represents a 'co_await' expression.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
llvm::StringRef getName() const
Return the IR name of the pointer value.
A scoped helper to set the current debug location to the specified location or preferred location of ...
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
All available information about a concrete callee.
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
CGFunctionInfo - Class to encapsulate the information about a function definition.
virtual void checkAndEmitLastprivateConditional(CodeGenFunction &CGF, const Expr *LHS)
Checks if the provided LVal is lastprivate conditional and emits the code to update the value of the ...
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.
LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, llvm::Value *&Result)
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
RValue EmitAtomicLoad(LValue LV, SourceLocation SL, AggValueSlot Slot=AggValueSlot::ignored())
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const LangOptions & getLangOpts() const
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type,...
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
llvm::Type * ConvertTypeForMem(QualType T)
ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr)
void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit)
EmitComplexExprIntoLValue - Emit the given expression of complex type and place its result into the s...
ComplexPairTy EmitPromotedComplexExpr(const Expr *E, QualType PromotionType)
ComplexPairTy EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre)
RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc)
EmitLoadOfComplex - Load a complex number from the specified l-value.
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type,...
LValue EmitComplexAssignmentLValue(const BinaryOperator *E)
Emit an l-value for an assignment (simple or compound) of complex type.
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.
Address emitAddrOfImagComponent(Address complex, QualType complexType)
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
RValue EmitVAArg(VAArgExpr *VE, Address &VAListAddr, AggValueSlot Slot=AggValueSlot::ignored())
Generate code to get an argument from the passed in pointer and update it accordingly.
RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot=AggValueSlot::ignored())
ASTContext & getContext() const
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
ComplexPairTy EmitUnPromotedValue(ComplexPairTy result, QualType PromotionType)
ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType)
llvm::Value * EmitPromotedScalarExpr(const Expr *E, QualType PromotionType)
llvm::Type * ConvertType(QualType T)
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit)
llvm::Value * EmitScalarConversion(llvm::Value *Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified type to the specified destination type, both of which are LLVM s...
RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its RValue mapping if it exists, otherwise create one.
RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot(), llvm::CallBase **CallOrInvoke=nullptr)
llvm::LLVMContext & getLLVMContext()
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
bool LValueIsSuitableForInlineAtomic(LValue Src)
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
Address emitAddrOfRealComponent(Address complex, QualType complexType)
LValue EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E)
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
RValue EmitAtomicExpr(AtomicExpr *E)
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
CodeGenTypes & getTypes()
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const CGFunctionInfo & arrangeFreeFunctionCall(const CallArgList &Args, const FunctionType *Ty, bool ChainCall)
Figure out the rules for calling a function with the given formal type using the given arguments.
LValue - This represents an lvalue references.
bool isVolatileQualified() const
void setTBAAInfo(TBAAAccessInfo Info)
Address getAddress() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
Complex values, per C99 6.2.5p11.
QualType getElementType() const
CompoundAssignOperator - For compound assignments (e.g.
CompoundLiteralExpr - [C99 6.5.2.5].
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Represents a 'co_yield' expression.
A reference to a declared variable, function, enum, etc.
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents difference between two FPOptions values.
Represents a prototype with parameter type info, e.g.
Represents a C11 generic selection.
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
const Expr * getSubExpr() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Represents an implicitly-generated value initialization of an object of a given type.
Describes an C or C++ initializer list.
@ CX_Full
Implementation of complex division and multiplication using a call to runtime library functions(gener...
@ CX_Basic
Implementation of complex division and multiplication using algebraic formulas at source precision.
@ CX_Promoted
Implementation of complex division using algebraic formulas at higher precision.
@ CX_Improved
Implementation of complex division offering an improved handling for overflow in intermediate calcula...
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
An expression that sends a message to the given Objective-C object or class.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
ParenExpr - This represents a parenthesized expression, e.g.
const Expr * getSubExpr() const
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
bool UseExcessPrecision(const ASTContext &Ctx)
Scope - A scope is a transient data structure that is used while parsing the program.
Encodes a location in the source.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
RetTy Visit(PTR(Stmt) S, ParamTys... P)
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Stmt - This represents one statement.
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Expr * getReplacement() const
const T * castAs() const
Member-template castAs<specific type>.
bool isAnyComplexType() const
bool isAtomicType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * getAs() const
Member-template getAs<specific type>'.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Represents a call to the builtin function __builtin_va_arg.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ComplexType > complexType
Matches C99 complex types.
bool Null(InterpState &S, CodePtr OpPC, uint64_t Value, const Descriptor *Desc)
bool GE(InterpState &S, CodePtr OpPC)
bool Ret(InterpState &S, CodePtr &PC)
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
CastKind
CastKind - The kind of operation required for a conversion.
@ EST_BasicNoexcept
noexcept
Diagnostic wrappers for TextAPI types for error reporting.
cl::opt< bool > EnableSingleByteCoverage
llvm::CallingConv::ID getRuntimeCC() const
static TBAAAccessInfo getMayAliasInfo()
Holds information about the various types of exception specification.
Extra information about a function prototype.
ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &ESI)