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> {
56 : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii) {
64 bool TestAndClearIgnoreReal() {
69 bool TestAndClearIgnoreImag() {
106 llvm_unreachable(
"Stmt can't have complex result type!");
110 if (llvm::Constant *Result =
ConstantEmitter(CGF).tryEmitConstantExpr(E))
112 Result->getAggregateElement(1U));
117 return Visit(
GE->getResultExpr());
134 ComplexPairTy emitConstant(
const CodeGenFunction::ConstantEmission &Constant,
136 assert(Constant &&
"not a constant");
137 if (Constant.isReference())
138 return EmitLoadOfLValue(Constant.getReferenceLValue(CGF, E),
141 llvm::Constant *pair = Constant.getValue();
143 pair->getAggregateElement(1U));
149 return emitConstant(Constant, E);
150 return EmitLoadOfLValue(E);
153 return EmitLoadOfLValue(E);
160 if (CodeGenFunction::ConstantEmission Constant =
163 return emitConstant(Constant, ME);
165 return EmitLoadOfLValue(ME);
185 return EmitLoadOfLValue(E);
189 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
192 return EmitLoadOfLValue(E);
200 bool isInc,
bool isPre) {
205 return VisitPrePostIncDec(E,
false,
false);
208 return VisitPrePostIncDec(E,
true,
false);
211 return VisitPrePostIncDec(E,
false,
true);
214 return VisitPrePostIncDec(E,
true,
true);
230 CodeGenFunction::CXXDefaultArgExprScope
Scope(CGF, DAE);
234 CodeGenFunction::CXXDefaultInitExprScope
Scope(CGF, DIE);
238 CodeGenFunction::RunCleanupsScope
Scope(CGF);
242 Scope.ForceCleanup({&Vals.first, &Vals.second});
248 llvm::Constant *
Null = llvm::Constant::getNullValue(CGF.
ConvertType(Elem));
254 llvm::Constant *
Null =
255 llvm::Constant::getNullValue(CGF.
ConvertType(Elem));
276 (
const BinOpInfo &));
282 ComplexPairTy EmitAlgebraicDiv(llvm::Value *A, llvm::Value *B, llvm::Value *
C,
284 ComplexPairTy EmitRangeReductionDiv(llvm::Value *A, llvm::Value *B,
285 llvm::Value *
C, llvm::Value *D);
288 const BinOpInfo &Op);
292 QualType ElementType = CT->getElementType();
301#define HANDLEBINOP(OP) \
302 ComplexPairTy VisitBin##OP(const BinaryOperator *E) { \
303 QualType promotionTy = getPromotionType(E->getType()); \
304 ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy)); \
305 if (!promotionTy.isNull()) \
307 CGF.EmitUnPromotedValue(result, E->getType()); \
323 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd);
326 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub);
329 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul);
332 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv);
353 return EmitLoadOfLValue(E);
386 assert(lvalue.
isSimple() &&
"non-simple complex l-value?");
393 llvm::Value *Real =
nullptr, *Imag =
nullptr;
395 if (!IgnoreReal || isVolatile) {
397 Real = Builder.CreateLoad(RealP, isVolatile, SrcPtr.
getName() +
".real");
400 if (!IgnoreImag || isVolatile) {
402 Imag = Builder.CreateLoad(ImagP, isVolatile, SrcPtr.
getName() +
".imag");
434 llvm::Value *
U = llvm::UndefValue::get(EltTy);
441 return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag);
447 return EmitLoadOfLValue(E);
453 CodeGenFunction::StmtExprEvaluation eval(CGF);
455 assert(RetAlloca.
isValid() &&
"Expected complex return value");
479ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val,
488 return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType()));
494 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
498 case CK_AtomicToNonAtomic:
499 case CK_NonAtomicToAtomic:
501 case CK_LValueToRValue:
502 case CK_UserDefinedConversion:
505 case CK_LValueBitCast: {
511 case CK_LValueToRValueBitCast: {
517 return EmitLoadOfLValue(DestLV, Op->
getExprLoc());
521 case CK_BaseToDerived:
522 case CK_DerivedToBase:
523 case CK_UncheckedDerivedToBase:
526 case CK_ArrayToPointerDecay:
527 case CK_FunctionToPointerDecay:
528 case CK_NullToPointer:
529 case CK_NullToMemberPointer:
530 case CK_BaseToDerivedMemberPointer:
531 case CK_DerivedToBaseMemberPointer:
532 case CK_MemberPointerToBoolean:
533 case CK_ReinterpretMemberPointer:
534 case CK_ConstructorConversion:
535 case CK_IntegralToPointer:
536 case CK_PointerToIntegral:
537 case CK_PointerToBoolean:
540 case CK_IntegralCast:
541 case CK_BooleanToSignedIntegral:
542 case CK_IntegralToBoolean:
543 case CK_IntegralToFloating:
544 case CK_FloatingToIntegral:
545 case CK_FloatingToBoolean:
546 case CK_FloatingCast:
547 case CK_CPointerToObjCPointerCast:
548 case CK_BlockPointerToObjCPointerCast:
549 case CK_AnyPointerToBlockPointerCast:
550 case CK_ObjCObjectLValueCast:
551 case CK_FloatingComplexToReal:
552 case CK_FloatingComplexToBoolean:
553 case CK_IntegralComplexToReal:
554 case CK_IntegralComplexToBoolean:
555 case CK_ARCProduceObject:
556 case CK_ARCConsumeObject:
557 case CK_ARCReclaimReturnedObject:
558 case CK_ARCExtendBlockObject:
559 case CK_CopyAndAutoreleaseBlockObject:
560 case CK_BuiltinFnToFnPtr:
561 case CK_ZeroToOCLOpaqueType:
562 case CK_AddressSpaceConversion:
563 case CK_IntToOCLSampler:
564 case CK_FloatingToFixedPoint:
565 case CK_FixedPointToFloating:
566 case CK_FixedPointCast:
567 case CK_FixedPointToBoolean:
568 case CK_FixedPointToIntegral:
569 case CK_IntegralToFixedPoint:
571 case CK_HLSLVectorTruncation:
572 llvm_unreachable(
"invalid cast kind for complex value");
574 case CK_FloatingRealToComplex:
575 case CK_IntegralRealToComplex: {
576 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op);
581 case CK_FloatingComplexCast:
582 case CK_FloatingComplexToIntegralComplex:
583 case CK_IntegralComplexCast:
584 case CK_IntegralComplexToFloatingComplex: {
585 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op);
586 return EmitComplexToComplexCast(Visit(Op), Op->
getType(), DestTy,
591 llvm_unreachable(
"unknown cast resulting in complex value");
600 if (!promotionTy.
isNull())
607 TestAndClearIgnoreReal();
608 TestAndClearIgnoreImag();
609 if (!PromotionType.
isNull())
620 if (!promotionTy.
isNull())
626 TestAndClearIgnoreReal();
627 TestAndClearIgnoreImag();
629 if (!PromotionType.
isNull())
634 llvm::Value *ResR, *ResI;
635 if (Op.first->getType()->isFloatingPointTy()) {
636 ResR = Builder.CreateFNeg(Op.first,
"neg.r");
637 ResI = Builder.CreateFNeg(Op.second,
"neg.i");
639 ResR = Builder.CreateNeg(Op.first,
"neg.r");
640 ResI = Builder.CreateNeg(Op.second,
"neg.i");
646 TestAndClearIgnoreReal();
647 TestAndClearIgnoreImag();
651 if (Op.second->getType()->isFloatingPointTy())
652 ResI = Builder.CreateFNeg(Op.second,
"conj.i");
654 ResI = Builder.CreateNeg(Op.second,
"conj.i");
659ComplexPairTy ComplexExprEmitter::EmitBinAdd(
const BinOpInfo &Op) {
660 llvm::Value *ResR, *ResI;
662 if (Op.LHS.first->getType()->isFloatingPointTy()) {
663 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
664 ResR = Builder.CreateFAdd(Op.LHS.first, Op.RHS.first,
"add.r");
665 if (Op.LHS.second && Op.RHS.second)
666 ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second,
"add.i");
668 ResI = Op.LHS.second ? Op.LHS.second : Op.RHS.second;
669 assert(ResI &&
"Only one operand may be real!");
671 ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first,
"add.r");
672 assert(Op.LHS.second && Op.RHS.second &&
673 "Both operands of integer complex operators must be complex!");
674 ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second,
"add.i");
679ComplexPairTy ComplexExprEmitter::EmitBinSub(
const BinOpInfo &Op) {
680 llvm::Value *ResR, *ResI;
681 if (Op.LHS.first->getType()->isFloatingPointTy()) {
682 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
683 ResR = Builder.CreateFSub(Op.LHS.first, Op.RHS.first,
"sub.r");
684 if (Op.LHS.second && Op.RHS.second)
685 ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second,
"sub.i");
687 ResI = Op.LHS.second ? Op.LHS.second
688 : Builder.CreateFNeg(Op.RHS.second,
"sub.i");
689 assert(ResI &&
"Only one operand may be real!");
691 ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first,
"sub.r");
692 assert(Op.LHS.second && Op.RHS.second &&
693 "Both operands of integer complex operators must be complex!");
694 ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second,
"sub.i");
700ComplexPairTy ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName,
701 const BinOpInfo &Op) {
725 Args, cast<FunctionType>(FQTy.
getTypePtr()),
false);
729 FTy, LibCallName, llvm::AttributeList(),
true);
732 llvm::CallBase *
Call;
741 switch (Ty->getTypeID()) {
743 llvm_unreachable(
"Unsupported floating point type!");
744 case llvm::Type::HalfTyID:
746 case llvm::Type::FloatTyID:
748 case llvm::Type::DoubleTyID:
750 case llvm::Type::PPC_FP128TyID:
752 case llvm::Type::X86_FP80TyID:
754 case llvm::Type::FP128TyID:
761ComplexPairTy ComplexExprEmitter::EmitBinMul(
const BinOpInfo &Op) {
766 if (Op.LHS.first->getType()->isFloatingPointTy()) {
775 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
776 if (Op.LHS.second && Op.RHS.second) {
787 Value *AC = Builder.CreateFMul(Op.LHS.first, Op.RHS.first,
"mul_ac");
788 Value *BD = Builder.CreateFMul(Op.LHS.second, Op.RHS.second,
"mul_bd");
789 Value *AD = Builder.CreateFMul(Op.LHS.first, Op.RHS.second,
"mul_ad");
790 Value *BC = Builder.CreateFMul(Op.LHS.second, Op.RHS.first,
"mul_bc");
794 ResR = Builder.CreateFSub(AC, BD,
"mul_r");
795 ResI = Builder.CreateFAdd(AD, BC,
"mul_i");
803 Value *IsRNaN = Builder.CreateFCmpUNO(ResR, ResR,
"isnan_cmp");
806 llvm::Instruction *Branch = Builder.CreateCondBr(IsRNaN, INaNBB, ContBB);
807 llvm::BasicBlock *OrigBB = Branch->getParent();
811 llvm::MDNode *BrWeight = MDHelper.createBranchWeights(1, (1U << 20) - 1);
812 Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight);
816 Value *IsINaN = Builder.CreateFCmpUNO(ResI, ResI,
"isnan_cmp");
818 Branch = Builder.CreateCondBr(IsINaN, LibCallBB, ContBB);
819 Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight);
823 Value *LibCallR, *LibCallI;
824 std::tie(LibCallR, LibCallI) = EmitComplexBinOpLibCall(
826 Builder.CreateBr(ContBB);
831 llvm::PHINode *RealPHI = Builder.CreatePHI(ResR->
getType(), 3,
"real_mul_phi");
832 RealPHI->addIncoming(ResR, OrigBB);
833 RealPHI->addIncoming(ResR, INaNBB);
834 RealPHI->addIncoming(LibCallR, LibCallBB);
835 llvm::PHINode *ImagPHI = Builder.CreatePHI(ResI->
getType(), 3,
"imag_mul_phi");
836 ImagPHI->addIncoming(ResI, OrigBB);
837 ImagPHI->addIncoming(ResI, INaNBB);
838 ImagPHI->addIncoming(LibCallI, LibCallBB);
841 assert((Op.LHS.second || Op.RHS.second) &&
842 "At least one operand must be complex!");
847 ResR = Builder.CreateFMul(Op.LHS.first, Op.RHS.first,
"mul.rl");
850 ? Builder.CreateFMul(Op.LHS.second, Op.RHS.first,
"mul.il")
851 : Builder.CreateFMul(Op.LHS.first, Op.RHS.second,
"mul.ir");
853 assert(Op.LHS.second && Op.RHS.second &&
854 "Both operands of integer complex operators must be complex!");
855 Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first,
"mul.rl");
856 Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second,
"mul.rr");
857 ResR = Builder.CreateSub(ResRl, ResRr,
"mul.r");
859 Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first,
"mul.il");
860 Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second,
"mul.ir");
861 ResI = Builder.CreateAdd(ResIl, ResIr,
"mul.i");
866ComplexPairTy ComplexExprEmitter::EmitAlgebraicDiv(llvm::Value *LHSr,
871 llvm::Value *DSTr, *DSTi;
873 llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr);
874 llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi);
875 llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD);
877 llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr);
878 llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi);
879 llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD);
881 llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr);
882 llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi);
883 llvm::Value *BCmAD = Builder.CreateFSub(BC, AD);
885 DSTr = Builder.CreateFDiv(ACpBD, CCpDD);
886 DSTi = Builder.CreateFDiv(BCmAD, CCpDD);
892 llvm::Function *
Func =
900ComplexPairTy ComplexExprEmitter::EmitRangeReductionDiv(llvm::Value *LHSr,
911 llvm::Value *IsR = Builder.CreateFCmpUGT(FAbsRHSr, FAbsRHSi,
"abs_cmp");
913 llvm::BasicBlock *TrueBB =
915 llvm::BasicBlock *FalseBB =
918 Builder.CreateCondBr(IsR, TrueBB, FalseBB);
926 llvm::Value *DdC = Builder.CreateFDiv(RHSi, RHSr);
928 llvm::Value *RD = Builder.CreateFMul(DdC, RHSi);
929 llvm::Value *CpRD = Builder.CreateFAdd(RHSr, RD);
931 llvm::Value *T3 = Builder.CreateFMul(LHSi, DdC);
932 llvm::Value *T4 = Builder.CreateFAdd(LHSr, T3);
933 llvm::Value *DSTTr = Builder.CreateFDiv(T4, CpRD);
935 llvm::Value *T5 = Builder.CreateFMul(LHSr, DdC);
936 llvm::Value *T6 = Builder.CreateFSub(LHSi, T5);
937 llvm::Value *DSTTi = Builder.CreateFDiv(T6, CpRD);
938 Builder.CreateBr(ContBB);
946 llvm::Value *CdD = Builder.CreateFDiv(RHSr, RHSi);
948 llvm::Value *RC = Builder.CreateFMul(CdD, RHSr);
949 llvm::Value *DpRC = Builder.CreateFAdd(RHSi, RC);
951 llvm::Value *T7 = Builder.CreateFMul(LHSr, CdD);
952 llvm::Value *T8 = Builder.CreateFAdd(T7, LHSi);
953 llvm::Value *DSTFr = Builder.CreateFDiv(T8, DpRC);
955 llvm::Value *T9 = Builder.CreateFMul(LHSi, CdD);
956 llvm::Value *T10 = Builder.CreateFSub(T9, LHSr);
957 llvm::Value *DSTFi = Builder.CreateFDiv(T10, DpRC);
958 Builder.CreateBr(ContBB);
962 llvm::PHINode *VALr = Builder.CreatePHI(DSTTr->getType(), 2);
963 VALr->addIncoming(DSTTr, TrueBB);
964 VALr->addIncoming(DSTFr, FalseBB);
965 llvm::PHINode *VALi = Builder.CreatePHI(DSTTi->getType(), 2);
966 VALi->addIncoming(DSTTi, TrueBB);
967 VALi->addIncoming(DSTFi, FalseBB);
973ComplexPairTy ComplexExprEmitter::EmitBinDiv(
const BinOpInfo &Op) {
974 llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second;
975 llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second;
976 llvm::Value *DSTr, *DSTi;
977 if (LHSr->getType()->isFloatingPointTy()) {
978 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
980 assert(LHSi &&
"Can have at most one non-complex operand!");
982 DSTr = Builder.CreateFDiv(LHSr, RHSr);
983 DSTi = Builder.CreateFDiv(LHSi, RHSr);
986 llvm::Value *OrigLHSi = LHSi;
988 LHSi = llvm::Constant::getNullValue(RHSi->getType());
990 return EmitRangeReductionDiv(LHSr, LHSi, RHSr, RHSi);
992 return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi);
1005 BinOpInfo LibCallOp = Op;
1008 LibCallOp.LHS.second = llvm::Constant::getNullValue(LHSr->getType());
1010 switch (LHSr->getType()->getTypeID()) {
1012 llvm_unreachable(
"Unsupported floating point type!");
1013 case llvm::Type::HalfTyID:
1014 return EmitComplexBinOpLibCall(
"__divhc3", LibCallOp);
1015 case llvm::Type::FloatTyID:
1016 return EmitComplexBinOpLibCall(
"__divsc3", LibCallOp);
1017 case llvm::Type::DoubleTyID:
1018 return EmitComplexBinOpLibCall(
"__divdc3", LibCallOp);
1019 case llvm::Type::PPC_FP128TyID:
1020 return EmitComplexBinOpLibCall(
"__divtc3", LibCallOp);
1021 case llvm::Type::X86_FP80TyID:
1022 return EmitComplexBinOpLibCall(
"__divxc3", LibCallOp);
1023 case llvm::Type::FP128TyID:
1024 return EmitComplexBinOpLibCall(
"__divtc3", LibCallOp);
1027 return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi);
1030 assert(Op.LHS.second && Op.RHS.second &&
1031 "Both operands of integer complex operators must be complex!");
1033 llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr);
1034 llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi);
1035 llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2);
1037 llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr);
1038 llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi);
1039 llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5);
1041 llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr);
1042 llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi);
1043 llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8);
1046 DSTr = Builder.CreateUDiv(Tmp3, Tmp6);
1047 DSTi = Builder.CreateUDiv(Tmp9, Tmp6);
1049 DSTr = Builder.CreateSDiv(Tmp3, Tmp6);
1050 DSTi = Builder.CreateSDiv(Tmp9, Tmp6);
1059 llvm::Type *ComplexElementTy =
1063 Builder.CreateFPTrunc(result.first, ComplexElementTy,
"unpromotion");
1066 Builder.CreateFPTrunc(result.second, ComplexElementTy,
"unpromotion");
1072 llvm::Type *ComplexElementTy =
1075 result.first =
Builder.CreateFPExt(result.first, ComplexElementTy,
"ext");
1077 result.second =
Builder.CreateFPExt(result.second, ComplexElementTy,
"ext");
1085 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
1086 switch (BO->getOpcode()) {
1087#define HANDLE_BINOP(OP) \
1089 return EmitBin##OP(EmitBinOps(BO, PromotionType));
1098 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
1099 switch (UO->getOpcode()) {
1101 return VisitMinus(UO, PromotionType);
1103 return VisitPlus(UO, PromotionType);
1108 auto result = Visit(
const_cast<Expr *
>(E));
1109 if (!PromotionType.
isNull())
1117 return ComplexExprEmitter(*this).EmitPromoted(E, DstTy);
1121ComplexExprEmitter::EmitPromotedComplexOperand(
const Expr *E,
1124 if (!OverallPromotionType.
isNull())
1127 return Visit(
const_cast<Expr *
>(E));
1129 if (!OverallPromotionType.
isNull()) {
1140ComplexExprEmitter::BinOpInfo
1143 TestAndClearIgnoreReal();
1144 TestAndClearIgnoreImag();
1147 Ops.LHS = EmitPromotedComplexOperand(E->
getLHS(), PromotionType);
1148 Ops.RHS = EmitPromotedComplexOperand(E->
getRHS(), PromotionType);
1149 if (!PromotionType.
isNull())
1150 Ops.Ty = PromotionType;
1158LValue ComplexExprEmitter::
1162 TestAndClearIgnoreReal();
1163 TestAndClearIgnoreImag();
1166 LHSTy = AT->getValueType();
1170 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
1177 if (PromotionTypeCR.
isNull())
1179 OpInfo.Ty = PromotionTypeCR;
1186 if (!PromotionTypeRHS.
isNull())
1196 if (!PromotionTypeRHS.
isNull()) {
1202 OpInfo.RHS = Visit(E->
getRHS());
1213 if (!PromotionTypeLHS.
isNull())
1215 EmitComplexToComplexCast(LHSVal, LHSTy, PromotionTypeLHS, Loc);
1217 OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc);
1224 if (!PromotionTypeLHS.
isNull()) {
1225 PromotedComplexElementTy =
1226 cast<ComplexType>(PromotionTypeLHS)->getElementType();
1230 PromotedComplexElementTy, Loc);
1238 OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc);
1248 EmitComplexToComplexCast(
Result, OpInfo.Ty, LHSTy, Loc);
1249 EmitStoreOfComplex(ResVal, LHS,
false);
1252 llvm::Value *ResVal =
1266 LValue LV = EmitCompoundAssignLValue(E,
Func, Val);
1276 return EmitLoadOfLValue(LV, E->
getExprLoc());
1283 "Invalid assignment");
1284 TestAndClearIgnoreReal();
1285 TestAndClearIgnoreImag();
1288 Val = Visit(E->
getRHS());
1294 EmitStoreOfComplex(Val, LHS,
false);
1301 LValue LV = EmitBinAssignLValue(E, Val);
1311 return EmitLoadOfLValue(LV, E->
getExprLoc());
1316 return Visit(E->
getRHS());
1321 TestAndClearIgnoreReal();
1322 TestAndClearIgnoreImag();
1328 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
1331 CodeGenFunction::ConditionalEvaluation eval(CGF);
1343 LHSBlock = Builder.GetInsertBlock();
1352 RHSBlock = Builder.GetInsertBlock();
1359 llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), 2,
"cond.r");
1360 RealPN->addIncoming(LHS.first, LHSBlock);
1361 RealPN->addIncoming(RHS.first, RHSBlock);
1364 llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), 2,
"cond.i");
1365 ImagPN->addIncoming(LHS.second, LHSBlock);
1366 ImagPN->addIncoming(RHS.second, RHSBlock);
1376 bool Ignore = TestAndClearIgnoreReal();
1378 assert (Ignore ==
false &&
"init list ignored");
1379 Ignore = TestAndClearIgnoreImag();
1381 assert (Ignore ==
false &&
"init list ignored");
1392 assert(E->
getNumInits() == 0 &&
"Unexpected number of inits");
1395 llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy);
1407 llvm::Value *
U = llvm::UndefValue::get(EltTy);
1424 "Invalid complex expression to emit");
1426 return ComplexExprEmitter(*
this, IgnoreReal, IgnoreImag)
1427 .Visit(
const_cast<Expr *
>(E));
1433 "Invalid complex expression to emit");
1434 ComplexExprEmitter
Emitter(*
this);
1436 Emitter.EmitStoreOfComplex(Val, dest, isInit);
1442 ComplexExprEmitter(*this).EmitStoreOfComplex(
V, dest, isInit);
1448 return ComplexExprEmitter(*this).EmitLoadOfLValue(src, loc);
1454 LValue LVal = ComplexExprEmitter(*this).EmitBinAssignLValue(E, Val);
1462 const ComplexExprEmitter::BinOpInfo &);
1466 case BO_MulAssign:
return &ComplexExprEmitter::EmitBinMul;
1467 case BO_DivAssign:
return &ComplexExprEmitter::EmitBinDiv;
1468 case BO_SubAssign:
return &ComplexExprEmitter::EmitBinSub;
1469 case BO_AddAssign:
return &ComplexExprEmitter::EmitBinAdd;
1471 llvm_unreachable(
"unexpected complex compound assignment");
1479 return ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);
1487 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)
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...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?: operator.
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
A builtin binary operation expression such as "x + y" or "x <= y".
SourceLocation getExprLoc() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
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.
Expr * getSemanticForm()
Get an equivalent semantic form for this expression.
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]).
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
bool changesVolatileQualification() const
Return.
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Represents a 'co_await' expression.
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.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke, bool IsMustTail, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type,...
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 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)
Address EmitVAArg(VAArgExpr *VE, Address &VAListAddr)
Generate code to get an argument from the passed in pointer and update it accordingly.
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.
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(CodeGenFunction &CGF) 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.
QualType getComputationLHSType() const
QualType getComputationResultType() const
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.
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...
const Expr * getSubExpr() const
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.
unsigned getNumInits() const
const Expr * getInit(unsigned Init) const
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.
SourceLocation getExprLoc() const LLVM_READONLY
Expr * getSelectedExpr() const
ParenExpr - This represents a parethesized 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;}).
CompoundStmt * getSubStmt()
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 isReferenceType() const
bool isAnyComplexType() const
bool isAtomicType() const
bool isRealFloatingType() const
Floating point categories.
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),...
Expr * getSubExpr() const
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)
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
YAML serialization mapping.
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)