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!");
111 if (llvm::Constant *Result =
ConstantEmitter(CGF).tryEmitConstantExpr(E))
113 Result->getAggregateElement(1U));
118 return Visit(
GE->getResultExpr());
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);
186 return EmitLoadOfLValue(E);
190 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
193 return EmitLoadOfLValue(E);
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);
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);
333 QualType ElementType = CT->getElementType();
336 LangOptions::ComplexRangeKind::CX_Promoted)
337 return HigherPrecisionTypeForComplexArithmetic(ElementType,
347#define HANDLEBINOP(OP) \
348 ComplexPairTy VisitBin##OP(const BinaryOperator *E) { \
349 QualType promotionTy = getPromotionType( \
351 (E->getOpcode() == BinaryOperatorKind::BO_Div) ? true : false); \
352 ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy)); \
353 if (!promotionTy.isNull()) \
354 result = CGF.EmitUnPromotedValue(result, E->getType()); \
370 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd);
373 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub);
376 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul);
379 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv);
400 return EmitLoadOfLValue(E);
433 assert(lvalue.
isSimple() &&
"non-simple complex l-value?");
440 llvm::Value *Real =
nullptr, *Imag =
nullptr;
442 if (!IgnoreReal || isVolatile) {
444 Real = Builder.CreateLoad(RealP, isVolatile, SrcPtr.
getName() +
".real");
447 if (!IgnoreImag || isVolatile) {
449 Imag = Builder.CreateLoad(ImagP, isVolatile, SrcPtr.
getName() +
".imag");
481 llvm::Value *
U = llvm::UndefValue::get(EltTy);
488 return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag);
494 return EmitLoadOfLValue(E);
500 CodeGenFunction::StmtExprEvaluation eval(CGF);
502 assert(RetAlloca.
isValid() &&
"Expected complex return value");
526ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val,
535 return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType()));
541 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
545 case CK_AtomicToNonAtomic:
546 case CK_NonAtomicToAtomic:
548 case CK_LValueToRValue:
549 case CK_UserDefinedConversion:
552 case CK_LValueBitCast: {
558 case CK_LValueToRValueBitCast: {
564 return EmitLoadOfLValue(DestLV, Op->
getExprLoc());
568 case CK_BaseToDerived:
569 case CK_DerivedToBase:
570 case CK_UncheckedDerivedToBase:
573 case CK_ArrayToPointerDecay:
574 case CK_FunctionToPointerDecay:
575 case CK_NullToPointer:
576 case CK_NullToMemberPointer:
577 case CK_BaseToDerivedMemberPointer:
578 case CK_DerivedToBaseMemberPointer:
579 case CK_MemberPointerToBoolean:
580 case CK_ReinterpretMemberPointer:
581 case CK_ConstructorConversion:
582 case CK_IntegralToPointer:
583 case CK_PointerToIntegral:
584 case CK_PointerToBoolean:
587 case CK_IntegralCast:
588 case CK_BooleanToSignedIntegral:
589 case CK_IntegralToBoolean:
590 case CK_IntegralToFloating:
591 case CK_FloatingToIntegral:
592 case CK_FloatingToBoolean:
593 case CK_FloatingCast:
594 case CK_CPointerToObjCPointerCast:
595 case CK_BlockPointerToObjCPointerCast:
596 case CK_AnyPointerToBlockPointerCast:
597 case CK_ObjCObjectLValueCast:
598 case CK_FloatingComplexToReal:
599 case CK_FloatingComplexToBoolean:
600 case CK_IntegralComplexToReal:
601 case CK_IntegralComplexToBoolean:
602 case CK_ARCProduceObject:
603 case CK_ARCConsumeObject:
604 case CK_ARCReclaimReturnedObject:
605 case CK_ARCExtendBlockObject:
606 case CK_CopyAndAutoreleaseBlockObject:
607 case CK_BuiltinFnToFnPtr:
608 case CK_ZeroToOCLOpaqueType:
609 case CK_AddressSpaceConversion:
610 case CK_IntToOCLSampler:
611 case CK_FloatingToFixedPoint:
612 case CK_FixedPointToFloating:
613 case CK_FixedPointCast:
614 case CK_FixedPointToBoolean:
615 case CK_FixedPointToIntegral:
616 case CK_IntegralToFixedPoint:
618 case CK_HLSLVectorTruncation:
619 case CK_HLSLArrayRValue:
620 llvm_unreachable(
"invalid cast kind for complex value");
622 case CK_FloatingRealToComplex:
623 case CK_IntegralRealToComplex: {
624 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op);
629 case CK_FloatingComplexCast:
630 case CK_FloatingComplexToIntegralComplex:
631 case CK_IntegralComplexCast:
632 case CK_IntegralComplexToFloatingComplex: {
633 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op);
634 return EmitComplexToComplexCast(Visit(Op), Op->
getType(), DestTy,
639 llvm_unreachable(
"unknown cast resulting in complex value");
648 if (!promotionTy.
isNull())
655 TestAndClearIgnoreReal();
656 TestAndClearIgnoreImag();
657 if (!PromotionType.
isNull())
668 if (!promotionTy.
isNull())
674 TestAndClearIgnoreReal();
675 TestAndClearIgnoreImag();
677 if (!PromotionType.
isNull())
682 llvm::Value *ResR, *ResI;
683 if (Op.first->getType()->isFloatingPointTy()) {
684 ResR = Builder.CreateFNeg(Op.first,
"neg.r");
685 ResI = Builder.CreateFNeg(Op.second,
"neg.i");
687 ResR = Builder.CreateNeg(Op.first,
"neg.r");
688 ResI = Builder.CreateNeg(Op.second,
"neg.i");
694 TestAndClearIgnoreReal();
695 TestAndClearIgnoreImag();
699 if (Op.second->getType()->isFloatingPointTy())
700 ResI = Builder.CreateFNeg(Op.second,
"conj.i");
702 ResI = Builder.CreateNeg(Op.second,
"conj.i");
707ComplexPairTy ComplexExprEmitter::EmitBinAdd(
const BinOpInfo &Op) {
708 llvm::Value *ResR, *ResI;
710 if (Op.LHS.first->getType()->isFloatingPointTy()) {
711 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
712 ResR = Builder.CreateFAdd(Op.LHS.first, Op.RHS.first,
"add.r");
713 if (Op.LHS.second && Op.RHS.second)
714 ResI = Builder.CreateFAdd(Op.LHS.second, Op.RHS.second,
"add.i");
716 ResI = Op.LHS.second ? Op.LHS.second : Op.RHS.second;
717 assert(ResI &&
"Only one operand may be real!");
719 ResR = Builder.CreateAdd(Op.LHS.first, Op.RHS.first,
"add.r");
720 assert(Op.LHS.second && Op.RHS.second &&
721 "Both operands of integer complex operators must be complex!");
722 ResI = Builder.CreateAdd(Op.LHS.second, Op.RHS.second,
"add.i");
727ComplexPairTy ComplexExprEmitter::EmitBinSub(
const BinOpInfo &Op) {
728 llvm::Value *ResR, *ResI;
729 if (Op.LHS.first->getType()->isFloatingPointTy()) {
730 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
731 ResR = Builder.CreateFSub(Op.LHS.first, Op.RHS.first,
"sub.r");
732 if (Op.LHS.second && Op.RHS.second)
733 ResI = Builder.CreateFSub(Op.LHS.second, Op.RHS.second,
"sub.i");
735 ResI = Op.LHS.second ? Op.LHS.second
736 : Builder.CreateFNeg(Op.RHS.second,
"sub.i");
737 assert(ResI &&
"Only one operand may be real!");
739 ResR = Builder.CreateSub(Op.LHS.first, Op.RHS.first,
"sub.r");
740 assert(Op.LHS.second && Op.RHS.second &&
741 "Both operands of integer complex operators must be complex!");
742 ResI = Builder.CreateSub(Op.LHS.second, Op.RHS.second,
"sub.i");
748ComplexPairTy ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName,
749 const BinOpInfo &Op) {
773 Args, cast<FunctionType>(FQTy.
getTypePtr()),
false);
777 FTy, LibCallName, llvm::AttributeList(),
true);
780 llvm::CallBase *
Call;
789 switch (Ty->getTypeID()) {
791 llvm_unreachable(
"Unsupported floating point type!");
792 case llvm::Type::HalfTyID:
794 case llvm::Type::FloatTyID:
796 case llvm::Type::DoubleTyID:
798 case llvm::Type::PPC_FP128TyID:
800 case llvm::Type::X86_FP80TyID:
802 case llvm::Type::FP128TyID:
809ComplexPairTy ComplexExprEmitter::EmitBinMul(
const BinOpInfo &Op) {
814 if (Op.LHS.first->getType()->isFloatingPointTy()) {
823 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
824 if (Op.LHS.second && Op.RHS.second) {
835 Value *AC = Builder.CreateFMul(Op.LHS.first, Op.RHS.first,
"mul_ac");
836 Value *BD = Builder.CreateFMul(Op.LHS.second, Op.RHS.second,
"mul_bd");
837 Value *AD = Builder.CreateFMul(Op.LHS.first, Op.RHS.second,
"mul_ad");
838 Value *BC = Builder.CreateFMul(Op.LHS.second, Op.RHS.first,
"mul_bc");
842 ResR = Builder.CreateFSub(AC, BD,
"mul_r");
843 ResI = Builder.CreateFAdd(AD, BC,
"mul_i");
852 Value *IsRNaN = Builder.CreateFCmpUNO(ResR, ResR,
"isnan_cmp");
855 llvm::Instruction *Branch = Builder.CreateCondBr(IsRNaN, INaNBB, ContBB);
856 llvm::BasicBlock *OrigBB = Branch->getParent();
860 llvm::MDNode *BrWeight = MDHelper.createBranchWeights(1, (1U << 20) - 1);
861 Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight);
865 Value *IsINaN = Builder.CreateFCmpUNO(ResI, ResI,
"isnan_cmp");
867 Branch = Builder.CreateCondBr(IsINaN, LibCallBB, ContBB);
868 Branch->setMetadata(llvm::LLVMContext::MD_prof, BrWeight);
872 Value *LibCallR, *LibCallI;
873 std::tie(LibCallR, LibCallI) = EmitComplexBinOpLibCall(
875 Builder.CreateBr(ContBB);
880 llvm::PHINode *RealPHI = Builder.CreatePHI(ResR->
getType(), 3,
"real_mul_phi");
881 RealPHI->addIncoming(ResR, OrigBB);
882 RealPHI->addIncoming(ResR, INaNBB);
883 RealPHI->addIncoming(LibCallR, LibCallBB);
884 llvm::PHINode *ImagPHI = Builder.CreatePHI(ResI->
getType(), 3,
"imag_mul_phi");
885 ImagPHI->addIncoming(ResI, OrigBB);
886 ImagPHI->addIncoming(ResI, INaNBB);
887 ImagPHI->addIncoming(LibCallI, LibCallBB);
890 assert((Op.LHS.second || Op.RHS.second) &&
891 "At least one operand must be complex!");
896 ResR = Builder.CreateFMul(Op.LHS.first, Op.RHS.first,
"mul.rl");
899 ? Builder.CreateFMul(Op.LHS.second, Op.RHS.first,
"mul.il")
900 : Builder.CreateFMul(Op.LHS.first, Op.RHS.second,
"mul.ir");
902 assert(Op.LHS.second && Op.RHS.second &&
903 "Both operands of integer complex operators must be complex!");
904 Value *ResRl = Builder.CreateMul(Op.LHS.first, Op.RHS.first,
"mul.rl");
905 Value *ResRr = Builder.CreateMul(Op.LHS.second, Op.RHS.second,
"mul.rr");
906 ResR = Builder.CreateSub(ResRl, ResRr,
"mul.r");
908 Value *ResIl = Builder.CreateMul(Op.LHS.second, Op.RHS.first,
"mul.il");
909 Value *ResIr = Builder.CreateMul(Op.LHS.first, Op.RHS.second,
"mul.ir");
910 ResI = Builder.CreateAdd(ResIl, ResIr,
"mul.i");
915ComplexPairTy ComplexExprEmitter::EmitAlgebraicDiv(llvm::Value *LHSr,
920 llvm::Value *DSTr, *DSTi;
922 llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr);
923 llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi);
924 llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD);
926 llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr);
927 llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi);
928 llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD);
930 llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr);
931 llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi);
932 llvm::Value *BCmAD = Builder.CreateFSub(BC, AD);
934 DSTr = Builder.CreateFDiv(ACpBD, CCpDD);
935 DSTi = Builder.CreateFDiv(BCmAD, CCpDD);
941 llvm::Function *
Func =
949ComplexPairTy ComplexExprEmitter::EmitRangeReductionDiv(llvm::Value *LHSr,
960 llvm::Value *IsR = Builder.CreateFCmpUGT(FAbsRHSr, FAbsRHSi,
"abs_cmp");
962 llvm::BasicBlock *TrueBB =
964 llvm::BasicBlock *FalseBB =
967 Builder.CreateCondBr(IsR, TrueBB, FalseBB);
975 llvm::Value *DdC = Builder.CreateFDiv(RHSi, RHSr);
977 llvm::Value *RD = Builder.CreateFMul(DdC, RHSi);
978 llvm::Value *CpRD = Builder.CreateFAdd(RHSr, RD);
980 llvm::Value *T3 = Builder.CreateFMul(LHSi, DdC);
981 llvm::Value *T4 = Builder.CreateFAdd(LHSr, T3);
982 llvm::Value *DSTTr = Builder.CreateFDiv(T4, CpRD);
984 llvm::Value *T5 = Builder.CreateFMul(LHSr, DdC);
985 llvm::Value *T6 = Builder.CreateFSub(LHSi, T5);
986 llvm::Value *DSTTi = Builder.CreateFDiv(T6, CpRD);
987 Builder.CreateBr(ContBB);
995 llvm::Value *CdD = Builder.CreateFDiv(RHSr, RHSi);
997 llvm::Value *RC = Builder.CreateFMul(CdD, RHSr);
998 llvm::Value *DpRC = Builder.CreateFAdd(RHSi, RC);
1000 llvm::Value *T7 = Builder.CreateFMul(LHSr, CdD);
1001 llvm::Value *T8 = Builder.CreateFAdd(T7, LHSi);
1002 llvm::Value *DSTFr = Builder.CreateFDiv(T8, DpRC);
1004 llvm::Value *T9 = Builder.CreateFMul(LHSi, CdD);
1005 llvm::Value *T10 = Builder.CreateFSub(T9, LHSr);
1006 llvm::Value *DSTFi = Builder.CreateFDiv(T10, DpRC);
1007 Builder.CreateBr(ContBB);
1011 llvm::PHINode *VALr = Builder.CreatePHI(DSTTr->getType(), 2);
1012 VALr->addIncoming(DSTTr, TrueBB);
1013 VALr->addIncoming(DSTFr, FalseBB);
1014 llvm::PHINode *VALi = Builder.CreatePHI(DSTTi->getType(), 2);
1015 VALi->addIncoming(DSTTi, TrueBB);
1016 VALi->addIncoming(DSTFi, FalseBB);
1022ComplexPairTy ComplexExprEmitter::EmitBinDiv(
const BinOpInfo &Op) {
1023 llvm::Value *LHSr = Op.LHS.first, *LHSi = Op.LHS.second;
1024 llvm::Value *RHSr = Op.RHS.first, *RHSi = Op.RHS.second;
1025 llvm::Value *DSTr, *DSTi;
1026 if (LHSr->getType()->isFloatingPointTy()) {
1027 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Op.FPFeatures);
1029 assert(LHSi &&
"Can have at most one non-complex operand!");
1031 DSTr = Builder.CreateFDiv(LHSr, RHSr);
1032 DSTi = Builder.CreateFDiv(LHSi, RHSr);
1035 llvm::Value *OrigLHSi = LHSi;
1037 LHSi = llvm::Constant::getNullValue(RHSi->getType());
1040 !FPHasBeenPromoted))
1041 return EmitRangeReductionDiv(LHSr, LHSi, RHSr, RHSi);
1044 return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi);
1056 BinOpInfo LibCallOp = Op;
1059 LibCallOp.LHS.second = llvm::Constant::getNullValue(LHSr->getType());
1061 switch (LHSr->getType()->getTypeID()) {
1063 llvm_unreachable(
"Unsupported floating point type!");
1064 case llvm::Type::HalfTyID:
1065 return EmitComplexBinOpLibCall(
"__divhc3", LibCallOp);
1066 case llvm::Type::FloatTyID:
1067 return EmitComplexBinOpLibCall(
"__divsc3", LibCallOp);
1068 case llvm::Type::DoubleTyID:
1069 return EmitComplexBinOpLibCall(
"__divdc3", LibCallOp);
1070 case llvm::Type::PPC_FP128TyID:
1071 return EmitComplexBinOpLibCall(
"__divtc3", LibCallOp);
1072 case llvm::Type::X86_FP80TyID:
1073 return EmitComplexBinOpLibCall(
"__divxc3", LibCallOp);
1074 case llvm::Type::FP128TyID:
1075 return EmitComplexBinOpLibCall(
"__divtc3", LibCallOp);
1078 return EmitAlgebraicDiv(LHSr, LHSi, RHSr, RHSi);
1081 assert(Op.LHS.second && Op.RHS.second &&
1082 "Both operands of integer complex operators must be complex!");
1084 llvm::Value *Tmp1 = Builder.CreateMul(LHSr, RHSr);
1085 llvm::Value *Tmp2 = Builder.CreateMul(LHSi, RHSi);
1086 llvm::Value *Tmp3 = Builder.CreateAdd(Tmp1, Tmp2);
1088 llvm::Value *Tmp4 = Builder.CreateMul(RHSr, RHSr);
1089 llvm::Value *Tmp5 = Builder.CreateMul(RHSi, RHSi);
1090 llvm::Value *Tmp6 = Builder.CreateAdd(Tmp4, Tmp5);
1092 llvm::Value *Tmp7 = Builder.CreateMul(LHSi, RHSr);
1093 llvm::Value *Tmp8 = Builder.CreateMul(LHSr, RHSi);
1094 llvm::Value *Tmp9 = Builder.CreateSub(Tmp7, Tmp8);
1097 DSTr = Builder.CreateUDiv(Tmp3, Tmp6);
1098 DSTi = Builder.CreateUDiv(Tmp9, Tmp6);
1100 DSTr = Builder.CreateSDiv(Tmp3, Tmp6);
1101 DSTi = Builder.CreateSDiv(Tmp9, Tmp6);
1110 llvm::Type *ComplexElementTy =
1114 Builder.CreateFPTrunc(result.first, ComplexElementTy,
"unpromotion");
1117 Builder.CreateFPTrunc(result.second, ComplexElementTy,
"unpromotion");
1123 llvm::Type *ComplexElementTy =
1126 result.first =
Builder.CreateFPExt(result.first, ComplexElementTy,
"ext");
1128 result.second =
Builder.CreateFPExt(result.second, ComplexElementTy,
"ext");
1136 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
1137 switch (BO->getOpcode()) {
1138#define HANDLE_BINOP(OP) \
1140 return EmitBin##OP(EmitBinOps(BO, PromotionType));
1149 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
1150 switch (UO->getOpcode()) {
1152 return VisitMinus(UO, PromotionType);
1154 return VisitPlus(UO, PromotionType);
1159 auto result = Visit(
const_cast<Expr *
>(E));
1160 if (!PromotionType.
isNull())
1168 return ComplexExprEmitter(*this).EmitPromoted(E, DstTy);
1172ComplexExprEmitter::EmitPromotedComplexOperand(
const Expr *E,
1175 if (!OverallPromotionType.
isNull())
1178 return Visit(
const_cast<Expr *
>(E));
1180 if (!OverallPromotionType.
isNull()) {
1191ComplexExprEmitter::BinOpInfo
1194 TestAndClearIgnoreReal();
1195 TestAndClearIgnoreImag();
1198 Ops.LHS = EmitPromotedComplexOperand(E->
getLHS(), PromotionType);
1199 Ops.RHS = EmitPromotedComplexOperand(E->
getRHS(), PromotionType);
1200 if (!PromotionType.
isNull())
1201 Ops.Ty = PromotionType;
1209LValue ComplexExprEmitter::
1213 TestAndClearIgnoreReal();
1214 TestAndClearIgnoreImag();
1217 LHSTy = AT->getValueType();
1221 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
1228 if (PromotionTypeCR.
isNull())
1230 OpInfo.Ty = PromotionTypeCR;
1237 if (!PromotionTypeRHS.
isNull())
1247 if (!PromotionTypeRHS.
isNull()) {
1253 OpInfo.RHS = Visit(E->
getRHS());
1264 if (!PromotionTypeLHS.
isNull())
1266 EmitComplexToComplexCast(LHSVal, LHSTy, PromotionTypeLHS, Loc);
1268 OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc);
1275 if (!PromotionTypeLHS.
isNull()) {
1276 PromotedComplexElementTy =
1277 cast<ComplexType>(PromotionTypeLHS)->getElementType();
1281 PromotedComplexElementTy, Loc);
1289 OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc);
1299 EmitComplexToComplexCast(
Result, OpInfo.Ty, LHSTy, Loc);
1300 EmitStoreOfComplex(ResVal, LHS,
false);
1303 llvm::Value *ResVal =
1317 LValue LV = EmitCompoundAssignLValue(E,
Func, Val);
1327 return EmitLoadOfLValue(LV, E->
getExprLoc());
1334 "Invalid assignment");
1335 TestAndClearIgnoreReal();
1336 TestAndClearIgnoreImag();
1339 Val = Visit(E->
getRHS());
1345 EmitStoreOfComplex(Val, LHS,
false);
1352 LValue LV = EmitBinAssignLValue(E, Val);
1362 return EmitLoadOfLValue(LV, E->
getExprLoc());
1367 return Visit(E->
getRHS());
1372 TestAndClearIgnoreReal();
1373 TestAndClearIgnoreImag();
1379 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
1382 CodeGenFunction::ConditionalEvaluation eval(CGF);
1394 LHSBlock = Builder.GetInsertBlock();
1403 RHSBlock = Builder.GetInsertBlock();
1410 llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), 2,
"cond.r");
1411 RealPN->addIncoming(LHS.first, LHSBlock);
1412 RealPN->addIncoming(RHS.first, RHSBlock);
1415 llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), 2,
"cond.i");
1416 ImagPN->addIncoming(LHS.second, LHSBlock);
1417 ImagPN->addIncoming(RHS.second, RHSBlock);
1427 bool Ignore = TestAndClearIgnoreReal();
1429 assert (Ignore ==
false &&
"init list ignored");
1430 Ignore = TestAndClearIgnoreImag();
1432 assert (Ignore ==
false &&
"init list ignored");
1443 assert(E->
getNumInits() == 0 &&
"Unexpected number of inits");
1446 llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy);
1458 llvm::Value *
U = llvm::UndefValue::get(EltTy);
1475 "Invalid complex expression to emit");
1477 return ComplexExprEmitter(*
this, IgnoreReal, IgnoreImag)
1478 .Visit(
const_cast<Expr *
>(E));
1484 "Invalid complex expression to emit");
1485 ComplexExprEmitter
Emitter(*
this);
1487 Emitter.EmitStoreOfComplex(Val, dest, isInit);
1493 ComplexExprEmitter(*this).EmitStoreOfComplex(
V, dest, isInit);
1499 return ComplexExprEmitter(*this).EmitLoadOfLValue(src, loc);
1505 LValue LVal = ComplexExprEmitter(*this).EmitBinAssignLValue(E, Val);
1513 const ComplexExprEmitter::BinOpInfo &);
1517 case BO_MulAssign:
return &ComplexExprEmitter::EmitBinMul;
1518 case BO_DivAssign:
return &ComplexExprEmitter::EmitBinDiv;
1519 case BO_SubAssign:
return &ComplexExprEmitter::EmitBinSub;
1520 case BO_AddAssign:
return &ComplexExprEmitter::EmitBinAdd;
1522 llvm_unreachable(
"unexpected complex compound assignment");
1530 return ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);
1538 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...
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.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
llvm::StringRef getName() const
Return the IR name of the pointer value.
A scoped helper to set the current debug location to the specified location or preferred location of ...
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
All available information about a concrete callee.
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
CGFunctionInfo - Class to encapsulate the information about a function definition.
virtual void checkAndEmitLastprivateConditional(CodeGenFunction &CGF, const Expr *LHS)
Checks if the provided LVal is lastprivate conditional and emits the code to update the value of the ...
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.
LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, llvm::Value *&Result)
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
RValue EmitAtomicLoad(LValue LV, SourceLocation SL, AggValueSlot Slot=AggValueSlot::ignored())
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const LangOptions & getLangOpts() const
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type,...
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
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.
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(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.
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.
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
@ 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.
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 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),...
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, 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)