19#include "llvm/IR/Constants.h"
20#include "llvm/IR/Instructions.h"
21#include "llvm/IR/MDBuilder.h"
22#include "llvm/IR/Metadata.h"
47class ComplexExprEmitter
48 :
public StmtVisitor<ComplexExprEmitter, ComplexPairTy> {
53 bool FPHasBeenPromoted;
56 ComplexExprEmitter(CodeGenFunction &cgf,
bool ir =
false,
bool ii =
false)
57 : CGF(cgf), Builder(CGF.Builder), IgnoreReal(ir), IgnoreImag(ii),
58 FPHasBeenPromoted(
false) {}
64 bool TestAndClearIgnoreReal() {
69 bool TestAndClearIgnoreImag() {
82 ComplexPairTy EmitLoadOfLValue(LValue LV, SourceLocation Loc);
86 void EmitStoreOfComplex(
ComplexPairTy Val, LValue LV,
bool isInit);
90 QualType DestType, SourceLocation Loc);
92 ComplexPairTy EmitScalarToComplexCast(llvm::Value *Val, QualType SrcType,
93 QualType DestType, SourceLocation Loc);
100 ApplyDebugLocation DL(CGF, E);
101 return StmtVisitor<ComplexExprEmitter, ComplexPairTy>::Visit(E);
106 llvm_unreachable(
"Stmt can't have complex result type!");
110 if (llvm::Constant *
Result = ConstantEmitter(CGF).tryEmitConstantExpr(E))
112 Result->getAggregateElement(1U));
116 ComplexPairTy VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
117 return Visit(
GE->getResultExpr());
119 ComplexPairTy VisitImaginaryLiteral(
const ImaginaryLiteral *IL);
121 VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *PE) {
134 ComplexPairTy emitConstant(
const CodeGenFunction::ConstantEmission &Constant,
136 assert(Constant &&
"not a constant");
141 llvm::Constant *pair = Constant.
getValue();
143 pair->getAggregateElement(1U));
149 return emitConstant(Constant, E);
150 return EmitLoadOfLValue(E);
153 return EmitLoadOfLValue(E);
158 ComplexPairTy VisitArraySubscriptExpr(Expr *E) {
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);
216 ComplexPairTy VisitUnaryDeref(
const Expr *E) {
return EmitLoadOfLValue(E); }
219 QualType PromotionType = QualType());
220 ComplexPairTy VisitPlus(
const UnaryOperator *E, QualType PromotionType);
222 QualType PromotionType = QualType());
223 ComplexPairTy VisitMinus(
const UnaryOperator *E, QualType PromotionType);
229 ComplexPairTy VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
230 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
233 ComplexPairTy VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
234 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
238 CodeGenFunction::RunCleanupsScope Scope(CGF);
242 Scope.ForceCleanup({&Vals.first, &Vals.second});
245 ComplexPairTy VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
247 QualType Elem = E->
getType()->
castAs<ComplexType>()->getElementType();
248 llvm::Constant *
Null = llvm::Constant::getNullValue(CGF.
ConvertType(Elem));
251 ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
253 QualType Elem = E->
getType()->
castAs<ComplexType>()->getElementType();
254 llvm::Constant *
Null =
255 llvm::Constant::getNullValue(CGF.
ConvertType(Elem));
263 FPOptions FPFeatures;
266 BinOpInfo EmitBinOps(
const BinaryOperator *E,
267 QualType PromotionTy = QualType());
268 ComplexPairTy EmitPromoted(
const Expr *E, QualType PromotionTy);
269 ComplexPairTy EmitPromotedComplexOperand(
const Expr *E, QualType PromotionTy);
270 LValue EmitCompoundAssignLValue(
const CompoundAssignOperator *E,
274 ComplexPairTy EmitCompoundAssign(
const CompoundAssignOperator *E,
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);
290 QualType HigherPrecisionTypeForComplexArithmetic(QualType ElementType) {
292 const QualType HigherElementType =
294 const llvm::fltSemantics &ElementTypeSemantics =
296 const llvm::fltSemantics &HigherElementTypeSemantics =
305 if (llvm::APFloat::semanticsMaxExponent(ElementTypeSemantics) * 2 + 1 <=
306 llvm::APFloat::semanticsMaxExponent(HigherElementTypeSemantics)) {
311 FPHasBeenPromoted =
true;
320 QualType getPromotionType(FPOptionsOverride Features, QualType Ty,
321 bool IsComplexDivisor) {
322 if (
auto *CT = Ty->
getAs<ComplexType>()) {
323 QualType ElementType = CT->getElementType();
325 bool IsComplexRangePromoted = CGF.
getLangOpts().getComplexRange() ==
326 LangOptions::ComplexRangeKind::CX_Promoted;
327 bool HasNoComplexRangeOverride = !Features.hasComplexRangeOverride();
328 bool HasMatchingComplexRange = Features.hasComplexRangeOverride() &&
329 Features.getComplexRangeOverride() ==
332 if (IsComplexDivisor && IsFloatingType && IsComplexRangePromoted &&
333 (HasNoComplexRangeOverride || HasMatchingComplexRange))
334 return HigherPrecisionTypeForComplexArithmetic(ElementType);
343#define HANDLEBINOP(OP) \
344 ComplexPairTy VisitBin##OP(const BinaryOperator *E) { \
345 QualType promotionTy = \
346 getPromotionType(E->getStoredFPFeaturesOrDefault(), E->getType(), \
347 (E->getOpcode() == BinaryOperatorKind::BO_Div && \
348 E->getRHS()->getType()->isAnyComplexType())); \
349 ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy)); \
350 if (!promotionTy.isNull()) \
351 result = CGF.EmitUnPromotedValue(result, E->getType()); \
366 ComplexPairTy VisitBinAddAssign(
const CompoundAssignOperator *E) {
368 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinAdd);
370 ComplexPairTy VisitBinSubAssign(
const CompoundAssignOperator *E) {
372 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinSub);
374 ComplexPairTy VisitBinMulAssign(
const CompoundAssignOperator *E) {
376 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinMul);
378 ComplexPairTy VisitBinDivAssign(
const CompoundAssignOperator *E) {
380 return EmitCompoundAssign(E, &ComplexExprEmitter::EmitBinDiv);
388 LValue EmitBinAssignLValue(
const BinaryOperator *E,
395 VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO);
400 ComplexPairTy VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
401 return EmitLoadOfLValue(E);
422 return Builder.CreateStructGEP(addr, 0, addr.
getName() +
".realp");
427 return Builder.CreateStructGEP(addr, 1, addr.
getName() +
".imagp");
434 assert(lvalue.
isSimple() &&
"non-simple complex l-value?");
441 llvm::Value *Real =
nullptr, *Imag =
nullptr;
443 if (!IgnoreReal || isVolatile) {
445 Real = Builder.CreateLoad(RealP, isVolatile, SrcPtr.
getName() +
".real");
448 if (!IgnoreImag || isVolatile) {
450 Imag = Builder.CreateLoad(ImagP, isVolatile, SrcPtr.
getName() +
".imag");
460 if (lvalue.getType()->isAtomicType() ||
464 Address Ptr = lvalue.getAddress();
469 Builder.CreateStore(Val.first, RealPtr, lvalue.isVolatileQualified());
472 Builder.CreateStore(Val.second, ImagPtr, lvalue.isVolatileQualified());
486 llvm::Value *U = llvm::PoisonValue::get(EltTy);
491VisitImaginaryLiteral(
const ImaginaryLiteral *IL) {
493 return ComplexPairTy(llvm::Constant::getNullValue(Imag->getType()), Imag);
497ComplexPairTy ComplexExprEmitter::VisitCallExpr(
const CallExpr *E) {
499 return EmitLoadOfLValue(E);
504ComplexPairTy ComplexExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
507 assert(RetAlloca.
isValid() &&
"Expected complex return value");
516 SourceLocation Loc) {
518 SrcType = SrcType->
castAs<ComplexType>()->getElementType();
519 DestType = DestType->
castAs<ComplexType>()->getElementType();
531ComplexPairTy ComplexExprEmitter::EmitScalarToComplexCast(llvm::Value *Val,
534 SourceLocation Loc) {
536 DestType = DestType->
castAs<ComplexType>()->getElementType();
540 return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType()));
546 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
550 case CK_AtomicToNonAtomic:
551 case CK_NonAtomicToAtomic:
553 case CK_LValueToRValue:
554 case CK_UserDefinedConversion:
557 case CK_LValueBitCast: {
563 case CK_LValueToRValueBitCast: {
569 return EmitLoadOfLValue(DestLV, Op->
getExprLoc());
573 case CK_BaseToDerived:
574 case CK_DerivedToBase:
575 case CK_UncheckedDerivedToBase:
578 case CK_ArrayToPointerDecay:
579 case CK_FunctionToPointerDecay:
580 case CK_NullToPointer:
581 case CK_NullToMemberPointer:
582 case CK_BaseToDerivedMemberPointer:
583 case CK_DerivedToBaseMemberPointer:
584 case CK_MemberPointerToBoolean:
585 case CK_ReinterpretMemberPointer:
586 case CK_ConstructorConversion:
587 case CK_IntegralToPointer:
588 case CK_PointerToIntegral:
589 case CK_PointerToBoolean:
592 case CK_IntegralCast:
593 case CK_BooleanToSignedIntegral:
594 case CK_IntegralToBoolean:
595 case CK_IntegralToFloating:
596 case CK_FloatingToIntegral:
597 case CK_FloatingToBoolean:
598 case CK_FloatingCast:
599 case CK_CPointerToObjCPointerCast:
600 case CK_BlockPointerToObjCPointerCast:
601 case CK_AnyPointerToBlockPointerCast:
602 case CK_ObjCObjectLValueCast:
603 case CK_FloatingComplexToReal:
604 case CK_FloatingComplexToBoolean:
605 case CK_IntegralComplexToReal:
606 case CK_IntegralComplexToBoolean:
607 case CK_ARCProduceObject:
608 case CK_ARCConsumeObject:
609 case CK_ARCReclaimReturnedObject:
610 case CK_ARCExtendBlockObject:
611 case CK_CopyAndAutoreleaseBlockObject:
612 case CK_BuiltinFnToFnPtr:
613 case CK_ZeroToOCLOpaqueType:
614 case CK_AddressSpaceConversion:
615 case CK_IntToOCLSampler:
616 case CK_FloatingToFixedPoint:
617 case CK_FixedPointToFloating:
618 case CK_FixedPointCast:
619 case CK_FixedPointToBoolean:
620 case CK_FixedPointToIntegral:
621 case CK_IntegralToFixedPoint:
623 case CK_HLSLVectorTruncation:
624 case CK_HLSLArrayRValue:
625 case CK_HLSLElementwiseCast:
626 case CK_HLSLAggregateSplatCast:
627 llvm_unreachable(
"invalid cast kind for complex value");
629 case CK_FloatingRealToComplex:
630 case CK_IntegralRealToComplex: {
636 case CK_FloatingComplexCast:
637 case CK_FloatingComplexToIntegralComplex:
638 case CK_IntegralComplexCast:
639 case CK_IntegralComplexToFloatingComplex: {
641 return EmitComplexToComplexCast(Visit(Op), Op->
getType(), DestTy,
646 llvm_unreachable(
"unknown cast resulting in complex value");
649ComplexPairTy ComplexExprEmitter::VisitUnaryPlus(
const UnaryOperator *E,
650 QualType PromotionType) {
651 QualType promotionTy =
658 if (!promotionTy.
isNull())
663ComplexPairTy ComplexExprEmitter::VisitPlus(
const UnaryOperator *E,
664 QualType PromotionType) {
665 TestAndClearIgnoreReal();
666 TestAndClearIgnoreImag();
667 if (!PromotionType.
isNull())
672ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(
const UnaryOperator *E,
673 QualType PromotionType) {
674 QualType promotionTy =
681 if (!promotionTy.
isNull())
685ComplexPairTy ComplexExprEmitter::VisitMinus(
const UnaryOperator *E,
686 QualType PromotionType) {
687 TestAndClearIgnoreReal();
688 TestAndClearIgnoreImag();
690 if (!PromotionType.
isNull())
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");
706ComplexPairTy ComplexExprEmitter::VisitUnaryNot(
const UnaryOperator *E) {
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()) {
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()) {
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) {
765 Op.Ty->castAs<ComplexType>()->getElementType());
767 Op.Ty->castAs<ComplexType>()->getElementType());
769 Op.Ty->castAs<ComplexType>()->getElementType());
771 Op.Ty->castAs<ComplexType>()->getElementType());
779 FunctionProtoType::ExtProtoInfo EPI;
782 SmallVector<QualType, 4> ArgsQTys(
783 4, Op.Ty->castAs<ComplexType>()->getElementType());
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()) {
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()) {
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);
1103 if (Op.Ty->castAs<ComplexType>()->getElementType()->isUnsignedIntegerType()) {
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
1199ComplexExprEmitter::EmitBinOps(
const BinaryOperator *E,
1200 QualType PromotionType) {
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::
1217EmitCompoundAssignLValue(
const CompoundAssignOperator *E,
1220 TestAndClearIgnoreReal();
1221 TestAndClearIgnoreImag();
1223 if (
const AtomicType *AT = LHSTy->
getAs<AtomicType>())
1224 LHSTy = AT->getValueType();
1230 const bool IsComplexDivisor = E->
getOpcode() == BO_DivAssign &&
1236 QualType PromotionTypeCR;
1240 if (PromotionTypeCR.
isNull())
1242 OpInfo.Ty = PromotionTypeCR;
1243 QualType ComplexElementTy =
1244 OpInfo.Ty->castAs<ComplexType>()->getElementType();
1245 QualType PromotionTypeRHS =
1251 if (!PromotionTypeRHS.
isNull())
1261 if (!PromotionTypeRHS.
isNull()) {
1267 OpInfo.RHS = Visit(E->
getRHS());
1275 QualType PromotionTypeLHS =
1280 if (!PromotionTypeLHS.
isNull())
1282 EmitComplexToComplexCast(LHSVal, LHSTy, PromotionTypeLHS, Loc);
1284 OpInfo.LHS = EmitComplexToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc);
1290 QualType PromotedComplexElementTy;
1291 if (!PromotionTypeLHS.
isNull()) {
1292 PromotedComplexElementTy =
1297 PromotedComplexElementTy, Loc);
1305 OpInfo.LHS = EmitScalarToComplexCast(LHSVal, LHSTy, OpInfo.Ty, Loc);
1315 EmitComplexToComplexCast(
Result, OpInfo.Ty, LHSTy, Loc);
1316 EmitStoreOfComplex(ResVal, LHS,
false);
1319 llvm::Value *ResVal =
1330EmitCompoundAssign(
const CompoundAssignOperator *E,
1333 LValue LV = EmitCompoundAssignLValue(E,
Func, Val);
1340 if (!LV.isVolatileQualified())
1343 return EmitLoadOfLValue(LV, E->
getExprLoc());
1346LValue ComplexExprEmitter::EmitBinAssignLValue(
const BinaryOperator *E,
1350 "Invalid assignment");
1351 TestAndClearIgnoreReal();
1352 TestAndClearIgnoreImag();
1355 Val = Visit(E->
getRHS());
1361 EmitStoreOfComplex(Val, LHS,
false);
1366ComplexPairTy ComplexExprEmitter::VisitBinAssign(
const BinaryOperator *E) {
1369 LValue LV = EmitBinAssignLValue(E, Val);
1376 if (!LV.isVolatileQualified())
1379 return EmitLoadOfLValue(LV, E->
getExprLoc());
1382ComplexPairTy ComplexExprEmitter::VisitBinComma(
const BinaryOperator *E) {
1384 return Visit(E->
getRHS());
1388VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
1389 TestAndClearIgnoreReal();
1390 TestAndClearIgnoreImag();
1411 LHSBlock = Builder.GetInsertBlock();
1420 RHSBlock = Builder.GetInsertBlock();
1427 llvm::PHINode *RealPN = Builder.CreatePHI(LHS.first->getType(), 2,
"cond.r");
1428 RealPN->addIncoming(LHS.first, LHSBlock);
1429 RealPN->addIncoming(RHS.first, RHSBlock);
1432 llvm::PHINode *ImagPN = Builder.CreatePHI(LHS.first->getType(), 2,
"cond.i");
1433 ImagPN->addIncoming(LHS.second, LHSBlock);
1434 ImagPN->addIncoming(RHS.second, RHSBlock);
1439ComplexPairTy ComplexExprEmitter::VisitChooseExpr(ChooseExpr *E) {
1443ComplexPairTy ComplexExprEmitter::VisitInitListExpr(InitListExpr *E) {
1444 bool Ignore = TestAndClearIgnoreReal();
1446 assert (Ignore ==
false &&
"init list ignored");
1447 Ignore = TestAndClearIgnoreImag();
1449 assert (Ignore ==
false &&
"init list ignored");
1460 assert(E->
getNumInits() == 0 &&
"Unexpected number of inits");
1461 QualType Ty = E->
getType()->
castAs<ComplexType>()->getElementType();
1463 llvm::Value* zeroConstant = llvm::Constant::getNullValue(LTy);
1467ComplexPairTy ComplexExprEmitter::VisitVAArgExpr(VAArgExpr *E) {
1475 llvm::Value *U = llvm::PoisonValue::get(EltTy);
1491 "Invalid complex expression to emit");
1493 return ComplexExprEmitter(*
this, IgnoreReal, IgnoreImag)
1494 .Visit(
const_cast<Expr *
>(E));
1500 "Invalid complex expression to emit");
1501 ComplexExprEmitter
Emitter(*
this);
1503 Emitter.EmitStoreOfComplex(Val, dest, isInit);
1509 ComplexExprEmitter(*this).EmitStoreOfComplex(
V, dest, isInit);
1515 return ComplexExprEmitter(*this).EmitLoadOfLValue(src, loc);
1521 LValue LVal = ComplexExprEmitter(*this).EmitBinAssignLValue(E, Val);
1523 CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(*
this,
1529 const ComplexExprEmitter::BinOpInfo &);
1533 case BO_MulAssign:
return &ComplexExprEmitter::EmitBinMul;
1534 case BO_DivAssign:
return &ComplexExprEmitter::EmitBinDiv;
1535 case BO_SubAssign:
return &ComplexExprEmitter::EmitBinSub;
1536 case BO_AddAssign:
return &ComplexExprEmitter::EmitBinAdd;
1538 llvm_unreachable(
"unexpected complex compound assignment");
1547 return ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);
1557 LValue Ret = ComplexExprEmitter(*this).EmitCompoundAssignLValue(E, Op, Val);
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)
static const ComplexType * getComplexType(QualType type)
Return the complex type that we are meant to emit.
mlir::Value(ComplexExprEmitter::*)(const ComplexExprEmitter::BinOpInfo &) CompoundFunc
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
const QualType GetHigherPrecisionFPType(QualType ElementType) const
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
const TargetInfo & getTargetInfo() const
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
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...
A builtin binary operation expression such as "x + y" or "x <= y".
FPOptionsOverride getStoredFPFeaturesOrDefault() const
Get the store FPOptionsOverride or default if not stored.
SourceLocation getExprLoc() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
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.
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CastKind getCastKind() const
bool changesVolatileQualification() const
Return.
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::StringRef getName() const
Return the IR name of the pointer value.
A scoped helper to set the current source atom group for CGDebugInfo::addInstToCurrentSourceAtom.
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.
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
An object to manage conditionally-evaluated expressions.
LValue getReferenceLValue(CodeGenFunction &CGF, const Expr *RefExpr) const
llvm::Constant * getValue() const
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
An RAII object to record that we're evaluating a statement expression.
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, const VarDecl *ConditionalDecl=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
ComplexPairTy EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre)
void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit)
EmitComplexExprIntoLValue - Emit the given expression of complex type and place its result into the s...
llvm::Type * ConvertType(QualType T)
ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc)
EmitLoadOfComplex - Load a complex number from the specified l-value.
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())
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)
See CGDebugInfo::addInstToCurrentSourceAtom.
llvm::Value * EmitPromotedScalarExpr(const Expr *E, QualType PromotionType)
const LangOptions & getLangOpts() const
LValue EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E)
ComplexPairTy EmitPromotedComplexExpr(const Expr *E, QualType PromotionType)
LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, llvm::Value *&Result)
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot(), llvm::CallBase **CallOrInvoke=nullptr)
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type,...
Address emitAddrOfImagComponent(Address complex, QualType complexType)
RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its RValue mapping if it exists, otherwise create one.
RValue EmitAtomicLoad(LValue LV, SourceLocation SL, AggValueSlot Slot=AggValueSlot::ignored())
CGDebugInfo * getDebugInfo()
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type,...
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,...
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
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...
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
EmitCompoundStmt - Emit a compound statement {..} node.
LValue EmitComplexAssignmentLValue(const BinaryOperator *E)
Emit an l-value for an assignment (simple or compound) of complex type.
llvm::Type * ConvertTypeForMem(QualType T)
RValue EmitAtomicExpr(AtomicExpr *E)
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
bool LValueIsSuitableForInlineAtomic(LValue Src)
An LValue is a candidate for having its loads and stores be made atomic if we are operating under /vo...
Address emitAddrOfRealComponent(Address complex, QualType complexType)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
ComplexPairTy EmitUnPromotedValue(ComplexPairTy result, QualType PromotionType)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit)
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
ConstantEmission tryEmitAsConstant(const DeclRefExpr *RefExpr)
Try to emit a reference to the given value without producing it as an l-value.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
llvm::LLVMContext & getLLVMContext()
ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType)
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...
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...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
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()
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const CGFunctionInfo & arrangeFreeFunctionCall(const CallArgList &Args, const FunctionType *Ty, bool ChainCall)
Figure out the rules for calling a function with the given formal type using the given arguments.
LValue - This represents an lvalue references.
bool isVolatileQualified() const
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.
QualType getComputationLHSType() const
QualType getComputationResultType() const
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
const Expr * getSubExpr() const
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...
SourceLocation getExprLoc() const LLVM_READONLY
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
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.
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool UseExcessPrecision(const ASTContext &Ctx)
Encodes a location in the source.
CompoundStmt * getSubStmt()
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
void dump() const
Dumps the specified AST fragment and all subtrees to llvm::errs().
Expr * getReplacement() const
virtual bool hasLongDoubleType() const
Determine whether the long double type is supported on this target.
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
const T * getAs() const
Member-template getAs<specific type>'.
Expr * getSubExpr() const
FPOptionsOverride getStoredFPFeaturesOrDefault() const
Get the store FPOptionsOverride or default if not stored.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ComplexType > complexType
bool Null(InterpState &S, CodePtr OpPC, uint64_t Value, 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.
U cast(CodeGen::Address addr)
@ EST_BasicNoexcept
noexcept
Diagnostic wrappers for TextAPI types for error reporting.
cl::opt< bool > EnableSingleByteCoverage
llvm::CallingConv::ID getRuntimeCC() const
static TBAAAccessInfo getMayAliasInfo()
ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &ESI)