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");
652 E->hasStoredFPFeatures();
655 ? getPromotionType(
E->getStoredFPFeaturesOrDefault(),
659 if (!promotionTy.
isNull())
666 TestAndClearIgnoreReal();
667 TestAndClearIgnoreImag();
668 if (!PromotionType.
isNull())
670 return Visit(
E->getSubExpr());
677 ? getPromotionType(
E->getStoredFPFeaturesOrDefault(),
681 if (!promotionTy.
isNull())
687 TestAndClearIgnoreReal();
688 TestAndClearIgnoreImag();
690 if (!PromotionType.
isNull())
693 Op = Visit(
E->getSubExpr());
695 llvm::Value *ResR, *ResI;
696 if (Op.first->getType()->isFloatingPointTy()) {
697 ResR = Builder.CreateFNeg(Op.first,
"neg.r");
698 ResI = Builder.CreateFNeg(Op.second,
"neg.i");
700 ResR = Builder.CreateNeg(Op.first,
"neg.r");
701 ResI = Builder.CreateNeg(Op.second,
"neg.i");
707 TestAndClearIgnoreReal();
708 TestAndClearIgnoreImag();
712 if (Op.second->getType()->isFloatingPointTy())
713 ResI = Builder.CreateFNeg(Op.second,
"conj.i");
715 ResI = Builder.CreateNeg(Op.second,
"conj.i");
720ComplexPairTy ComplexExprEmitter::EmitBinAdd(
const BinOpInfo &Op) {
721 llvm::Value *ResR, *ResI;
723 if (Op.LHS.first->getType()->isFloatingPointTy()) {
724 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
725 ResR = Builder.CreateFAdd(Op.LHS.first, Op.RHS.first,
"add.r");
726 if (Op.LHS.second && Op.RHS.second)
727 ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second,
"add.i");
729 ResI = Op.LHS.second ? Op.LHS.second : Op.RHS.second;
730 assert(ResI &&
"Only one operand may be real!");
732 ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first,
"add.r");
733 assert(Op.LHS.second && Op.RHS.second &&
734 "Both operands of integer complex operators must be complex!");
735 ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second,
"add.i");
740ComplexPairTy ComplexExprEmitter::EmitBinSub(
const BinOpInfo &Op) {
741 llvm::Value *ResR, *ResI;
742 if (Op.LHS.first->getType()->isFloatingPointTy()) {
743 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
744 ResR = Builder.CreateFSub(Op.LHS.first, Op.RHS.first,
"sub.r");
745 if (Op.LHS.second && Op.RHS.second)
746 ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second,
"sub.i");
748 ResI = Op.LHS.second ? Op.LHS.second
749 : Builder.CreateFNeg(Op.RHS.second,
"sub.i");
750 assert(ResI &&
"Only one operand may be real!");
752 ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first,
"sub.r");
753 assert(Op.LHS.second && Op.RHS.second &&
754 "Both operands of integer complex operators must be complex!");
755 ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second,
"sub.i");
761ComplexPairTy ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName,
762 const BinOpInfo &Op) {
786 Args, cast<FunctionType>(FQTy.
getTypePtr()),
false);
790 FTy, LibCallName, llvm::AttributeList(),
true);
793 llvm::CallBase *
Call;
802 switch (Ty->getTypeID()) {
804 llvm_unreachable(
"Unsupported floating point type!");
805 case llvm::Type::HalfTyID:
807 case llvm::Type::FloatTyID:
809 case llvm::Type::DoubleTyID:
811 case llvm::Type::PPC_FP128TyID:
813 case llvm::Type::X86_FP80TyID:
815 case llvm::Type::FP128TyID:
822ComplexPairTy ComplexExprEmitter::EmitBinMul(
const BinOpInfo &Op) {
827 if (Op.LHS.first->getType()->isFloatingPointTy()) {
834 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
835 if (Op.LHS.second && Op.RHS.second) {
846 Value *AC = Builder.CreateFMul(Op.LHS.first, Op.RHS.first,
"mul_ac");
847 Value *BD = Builder.CreateFMul(Op.LHS.second, Op.RHS.second,
"mul_bd");
848 Value *AD = Builder.CreateFMul(Op.LHS.first, Op.RHS.second,
"mul_ad");
849 Value *BC = Builder.CreateFMul(Op.LHS.second, Op.RHS.first,
"mul_bc");
853 ResR = Builder.CreateFSub(AC, BD,
"mul_r");
854 ResI = Builder.CreateFAdd(AD, BC,
"mul_i");
863 Value *IsRNaN = Builder.CreateFCmpUNO(ResR, ResR,
"isnan_cmp");
866 llvm::Instruction *Branch = Builder.CreateCondBr(IsRNaN, INaNBB, ContBB);
867 llvm::BasicBlock *OrigBB = Branch->getParent();
870 llvm::MDNode *BrWeight = MDHelper.createUnlikelyBranchWeights();
871 Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight);
875 Value *IsINaN = Builder.CreateFCmpUNO(ResI, ResI,
"isnan_cmp");
877 Branch = Builder.CreateCondBr(IsINaN, LibCallBB, ContBB);
878 Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight);
882 Value *LibCallR, *LibCallI;
883 std::tie(LibCallR, LibCallI) = EmitComplexBinOpLibCall(
885 Builder.CreateBr(ContBB);
890 llvm::PHINode *RealPHI = Builder.CreatePHI(ResR->
getType(), 3,
"real_mul_phi");
891 RealPHI->addIncoming(ResR, OrigBB);
892 RealPHI->addIncoming(ResR, INaNBB);
893 RealPHI->addIncoming(LibCallR, LibCallBB);
894 llvm::PHINode *ImagPHI = Builder.CreatePHI(ResI->
getType(), 3,
"imag_mul_phi");
895 ImagPHI->addIncoming(ResI, OrigBB);
896 ImagPHI->addIncoming(ResI, INaNBB);
897 ImagPHI->addIncoming(LibCallI, LibCallBB);
900 assert((Op.LHS.second || Op.RHS.second) &&
901 "At least one operand must be complex!");
906 ResR = Builder.CreateFMul(Op.LHS.first, Op.RHS.first,
"mul.rl");
909 ? Builder.CreateFMul(Op.LHS.second, Op.RHS.first,
"mul.il")
910 : Builder.CreateFMul(Op.LHS.first, Op.RHS.second,
"mul.ir");
912 assert(Op.LHS.second && Op.RHS.second &&
913 "Both operands of integer complex operators must be complex!");
914 Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first,
"mul.rl");
915 Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second,
"mul.rr");
916 ResR = Builder.CreateSub(ResRl, ResRr,
"mul.r");
918 Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first,
"mul.il");
919 Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second,
"mul.ir");
920 ResI = Builder.CreateAdd(ResIl, ResIr,
"mul.i");
925ComplexPairTy ComplexExprEmitter::EmitAlgebraicDiv(llvm::Value *LHSr,
930 llvm::Value *DSTr, *DSTi;
932 llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr);
933 llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi);
934 llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD);
936 llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr);
937 llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi);
938 llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD);
940 llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr);
941 llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi);
942 llvm::Value *BCmAD = Builder.CreateFSub(BC, AD);
944 DSTr = Builder.CreateFDiv(ACpBD, CCpDD);
945 DSTi = Builder.CreateFDiv(BCmAD, CCpDD);
951 llvm::Function *
Func =
959ComplexPairTy ComplexExprEmitter::EmitRangeReductionDiv(llvm::Value *LHSr,
970 llvm::Value *IsR = Builder.CreateFCmpUGT(FAbsRHSr, FAbsRHSi,
"abs_cmp");
972 llvm::BasicBlock *TrueBB =
974 llvm::BasicBlock *FalseBB =
977 Builder.CreateCondBr(IsR, TrueBB, FalseBB);
985 llvm::Value *DdC = Builder.CreateFDiv(RHSi, RHSr);
987 llvm::Value *RD = Builder.CreateFMul(DdC, RHSi);
988 llvm::Value *CpRD = Builder.CreateFAdd(RHSr, RD);
990 llvm::Value *T3 = Builder.CreateFMul(LHSi, DdC);
991 llvm::Value *T4 = Builder.CreateFAdd(LHSr, T3);
992 llvm::Value *DSTTr = Builder.CreateFDiv(T4, CpRD);
994 llvm::Value *T5 = Builder.CreateFMul(LHSr, DdC);
995 llvm::Value *T6 = Builder.CreateFSub(LHSi, T5);
996 llvm::Value *DSTTi = Builder.CreateFDiv(T6, CpRD);
997 Builder.CreateBr(ContBB);
1005 llvm::Value *CdD = Builder.CreateFDiv(RHSr, RHSi);
1007 llvm::Value *RC = Builder.CreateFMul(CdD, RHSr);
1008 llvm::Value *DpRC = Builder.CreateFAdd(RHSi, RC);
1010 llvm::Value *T7 = Builder.CreateFMul(LHSr, CdD);
1011 llvm::Value *T8 = Builder.CreateFAdd(T7, LHSi);
1012 llvm::Value *DSTFr = Builder.CreateFDiv(T8, DpRC);
1014 llvm::Value *T9 = Builder.CreateFMul(LHSi, CdD);
1015 llvm::Value *T10 = Builder.CreateFSub(T9, LHSr);
1016 llvm::Value *DSTFi = Builder.CreateFDiv(T10, DpRC);
1017 Builder.CreateBr(ContBB);
1021 llvm::PHINode *VALr = Builder.CreatePHI(DSTTr->getType(), 2);
1022 VALr->addIncoming(DSTTr, TrueBB);
1023 VALr->addIncoming(DSTFr, FalseBB);
1024 llvm::PHINode *VALi = Builder.CreatePHI(DSTTi->getType(), 2);
1025 VALi->addIncoming(DSTTi, TrueBB);
1026 VALi->addIncoming(DSTFi, FalseBB);
1032ComplexPairTy ComplexExprEmitter::EmitBinDiv(
const BinOpInfo &Op) {
1033 llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second;
1034 llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second;
1035 llvm::Value *DSTr, *DSTi;
1036 if (LHSr->getType()->isFloatingPointTy()) {
1037 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
1039 assert(LHSi &&
"Can have at most one non-complex operand!");
1041 DSTr = Builder.CreateFDiv(LHSr, RHSr);
1042 DSTi = Builder.CreateFDiv(LHSi, RHSr);
1045 llvm::Value *OrigLHSi = LHSi;
1047 LHSi = llvm::Constant::getNullValue(RHSi->getType());
1050 !FPHasBeenPromoted))
1051 return EmitRangeReductionDiv(LHSr, LHSi, RHSr, RHSi);
1054 return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi);
1063 BinOpInfo LibCallOp = Op;
1066 LibCallOp.LHS.second = llvm::Constant::getNullValue(LHSr->getType());
1068 switch (LHSr->getType()->getTypeID()) {
1070 llvm_unreachable(
"Unsupported floating point type!");
1071 case llvm::Type::HalfTyID:
1072 return EmitComplexBinOpLibCall(
"__divhc3", LibCallOp);
1073 case llvm::Type::FloatTyID:
1074 return EmitComplexBinOpLibCall(
"__divsc3", LibCallOp);
1075 case llvm::Type::DoubleTyID:
1076 return EmitComplexBinOpLibCall(
"__divdc3", LibCallOp);
1077 case llvm::Type::PPC_FP128TyID:
1078 return EmitComplexBinOpLibCall(
"__divtc3", LibCallOp);
1079 case llvm::Type::X86_FP80TyID:
1080 return EmitComplexBinOpLibCall(
"__divxc3", LibCallOp);
1081 case llvm::Type::FP128TyID:
1082 return EmitComplexBinOpLibCall(
"__divtc3", LibCallOp);
1085 return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi);
1088 assert(Op.LHS.second && Op.RHS.second &&
1089 "Both operands of integer complex operators must be complex!");
1091 llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr);
1092 llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi);
1093 llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2);
1095 llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr);
1096 llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi);
1097 llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5);
1099 llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr);
1100 llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi);
1101 llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8);
1104 DSTr = Builder.CreateUDiv(Tmp3, Tmp6);
1105 DSTi = Builder.CreateUDiv(Tmp9, Tmp6);
1107 DSTr = Builder.CreateSDiv(Tmp3, Tmp6);
1108 DSTi = Builder.CreateSDiv(Tmp9, Tmp6);
1117 llvm::Type *ComplexElementTy =
1121 Builder.CreateFPTrunc(result.first, ComplexElementTy,
"unpromotion");
1124 Builder.CreateFPTrunc(result.second, ComplexElementTy,
"unpromotion");
1130 llvm::Type *ComplexElementTy =
1133 result.first =
Builder.CreateFPExt(result.first, ComplexElementTy,
"ext");
1135 result.second =
Builder.CreateFPExt(result.second, ComplexElementTy,
"ext");
1143 if (
auto BO = dyn_cast<BinaryOperator>(
E)) {
1144 switch (BO->getOpcode()) {
1145#define HANDLE_BINOP(OP) \
1147 return EmitBin##OP(EmitBinOps(BO, PromotionType));
1156 }
else if (
auto UO = dyn_cast<UnaryOperator>(
E)) {
1157 switch (UO->getOpcode()) {
1159 return VisitMinus(UO, PromotionType);
1161 return VisitPlus(UO, PromotionType);
1166 auto result = Visit(
const_cast<Expr *
>(
E));
1167 if (!PromotionType.
isNull())
1175 return ComplexExprEmitter(*this).EmitPromoted(
E, DstTy);
1179ComplexExprEmitter::EmitPromotedComplexOperand(
const Expr *
E,
1182 if (!OverallPromotionType.
isNull())
1185 return Visit(
const_cast<Expr *
>(
E));
1187 if (!OverallPromotionType.
isNull()) {
1198ComplexExprEmitter::BinOpInfo
1201 TestAndClearIgnoreReal();
1202 TestAndClearIgnoreImag();
1205 Ops.LHS = EmitPromotedComplexOperand(
E->getLHS(), PromotionType);
1206 Ops.RHS = EmitPromotedComplexOperand(
E->getRHS(), PromotionType);
1207 if (!PromotionType.
isNull())
1208 Ops.Ty = PromotionType;
1216LValue ComplexExprEmitter::
1220 TestAndClearIgnoreReal();
1221 TestAndClearIgnoreImag();
1224 LHSTy = AT->getValueType();
1228 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
1234 PromotionTypeCR = getPromotionType(
E->getStoredFPFeaturesOrDefault(),
1235 E->getComputationResultType());
1236 if (PromotionTypeCR.
isNull())
1237 PromotionTypeCR =
E->getComputationResultType();
1238 OpInfo.Ty = PromotionTypeCR;
1241 QualType PromotionTypeRHS = getPromotionType(
1242 E->getStoredFPFeaturesOrDefault(),
E->getRHS()->
getType());
1246 if (!PromotionTypeRHS.
isNull())
1256 if (!PromotionTypeRHS.
isNull()) {
1262 OpInfo.RHS = Visit(
E->getRHS());
1270 QualType PromotionTypeLHS = getPromotionType(
1271 E->getStoredFPFeaturesOrDefault(),
E->getComputationLHSType());
1274 if (!PromotionTypeLHS.
isNull())
1276 EmitComplexToComplexCast(LHSVal, LHSTy, PromotionTypeLHS,
Loc);
1278 OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty,
Loc);
1285 if (!PromotionTypeLHS.
isNull()) {
1286 PromotedComplexElementTy =
1287 cast<ComplexType>(PromotionTypeLHS)->getElementType();
1291 PromotedComplexElementTy,
Loc);
1299 OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty,
Loc);
1309 EmitComplexToComplexCast(
Result, OpInfo.Ty, LHSTy,
Loc);
1310 EmitStoreOfComplex(ResVal, LHS,
false);
1313 llvm::Value *ResVal =
1327 LValue LV = EmitCompoundAssignLValue(
E,
Func, Val);
1344 "Invalid assignment");
1345 TestAndClearIgnoreReal();
1346 TestAndClearIgnoreImag();
1349 Val = Visit(
E->getRHS());
1355 EmitStoreOfComplex(Val, LHS,
false);
1362 LValue LV = EmitBinAssignLValue(
E, Val);
1377 return Visit(
E->getRHS());
1382 TestAndClearIgnoreReal();
1383 TestAndClearIgnoreImag();
1389 CodeGenFunction::OpaqueValueMapping binding(CGF,
E);
1392 CodeGenFunction::ConditionalEvaluation eval(CGF);
1404 LHSBlock = Builder.GetInsertBlock();
1413 RHSBlock = Builder.GetInsertBlock();
1420 llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), 2,
"cond.r");
1421 RealPN->addIncoming(LHS.first, LHSBlock);
1422 RealPN->addIncoming(RHS.first, RHSBlock);
1425 llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), 2,
"cond.i");
1426 ImagPN->addIncoming(LHS.second, LHSBlock);
1427 ImagPN->addIncoming(RHS.second, RHSBlock);
1433 return Visit(
E->getChosenSubExpr());
1437 bool Ignore = TestAndClearIgnoreReal();
1439 assert (Ignore ==
false &&
"init list ignored");
1440 Ignore = TestAndClearIgnoreImag();
1442 assert (Ignore ==
false &&
"init list ignored");
1444 if (
E->getNumInits() == 2) {
1448 }
else if (
E->getNumInits() == 1) {
1449 return Visit(
E->getInit(0));
1453 assert(
E->getNumInits() == 0 &&
"Unexpected number of inits");
1456 llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy);
1468 llvm::Value *
U = llvm::UndefValue::get(EltTy);
1484 "Invalid complex expression to emit");
1486 return ComplexExprEmitter(*
this, IgnoreReal, IgnoreImag)
1487 .Visit(
const_cast<Expr *
>(
E));
1493 "Invalid complex expression to emit");
1494 ComplexExprEmitter
Emitter(*
this);
1496 Emitter.EmitStoreOfComplex(Val, dest, isInit);
1502 ComplexExprEmitter(*this).EmitStoreOfComplex(
V, dest, isInit);
1508 return ComplexExprEmitter(*this).EmitLoadOfLValue(src, loc);
1512 assert(
E->getOpcode() == BO_Assign);
1514 LValue LVal = ComplexExprEmitter(*this).EmitBinAssignLValue(
E, Val);
1522 const ComplexExprEmitter::BinOpInfo &);
1526 case BO_MulAssign:
return &ComplexExprEmitter::EmitBinMul;
1527 case BO_DivAssign:
return &ComplexExprEmitter::EmitBinDiv;
1528 case BO_SubAssign:
return &ComplexExprEmitter::EmitBinSub;
1529 case BO_AddAssign:
return &ComplexExprEmitter::EmitBinAdd;
1531 llvm_unreachable(
"unexpected complex compound assignment");
1539 return ComplexExprEmitter(*this).EmitCompoundAssignLValue(
E, Op, Val);
1547 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)