18#include "llvm/ADT/STLExtras.h"
19#include "llvm/IR/Constants.h"
20#include "llvm/IR/Instructions.h"
21#include "llvm/IR/MDBuilder.h"
22#include "llvm/IR/Metadata.h"
25using namespace CodeGen;
43 return cast<ComplexType>(cast<AtomicType>(
type)->getValueType());
48class ComplexExprEmitter
49 :
public StmtVisitor<ComplexExprEmitter, ComplexPairTy> {
54 bool FPHasBeenPromoted;
57 ComplexExprEmitter(
CodeGenFunction &cgf,
bool ir =
false,
bool ii =
false)
58 : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii),
59 FPHasBeenPromoted(
false) {}
65 bool TestAndClearIgnoreReal() {
70 bool TestAndClearIgnoreImag() {
107 llvm_unreachable(
"Stmt can't have complex result type!");
113 Result->getAggregateElement(1U));
114 return Visit(
E->getSubExpr());
118 return Visit(
GE->getResultExpr());
132 return Visit(
E->getSubExpr());
135 ComplexPairTy emitConstant(
const CodeGenFunction::ConstantEmission &Constant,
137 assert(Constant &&
"not a constant");
138 if (Constant.isReference())
139 return EmitLoadOfLValue(Constant.getReferenceLValue(CGF,
E),
142 llvm::Constant *pair = Constant.getValue();
144 pair->getAggregateElement(1U));
150 return emitConstant(Constant,
E);
151 return EmitLoadOfLValue(
E);
154 return EmitLoadOfLValue(
E);
161 if (CodeGenFunction::ConstantEmission Constant =
164 return emitConstant(Constant, ME);
166 return EmitLoadOfLValue(ME);
185 if (
E->changesVolatileQualification())
186 return EmitLoadOfLValue(
E);
187 return EmitCast(
E->getCastKind(),
E->getSubExpr(),
E->
getType());
190 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(
E))
192 if (
E->changesVolatileQualification())
193 return EmitLoadOfLValue(
E);
194 return EmitCast(
E->getCastKind(),
E->getSubExpr(),
E->
getType());
201 bool isInc,
bool isPre) {
206 return VisitPrePostIncDec(
E,
false,
false);
209 return VisitPrePostIncDec(
E,
true,
false);
212 return VisitPrePostIncDec(
E,
false,
true);
215 return VisitPrePostIncDec(
E,
true,
true);
228 return Visit(
E->getSubExpr());
231 CodeGenFunction::CXXDefaultArgExprScope
Scope(CGF, DAE);
235 CodeGenFunction::CXXDefaultInitExprScope
Scope(CGF, DIE);
239 CodeGenFunction::RunCleanupsScope
Scope(CGF);
243 Scope.ForceCleanup({&Vals.first, &Vals.second});
249 llvm::Constant *
Null = llvm::Constant::getNullValue(CGF.
ConvertType(Elem));
255 llvm::Constant *
Null =
256 llvm::Constant::getNullValue(CGF.
ConvertType(Elem));
277 (
const BinOpInfo &));
283 ComplexPairTy EmitAlgebraicDiv(llvm::Value *A, llvm::Value *B, llvm::Value *
C,
285 ComplexPairTy EmitRangeReductionDiv(llvm::Value *A, llvm::Value *B,
286 llvm::Value *
C, llvm::Value *
D);
289 const BinOpInfo &Op);
292 const auto *CurrentBT = cast<BuiltinType>(ElementType);
293 switch (CurrentBT->getKind()) {
294 case BuiltinType::Kind::Float16:
296 case BuiltinType::Kind::Float:
297 case BuiltinType::Kind::BFloat16:
299 case BuiltinType::Kind::Double:
308 QualType HigherElementType = GetHigherPrecisionFPType(ElementType);
309 const llvm::fltSemantics &ElementTypeSemantics =
311 const llvm::fltSemantics &HigherElementTypeSemantics =
320 if (llvm::APFloat::semanticsMaxExponent(ElementTypeSemantics) * 2 + 1 <=
321 llvm::APFloat::semanticsMaxExponent(HigherElementTypeSemantics)) {
322 FPHasBeenPromoted =
true;
326 Diags.
Report(diag::warn_next_larger_fp_type_same_size_than_fp);
332 bool IsDivOpCode =
false) {
334 QualType ElementType = CT->getElementType();
336 bool IsComplexRangePromoted = CGF.
getLangOpts().getComplexRange() ==
337 LangOptions::ComplexRangeKind::CX_Promoted;
338 bool HasNoComplexRangeOverride = !Features.hasComplexRangeOverride();
339 bool HasMatchingComplexRange = Features.hasComplexRangeOverride() &&
340 Features.getComplexRangeOverride() ==
343 if (IsDivOpCode && IsFloatingType && IsComplexRangePromoted &&
344 (HasNoComplexRangeOverride || HasMatchingComplexRange))
345 return HigherPrecisionTypeForComplexArithmetic(ElementType,
355#define HANDLEBINOP(OP) \
356 ComplexPairTy VisitBin##OP(const BinaryOperator *E) { \
357 QualType promotionTy = getPromotionType( \
358 E->getStoredFPFeaturesOrDefault(), E->getType(), \
359 (E->getOpcode() == BinaryOperatorKind::BO_Div) ? true : false); \
360 ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy)); \
361 if (!promotionTy.isNull()) \
362 result = CGF.EmitUnPromotedValue(result, E->getType()); \
373 return Visit(
E->getSemanticForm());
378 return EmitCompoundAssign(
E, &ComplexExprEmitter::EmitBinAdd);
381 return EmitCompoundAssign(
E, &ComplexExprEmitter::EmitBinSub);
384 return EmitCompoundAssign(
E, &ComplexExprEmitter::EmitBinMul);
387 return EmitCompoundAssign(
E, &ComplexExprEmitter::EmitBinDiv);
408 return EmitLoadOfLValue(
E);
418 return Visit(
E->getSelectedExpr());
441 assert(lvalue.
isSimple() &&
"non-simple complex l-value?");
448 llvm::Value *Real =
nullptr, *Imag =
nullptr;
450 if (!IgnoreReal || isVolatile) {
452 Real = Builder.CreateLoad(RealP, isVolatile, SrcPtr.
getName() +
".real");
455 if (!IgnoreImag || isVolatile) {
457 Imag = Builder.CreateLoad(ImagP, isVolatile, SrcPtr.
getName() +
".imag");
489 llvm::Value *
U = llvm::UndefValue::get(EltTy);
496 return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag);
501 if (
E->getCallReturnType(CGF.
getContext())->isReferenceType())
502 return EmitLoadOfLValue(
E);
508 CodeGenFunction::StmtExprEvaluation eval(CGF);
510 assert(RetAlloca.
isValid() &&
"Expected complex return value");
534ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val,
543 return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType()));
549 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
553 case CK_AtomicToNonAtomic:
554 case CK_NonAtomicToAtomic:
556 case CK_LValueToRValue:
557 case CK_UserDefinedConversion:
560 case CK_LValueBitCast: {
566 case CK_LValueToRValueBitCast: {
572 return EmitLoadOfLValue(DestLV, Op->
getExprLoc());
576 case CK_BaseToDerived:
577 case CK_DerivedToBase:
578 case CK_UncheckedDerivedToBase:
581 case CK_ArrayToPointerDecay:
582 case CK_FunctionToPointerDecay:
583 case CK_NullToPointer:
584 case CK_NullToMemberPointer:
585 case CK_BaseToDerivedMemberPointer:
586 case CK_DerivedToBaseMemberPointer:
587 case CK_MemberPointerToBoolean:
588 case CK_ReinterpretMemberPointer:
589 case CK_ConstructorConversion:
590 case CK_IntegralToPointer:
591 case CK_PointerToIntegral:
592 case CK_PointerToBoolean:
595 case CK_IntegralCast:
596 case CK_BooleanToSignedIntegral:
597 case CK_IntegralToBoolean:
598 case CK_IntegralToFloating:
599 case CK_FloatingToIntegral:
600 case CK_FloatingToBoolean:
601 case CK_FloatingCast:
602 case CK_CPointerToObjCPointerCast:
603 case CK_BlockPointerToObjCPointerCast:
604 case CK_AnyPointerToBlockPointerCast:
605 case CK_ObjCObjectLValueCast:
606 case CK_FloatingComplexToReal:
607 case CK_FloatingComplexToBoolean:
608 case CK_IntegralComplexToReal:
609 case CK_IntegralComplexToBoolean:
610 case CK_ARCProduceObject:
611 case CK_ARCConsumeObject:
612 case CK_ARCReclaimReturnedObject:
613 case CK_ARCExtendBlockObject:
614 case CK_CopyAndAutoreleaseBlockObject:
615 case CK_BuiltinFnToFnPtr:
616 case CK_ZeroToOCLOpaqueType:
617 case CK_AddressSpaceConversion:
618 case CK_IntToOCLSampler:
619 case CK_FloatingToFixedPoint:
620 case CK_FixedPointToFloating:
621 case CK_FixedPointCast:
622 case CK_FixedPointToBoolean:
623 case CK_FixedPointToIntegral:
624 case CK_IntegralToFixedPoint:
626 case CK_HLSLVectorTruncation:
627 case CK_HLSLArrayRValue:
628 llvm_unreachable(
"invalid cast kind for complex value");
630 case CK_FloatingRealToComplex:
631 case CK_IntegralRealToComplex: {
632 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op);
637 case CK_FloatingComplexCast:
638 case CK_FloatingComplexToIntegralComplex:
639 case CK_IntegralComplexCast:
640 case CK_IntegralComplexToFloatingComplex: {
641 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op);
642 return EmitComplexToComplexCast(Visit(Op), Op->
getType(), DestTy,
647 llvm_unreachable(
"unknown cast resulting in complex value");
654 ? getPromotionType(
E->getStoredFPFeaturesOrDefault(),
658 if (!promotionTy.
isNull())
665 TestAndClearIgnoreReal();
666 TestAndClearIgnoreImag();
667 if (!PromotionType.
isNull())
669 return Visit(
E->getSubExpr());
676 ? getPromotionType(
E->getStoredFPFeaturesOrDefault(),
680 if (!promotionTy.
isNull())
686 TestAndClearIgnoreReal();
687 TestAndClearIgnoreImag();
689 if (!PromotionType.
isNull())
692 Op = Visit(
E->getSubExpr());
694 llvm::Value *ResR, *ResI;
695 if (Op.first->getType()->isFloatingPointTy()) {
696 ResR = Builder.CreateFNeg(Op.first,
"neg.r");
697 ResI = Builder.CreateFNeg(Op.second,
"neg.i");
699 ResR = Builder.CreateNeg(Op.first,
"neg.r");
700 ResI = Builder.CreateNeg(Op.second,
"neg.i");
706 TestAndClearIgnoreReal();
707 TestAndClearIgnoreImag();
711 if (Op.second->getType()->isFloatingPointTy())
712 ResI = Builder.CreateFNeg(Op.second,
"conj.i");
714 ResI = Builder.CreateNeg(Op.second,
"conj.i");
719ComplexPairTy ComplexExprEmitter::EmitBinAdd(
const BinOpInfo &Op) {
720 llvm::Value *ResR, *ResI;
722 if (Op.LHS.first->getType()->isFloatingPointTy()) {
723 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
724 ResR = Builder.CreateFAdd(Op.LHS.first, Op.RHS.first,
"add.r");
725 if (Op.LHS.second && Op.RHS.second)
726 ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second,
"add.i");
728 ResI = Op.LHS.second ? Op.LHS.second : Op.RHS.second;
729 assert(ResI &&
"Only one operand may be real!");
731 ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first,
"add.r");
732 assert(Op.LHS.second && Op.RHS.second &&
733 "Both operands of integer complex operators must be complex!");
734 ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second,
"add.i");
739ComplexPairTy ComplexExprEmitter::EmitBinSub(
const BinOpInfo &Op) {
740 llvm::Value *ResR, *ResI;
741 if (Op.LHS.first->getType()->isFloatingPointTy()) {
742 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
743 ResR = Builder.CreateFSub(Op.LHS.first, Op.RHS.first,
"sub.r");
744 if (Op.LHS.second && Op.RHS.second)
745 ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second,
"sub.i");
747 ResI = Op.LHS.second ? Op.LHS.second
748 : Builder.CreateFNeg(Op.RHS.second,
"sub.i");
749 assert(ResI &&
"Only one operand may be real!");
751 ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first,
"sub.r");
752 assert(Op.LHS.second && Op.RHS.second &&
753 "Both operands of integer complex operators must be complex!");
754 ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second,
"sub.i");
760ComplexPairTy ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName,
761 const BinOpInfo &Op) {
785 Args, cast<FunctionType>(FQTy.
getTypePtr()),
false);
789 FTy, LibCallName, llvm::AttributeList(),
true);
792 llvm::CallBase *
Call;
801 switch (Ty->getTypeID()) {
803 llvm_unreachable(
"Unsupported floating point type!");
804 case llvm::Type::HalfTyID:
806 case llvm::Type::FloatTyID:
808 case llvm::Type::DoubleTyID:
810 case llvm::Type::PPC_FP128TyID:
812 case llvm::Type::X86_FP80TyID:
814 case llvm::Type::FP128TyID:
821ComplexPairTy ComplexExprEmitter::EmitBinMul(
const BinOpInfo &Op) {
826 if (Op.LHS.first->getType()->isFloatingPointTy()) {
833 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
834 if (Op.LHS.second && Op.RHS.second) {
845 Value *AC = Builder.CreateFMul(Op.LHS.first, Op.RHS.first,
"mul_ac");
846 Value *BD = Builder.CreateFMul(Op.LHS.second, Op.RHS.second,
"mul_bd");
847 Value *AD = Builder.CreateFMul(Op.LHS.first, Op.RHS.second,
"mul_ad");
848 Value *BC = Builder.CreateFMul(Op.LHS.second, Op.RHS.first,
"mul_bc");
852 ResR = Builder.CreateFSub(AC, BD,
"mul_r");
853 ResI = Builder.CreateFAdd(AD, BC,
"mul_i");
862 Value *IsRNaN = Builder.CreateFCmpUNO(ResR, ResR,
"isnan_cmp");
865 llvm::Instruction *Branch = Builder.CreateCondBr(IsRNaN, INaNBB, ContBB);
866 llvm::BasicBlock *OrigBB = Branch->getParent();
869 llvm::MDNode *BrWeight = MDHelper.createUnlikelyBranchWeights();
870 Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight);
874 Value *IsINaN = Builder.CreateFCmpUNO(ResI, ResI,
"isnan_cmp");
876 Branch = Builder.CreateCondBr(IsINaN, LibCallBB, ContBB);
877 Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight);
881 Value *LibCallR, *LibCallI;
882 std::tie(LibCallR, LibCallI) = EmitComplexBinOpLibCall(
884 Builder.CreateBr(ContBB);
889 llvm::PHINode *RealPHI = Builder.CreatePHI(ResR->
getType(), 3,
"real_mul_phi");
890 RealPHI->addIncoming(ResR, OrigBB);
891 RealPHI->addIncoming(ResR, INaNBB);
892 RealPHI->addIncoming(LibCallR, LibCallBB);
893 llvm::PHINode *ImagPHI = Builder.CreatePHI(ResI->
getType(), 3,
"imag_mul_phi");
894 ImagPHI->addIncoming(ResI, OrigBB);
895 ImagPHI->addIncoming(ResI, INaNBB);
896 ImagPHI->addIncoming(LibCallI, LibCallBB);
899 assert((Op.LHS.second || Op.RHS.second) &&
900 "At least one operand must be complex!");
905 ResR = Builder.CreateFMul(Op.LHS.first, Op.RHS.first,
"mul.rl");
908 ? Builder.CreateFMul(Op.LHS.second, Op.RHS.first,
"mul.il")
909 : Builder.CreateFMul(Op.LHS.first, Op.RHS.second,
"mul.ir");
911 assert(Op.LHS.second && Op.RHS.second &&
912 "Both operands of integer complex operators must be complex!");
913 Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first,
"mul.rl");
914 Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second,
"mul.rr");
915 ResR = Builder.CreateSub(ResRl, ResRr,
"mul.r");
917 Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first,
"mul.il");
918 Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second,
"mul.ir");
919 ResI = Builder.CreateAdd(ResIl, ResIr,
"mul.i");
924ComplexPairTy ComplexExprEmitter::EmitAlgebraicDiv(llvm::Value *LHSr,
929 llvm::Value *DSTr, *DSTi;
931 llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr);
932 llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi);
933 llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD);
935 llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr);
936 llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi);
937 llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD);
939 llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr);
940 llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi);
941 llvm::Value *BCmAD = Builder.CreateFSub(BC, AD);
943 DSTr = Builder.CreateFDiv(ACpBD, CCpDD);
944 DSTi = Builder.CreateFDiv(BCmAD, CCpDD);
950 llvm::Function *
Func =
958ComplexPairTy ComplexExprEmitter::EmitRangeReductionDiv(llvm::Value *LHSr,
969 llvm::Value *IsR = Builder.CreateFCmpUGT(FAbsRHSr, FAbsRHSi,
"abs_cmp");
971 llvm::BasicBlock *TrueBB =
973 llvm::BasicBlock *FalseBB =
976 Builder.CreateCondBr(IsR, TrueBB, FalseBB);
984 llvm::Value *DdC = Builder.CreateFDiv(RHSi, RHSr);
986 llvm::Value *RD = Builder.CreateFMul(DdC, RHSi);
987 llvm::Value *CpRD = Builder.CreateFAdd(RHSr, RD);
989 llvm::Value *T3 = Builder.CreateFMul(LHSi, DdC);
990 llvm::Value *T4 = Builder.CreateFAdd(LHSr, T3);
991 llvm::Value *DSTTr = Builder.CreateFDiv(T4, CpRD);
993 llvm::Value *T5 = Builder.CreateFMul(LHSr, DdC);
994 llvm::Value *T6 = Builder.CreateFSub(LHSi, T5);
995 llvm::Value *DSTTi = Builder.CreateFDiv(T6, CpRD);
996 Builder.CreateBr(ContBB);
1004 llvm::Value *CdD = Builder.CreateFDiv(RHSr, RHSi);
1006 llvm::Value *RC = Builder.CreateFMul(CdD, RHSr);
1007 llvm::Value *DpRC = Builder.CreateFAdd(RHSi, RC);
1009 llvm::Value *T7 = Builder.CreateFMul(LHSr, CdD);
1010 llvm::Value *T8 = Builder.CreateFAdd(T7, LHSi);
1011 llvm::Value *DSTFr = Builder.CreateFDiv(T8, DpRC);
1013 llvm::Value *T9 = Builder.CreateFMul(LHSi, CdD);
1014 llvm::Value *T10 = Builder.CreateFSub(T9, LHSr);
1015 llvm::Value *DSTFi = Builder.CreateFDiv(T10, DpRC);
1016 Builder.CreateBr(ContBB);
1020 llvm::PHINode *VALr = Builder.CreatePHI(DSTTr->getType(), 2);
1021 VALr->addIncoming(DSTTr, TrueBB);
1022 VALr->addIncoming(DSTFr, FalseBB);
1023 llvm::PHINode *VALi = Builder.CreatePHI(DSTTi->getType(), 2);
1024 VALi->addIncoming(DSTTi, TrueBB);
1025 VALi->addIncoming(DSTFi, FalseBB);
1031ComplexPairTy ComplexExprEmitter::EmitBinDiv(
const BinOpInfo &Op) {
1032 llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second;
1033 llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second;
1034 llvm::Value *DSTr, *DSTi;
1035 if (LHSr->getType()->isFloatingPointTy()) {
1036 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
1038 assert(LHSi &&
"Can have at most one non-complex operand!");
1040 DSTr = Builder.CreateFDiv(LHSr, RHSr);
1041 DSTi = Builder.CreateFDiv(LHSi, RHSr);
1044 llvm::Value *OrigLHSi = LHSi;
1046 LHSi = llvm::Constant::getNullValue(RHSi->getType());
1049 !FPHasBeenPromoted))
1050 return EmitRangeReductionDiv(LHSr, LHSi, RHSr, RHSi);
1053 return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi);
1062 BinOpInfo LibCallOp = Op;
1065 LibCallOp.LHS.second = llvm::Constant::getNullValue(LHSr->getType());
1067 switch (LHSr->getType()->getTypeID()) {
1069 llvm_unreachable(
"Unsupported floating point type!");
1070 case llvm::Type::HalfTyID:
1071 return EmitComplexBinOpLibCall(
"__divhc3", LibCallOp);
1072 case llvm::Type::FloatTyID:
1073 return EmitComplexBinOpLibCall(
"__divsc3", LibCallOp);
1074 case llvm::Type::DoubleTyID:
1075 return EmitComplexBinOpLibCall(
"__divdc3", LibCallOp);
1076 case llvm::Type::PPC_FP128TyID:
1077 return EmitComplexBinOpLibCall(
"__divtc3", LibCallOp);
1078 case llvm::Type::X86_FP80TyID:
1079 return EmitComplexBinOpLibCall(
"__divxc3", LibCallOp);
1080 case llvm::Type::FP128TyID:
1081 return EmitComplexBinOpLibCall(
"__divtc3", LibCallOp);
1084 return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi);
1087 assert(Op.LHS.second && Op.RHS.second &&
1088 "Both operands of integer complex operators must be complex!");
1090 llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr);
1091 llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi);
1092 llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2);
1094 llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr);
1095 llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi);
1096 llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5);
1098 llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr);
1099 llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi);
1100 llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8);
1103 DSTr = Builder.CreateUDiv(Tmp3, Tmp6);
1104 DSTi = Builder.CreateUDiv(Tmp9, Tmp6);
1106 DSTr = Builder.CreateSDiv(Tmp3, Tmp6);
1107 DSTi = Builder.CreateSDiv(Tmp9, Tmp6);
1116 llvm::Type *ComplexElementTy =
1120 Builder.CreateFPTrunc(result.first, ComplexElementTy,
"unpromotion");
1123 Builder.CreateFPTrunc(result.second, ComplexElementTy,
"unpromotion");
1129 llvm::Type *ComplexElementTy =
1132 result.first =
Builder.CreateFPExt(result.first, ComplexElementTy,
"ext");
1134 result.second =
Builder.CreateFPExt(result.second, ComplexElementTy,
"ext");
1142 if (
auto BO = dyn_cast<BinaryOperator>(
E)) {
1143 switch (BO->getOpcode()) {
1144#define HANDLE_BINOP(OP) \
1146 return EmitBin##OP(EmitBinOps(BO, PromotionType));
1155 }
else if (
auto UO = dyn_cast<UnaryOperator>(
E)) {
1156 switch (UO->getOpcode()) {
1158 return VisitMinus(UO, PromotionType);
1160 return VisitPlus(UO, PromotionType);
1165 auto result = Visit(
const_cast<Expr *
>(
E));
1166 if (!PromotionType.
isNull())
1174 return ComplexExprEmitter(*this).EmitPromoted(
E, DstTy);
1178ComplexExprEmitter::EmitPromotedComplexOperand(
const Expr *
E,
1181 if (!OverallPromotionType.
isNull())
1184 return Visit(
const_cast<Expr *
>(
E));
1186 if (!OverallPromotionType.
isNull()) {
1197ComplexExprEmitter::BinOpInfo
1200 TestAndClearIgnoreReal();
1201 TestAndClearIgnoreImag();
1204 Ops.LHS = EmitPromotedComplexOperand(
E->getLHS(), PromotionType);
1205 Ops.RHS = EmitPromotedComplexOperand(
E->getRHS(), PromotionType);
1206 if (!PromotionType.
isNull())
1207 Ops.Ty = PromotionType;
1215LValue ComplexExprEmitter::
1219 TestAndClearIgnoreReal();
1220 TestAndClearIgnoreImag();
1223 LHSTy = AT->getValueType();
1227 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
1233 PromotionTypeCR = getPromotionType(
E->getStoredFPFeaturesOrDefault(),
1234 E->getComputationResultType());
1235 if (PromotionTypeCR.
isNull())
1236 PromotionTypeCR =
E->getComputationResultType();
1237 OpInfo.Ty = PromotionTypeCR;
1240 QualType PromotionTypeRHS = getPromotionType(
1241 E->getStoredFPFeaturesOrDefault(),
E->getRHS()->
getType());
1245 if (!PromotionTypeRHS.
isNull())
1255 if (!PromotionTypeRHS.
isNull()) {
1261 OpInfo.RHS = Visit(
E->getRHS());
1269 QualType PromotionTypeLHS = getPromotionType(
1270 E->getStoredFPFeaturesOrDefault(),
E->getComputationLHSType());
1273 if (!PromotionTypeLHS.
isNull())
1275 EmitComplexToComplexCast(LHSVal, LHSTy, PromotionTypeLHS,
Loc);
1277 OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty,
Loc);
1284 if (!PromotionTypeLHS.
isNull()) {
1285 PromotedComplexElementTy =
1286 cast<ComplexType>(PromotionTypeLHS)->getElementType();
1290 PromotedComplexElementTy,
Loc);
1298 OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty,
Loc);
1308 EmitComplexToComplexCast(
Result, OpInfo.Ty, LHSTy,
Loc);
1309 EmitStoreOfComplex(ResVal, LHS,
false);
1312 llvm::Value *ResVal =
1326 LValue LV = EmitCompoundAssignLValue(
E,
Func, Val);
1343 "Invalid assignment");
1344 TestAndClearIgnoreReal();
1345 TestAndClearIgnoreImag();
1348 Val = Visit(
E->getRHS());
1354 EmitStoreOfComplex(Val, LHS,
false);
1361 LValue LV = EmitBinAssignLValue(
E, Val);
1376 return Visit(
E->getRHS());
1381 TestAndClearIgnoreReal();
1382 TestAndClearIgnoreImag();
1388 CodeGenFunction::OpaqueValueMapping binding(CGF,
E);
1391 CodeGenFunction::ConditionalEvaluation eval(CGF);
1403 LHSBlock = Builder.GetInsertBlock();
1412 RHSBlock = Builder.GetInsertBlock();
1419 llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), 2,
"cond.r");
1420 RealPN->addIncoming(LHS.first, LHSBlock);
1421 RealPN->addIncoming(RHS.first, RHSBlock);
1424 llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), 2,
"cond.i");
1425 ImagPN->addIncoming(LHS.second, LHSBlock);
1426 ImagPN->addIncoming(RHS.second, RHSBlock);
1432 return Visit(
E->getChosenSubExpr());
1436 bool Ignore = TestAndClearIgnoreReal();
1438 assert (Ignore ==
false &&
"init list ignored");
1439 Ignore = TestAndClearIgnoreImag();
1441 assert (Ignore ==
false &&
"init list ignored");
1443 if (
E->getNumInits() == 2) {
1447 }
else if (
E->getNumInits() == 1) {
1448 return Visit(
E->getInit(0));
1452 assert(
E->getNumInits() == 0 &&
"Unexpected number of inits");
1455 llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy);
1467 llvm::Value *
U = llvm::UndefValue::get(EltTy);
1483 "Invalid complex expression to emit");
1485 return ComplexExprEmitter(*
this, IgnoreReal, IgnoreImag)
1486 .Visit(
const_cast<Expr *
>(
E));
1492 "Invalid complex expression to emit");
1493 ComplexExprEmitter
Emitter(*
this);
1495 Emitter.EmitStoreOfComplex(Val, dest, isInit);
1501 ComplexExprEmitter(*this).EmitStoreOfComplex(
V, dest, isInit);
1507 return ComplexExprEmitter(*this).EmitLoadOfLValue(src, loc);
1511 assert(
E->getOpcode() == BO_Assign);
1513 LValue LVal = ComplexExprEmitter(*this).EmitBinAssignLValue(
E, Val);
1521 const ComplexExprEmitter::BinOpInfo &);
1525 case BO_MulAssign:
return &ComplexExprEmitter::EmitBinMul;
1526 case BO_DivAssign:
return &ComplexExprEmitter::EmitBinDiv;
1527 case BO_SubAssign:
return &ComplexExprEmitter::EmitBinSub;
1528 case BO_AddAssign:
return &ComplexExprEmitter::EmitBinAdd;
1530 llvm_unreachable(
"unexpected complex compound assignment");
1538 return ComplexExprEmitter(*this).EmitCompoundAssignLValue(
E, Op, Val);
1546 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)
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
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 a value-initialized rvalue of type T, which is a non-class type.
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.
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,...
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 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::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.
DiagnosticsEngine & getDiags() const
CodeGenTypes & getTypes()
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys=std::nullopt)
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.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
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 Ret(InterpState &S, CodePtr &PC, APValue &Result)
bool Null(InterpState &S, CodePtr OpPC, const Descriptor *Desc)
bool GE(InterpState &S, CodePtr OpPC)
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)