35#include "llvm/ADT/APFixedPoint.h"
36#include "llvm/ADT/ScopeExit.h"
37#include "llvm/IR/Argument.h"
38#include "llvm/IR/CFG.h"
39#include "llvm/IR/Constants.h"
40#include "llvm/IR/DataLayout.h"
41#include "llvm/IR/DerivedTypes.h"
42#include "llvm/IR/FixedPointBuilder.h"
43#include "llvm/IR/Function.h"
44#include "llvm/IR/GEPNoWrapFlags.h"
45#include "llvm/IR/GetElementPtrTypeIterator.h"
46#include "llvm/IR/GlobalVariable.h"
47#include "llvm/IR/Intrinsics.h"
48#include "llvm/IR/IntrinsicsPowerPC.h"
49#include "llvm/IR/MatrixBuilder.h"
50#include "llvm/IR/Module.h"
51#include "llvm/Support/TypeSize.h"
74bool mayHaveIntegerOverflow(llvm::ConstantInt *LHS, llvm::ConstantInt *RHS,
76 llvm::APInt &Result) {
79 const auto &LHSAP = LHS->getValue();
80 const auto &RHSAP = RHS->getValue();
81 if (Opcode == BO_Add) {
82 Result =
Signed ? LHSAP.sadd_ov(RHSAP, Overflow)
83 : LHSAP.uadd_ov(RHSAP, Overflow);
84 }
else if (Opcode == BO_Sub) {
85 Result =
Signed ? LHSAP.ssub_ov(RHSAP, Overflow)
86 : LHSAP.usub_ov(RHSAP, Overflow);
87 }
else if (Opcode == BO_Mul) {
88 Result =
Signed ? LHSAP.smul_ov(RHSAP, Overflow)
89 : LHSAP.umul_ov(RHSAP, Overflow);
90 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
91 if (
Signed && !RHS->isZero())
92 Result = LHSAP.sdiv_ov(RHSAP, Overflow);
104 FPOptions FPFeatures;
108 bool mayHaveIntegerOverflow()
const {
110 auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
111 auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
112 if (!LHSCI || !RHSCI)
116 return ::mayHaveIntegerOverflow(
121 bool isDivremOp()
const {
127 bool mayHaveIntegerDivisionByZero()
const {
129 if (
auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
135 bool mayHaveFloatDivisionByZero()
const {
137 if (
auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
138 return CFP->isZero();
145 bool isFixedPointOp()
const {
148 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
149 QualType LHSType = BinOp->getLHS()->getType();
150 QualType RHSType = BinOp->getRHS()->getType();
153 if (
const auto *UnOp = dyn_cast<UnaryOperator>(E))
154 return UnOp->getSubExpr()->getType()->isFixedPointType();
159 bool rhsHasSignedIntegerRepresentation()
const {
160 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
161 QualType RHSType = BinOp->getRHS()->getType();
168static bool MustVisitNullValue(
const Expr *E) {
191static bool IsWidenedIntegerOp(
const ASTContext &Ctx,
const Expr *E) {
196static bool CanElideOverflowCheck(
const ASTContext &Ctx,
const BinOpInfo &Op) {
198 "Expected a unary or binary operator");
202 if (!Op.mayHaveIntegerOverflow())
205 if (Op.Ty->isSignedIntegerType() &&
211 if (Op.Ty->isUnsignedIntegerType() &&
232 if (BO->hasExcludedOverflowPattern())
248 if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
254 unsigned PromotedSize = Ctx.
getTypeSize(Op.E->getType());
255 return (2 * Ctx.
getTypeSize(LHSTy)) < PromotedSize ||
259class ScalarExprEmitter
261 CodeGenFunction &CGF;
262 CGBuilderTy &Builder;
263 bool IgnoreResultAssign;
264 llvm::LLVMContext &VMContext;
267 ScalarExprEmitter(CodeGenFunction &cgf,
bool ira=
false)
268 : CGF(cgf), Builder(CGF.Builder), IgnoreResultAssign(ira),
269 VMContext(cgf.getLLVMContext()) {
276 bool TestAndClearIgnoreResultAssign() {
277 bool I = IgnoreResultAssign;
278 IgnoreResultAssign =
false;
282 llvm::Type *ConvertType(QualType
T) {
return CGF.
ConvertType(
T); }
283 LValue EmitLValue(
const Expr *E) {
return CGF.
EmitLValue(E); }
289 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
290 const BinOpInfo &Info);
292 Value *EmitLoadOfLValue(LValue LV, SourceLocation Loc) {
296 void EmitLValueAlignmentAssumption(
const Expr *E,
Value *
V) {
297 const AlignValueAttr *AVAttr =
nullptr;
298 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
299 const ValueDecl *VD = DRE->getDecl();
302 if (
const auto *TTy =
304 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
314 AVAttr = VD->
getAttr<AlignValueAttr>();
319 if (
const auto *TTy = E->
getType()->
getAs<TypedefType>())
320 AVAttr = TTy->getDecl()->getAttr<AlignValueAttr>();
333 Value *EmitLoadOfLValue(
const Expr *E) {
337 EmitLValueAlignmentAssumption(E,
V);
343 Value *EmitConversionToBool(
Value *Src, QualType DstTy);
347 void EmitFloatConversionCheck(
Value *OrigSrc, QualType OrigSrcType,
348 Value *Src, QualType SrcType, QualType DstType,
349 llvm::Type *DstTy, SourceLocation Loc);
354 enum ImplicitConversionCheckKind :
unsigned char {
355 ICCK_IntegerTruncation = 0,
356 ICCK_UnsignedIntegerTruncation = 1,
357 ICCK_SignedIntegerTruncation = 2,
358 ICCK_IntegerSignChange = 3,
359 ICCK_SignedIntegerTruncationOrSignChange = 4,
364 void EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
Value *Dst,
365 QualType DstType, SourceLocation Loc);
370 void EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
Value *Dst,
371 QualType DstType, SourceLocation Loc);
375 struct ScalarConversionOpts {
376 bool TreatBooleanAsSigned;
377 bool EmitImplicitIntegerTruncationChecks;
378 bool EmitImplicitIntegerSignChangeChecks;
380 ScalarConversionOpts()
381 : TreatBooleanAsSigned(
false),
382 EmitImplicitIntegerTruncationChecks(
false),
383 EmitImplicitIntegerSignChangeChecks(
false) {}
385 ScalarConversionOpts(clang::SanitizerSet SanOpts)
386 : TreatBooleanAsSigned(
false),
387 EmitImplicitIntegerTruncationChecks(
388 SanOpts.hasOneOf(SanitizerKind::ImplicitIntegerTruncation)),
389 EmitImplicitIntegerSignChangeChecks(
390 SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange)) {}
392 Value *EmitScalarCast(
Value *Src, QualType SrcType, QualType DstType,
393 llvm::Type *SrcTy, llvm::Type *DstTy,
394 ScalarConversionOpts Opts);
396 EmitScalarConversion(
Value *Src, QualType SrcTy, QualType DstTy,
398 ScalarConversionOpts Opts = ScalarConversionOpts());
402 Value *EmitFixedPointConversion(
Value *Src, QualType SrcTy, QualType DstTy,
408 QualType SrcTy, QualType DstTy,
412 Value *EmitNullValue(QualType Ty);
417 llvm::Value *
Zero = llvm::Constant::getNullValue(
V->getType());
418 return Builder.CreateFCmpUNE(
V,
Zero,
"tobool");
422 Value *EmitPointerToBoolConversion(
Value *
V, QualType QT) {
425 return Builder.CreateICmpNE(
V,
Zero,
"tobool");
432 if (llvm::ZExtInst *ZI = dyn_cast<llvm::ZExtInst>(
V)) {
433 if (ZI->getOperand(0)->getType() == Builder.getInt1Ty()) {
439 ZI->eraseFromParent();
444 return Builder.CreateIsNotNull(
V,
"tobool");
451 Value *Visit(Expr *E) {
452 ApplyDebugLocation DL(CGF, E);
453 return StmtVisitor<ScalarExprEmitter, Value*>::Visit(E);
456 Value *VisitStmt(Stmt *S) {
458 llvm_unreachable(
"Stmt can't have complex result type!");
460 Value *VisitExpr(Expr *S);
462 Value *VisitConstantExpr(ConstantExpr *E) {
468 if (
Value *
Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
483 Value *VisitParenExpr(ParenExpr *PE) {
486 Value *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
489 Value *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
490 return Visit(
GE->getResultExpr());
492 Value *VisitCoawaitExpr(CoawaitExpr *S) {
495 Value *VisitCoyieldExpr(CoyieldExpr *S) {
498 Value *VisitUnaryCoawait(
const UnaryOperator *E) {
503 Value *VisitIntegerLiteral(
const IntegerLiteral *E) {
504 return Builder.getInt(E->
getValue());
506 Value *VisitFixedPointLiteral(
const FixedPointLiteral *E) {
507 return Builder.getInt(E->
getValue());
509 Value *VisitFloatingLiteral(
const FloatingLiteral *E) {
510 return llvm::ConstantFP::get(VMContext, E->
getValue());
512 Value *VisitCharacterLiteral(
const CharacterLiteral *E) {
515 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue(),
518 Value *VisitObjCBoolLiteralExpr(
const ObjCBoolLiteralExpr *E) {
519 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
521 Value *VisitCXXBoolLiteralExpr(
const CXXBoolLiteralExpr *E) {
522 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
524 Value *VisitCXXScalarValueInitExpr(
const CXXScalarValueInitExpr *E) {
528 return EmitNullValue(E->
getType());
530 Value *VisitGNUNullExpr(
const GNUNullExpr *E) {
531 return EmitNullValue(E->
getType());
533 Value *VisitOffsetOfExpr(OffsetOfExpr *E);
534 Value *VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E);
535 Value *VisitAddrLabelExpr(
const AddrLabelExpr *E) {
537 return Builder.CreateBitCast(
V, ConvertType(E->
getType()));
540 Value *VisitSizeOfPackExpr(SizeOfPackExpr *E) {
544 Value *VisitPseudoObjectExpr(PseudoObjectExpr *E) {
548 Value *VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E);
549 Value *VisitEmbedExpr(EmbedExpr *E);
551 Value *VisitOpaqueValueExpr(OpaqueValueExpr *E) {
560 Value *VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *E) {
561 llvm_unreachable(
"Codegen for this isn't defined/implemented");
565 Value *VisitDeclRefExpr(DeclRefExpr *E) {
568 return EmitLoadOfLValue(E);
571 Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
574 Value *VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
577 Value *VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
578 return EmitLoadOfLValue(E);
580 Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
583 return EmitLoadOfLValue(E);
587 Value *VisitObjCIsaExpr(ObjCIsaExpr *E) {
593 Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
599 return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
604 Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
605 Value *VisitMatrixSingleSubscriptExpr(MatrixSingleSubscriptExpr *E);
606 Value *VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E);
607 Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
608 Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
609 Value *VisitMemberExpr(MemberExpr *E);
610 Value *VisitExtVectorElementExpr(Expr *E) {
return EmitLoadOfLValue(E); }
611 Value *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
617 return EmitLoadOfLValue(E);
620 Value *VisitInitListExpr(InitListExpr *E);
622 Value *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
624 "ArrayInitIndexExpr not inside an ArrayInitLoopExpr?");
628 Value *VisitImplicitValueInitExpr(
const ImplicitValueInitExpr *E) {
629 return EmitNullValue(E->
getType());
631 Value *VisitExplicitCastExpr(ExplicitCastExpr *E) {
633 return VisitCastExpr(E);
637 Value *VisitCallExpr(
const CallExpr *E) {
639 return EmitLoadOfLValue(E);
643 EmitLValueAlignmentAssumption(E,
V);
647 Value *VisitStmtExpr(
const StmtExpr *E);
650 Value *VisitUnaryPostDec(
const UnaryOperator *E) {
652 return EmitScalarPrePostIncDec(E, LV,
false,
false);
654 Value *VisitUnaryPostInc(
const UnaryOperator *E) {
656 return EmitScalarPrePostIncDec(E, LV,
true,
false);
658 Value *VisitUnaryPreDec(
const UnaryOperator *E) {
660 return EmitScalarPrePostIncDec(E, LV,
false,
true);
662 Value *VisitUnaryPreInc(
const UnaryOperator *E) {
664 return EmitScalarPrePostIncDec(E, LV,
true,
true);
667 llvm::Value *EmitIncDecConsiderOverflowBehavior(
const UnaryOperator *E,
671 llvm::Value *EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
672 bool isInc,
bool isPre);
675 Value *VisitUnaryAddrOf(
const UnaryOperator *E) {
679 return EmitLValue(E->
getSubExpr()).getPointer(CGF);
681 Value *VisitUnaryDeref(
const UnaryOperator *E) {
684 return EmitLoadOfLValue(E);
687 Value *VisitUnaryPlus(
const UnaryOperator *E,
688 QualType PromotionType = QualType());
689 Value *VisitPlus(
const UnaryOperator *E, QualType PromotionType);
690 Value *VisitUnaryMinus(
const UnaryOperator *E,
691 QualType PromotionType = QualType());
692 Value *VisitMinus(
const UnaryOperator *E, QualType PromotionType);
694 Value *VisitUnaryNot (
const UnaryOperator *E);
695 Value *VisitUnaryLNot (
const UnaryOperator *E);
696 Value *VisitUnaryReal(
const UnaryOperator *E,
697 QualType PromotionType = QualType());
698 Value *VisitReal(
const UnaryOperator *E, QualType PromotionType);
699 Value *VisitUnaryImag(
const UnaryOperator *E,
700 QualType PromotionType = QualType());
701 Value *VisitImag(
const UnaryOperator *E, QualType PromotionType);
702 Value *VisitUnaryExtension(
const UnaryOperator *E) {
707 Value *VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *E) {
708 return EmitLoadOfLValue(E);
710 Value *VisitSourceLocExpr(SourceLocExpr *SLE) {
718 Value *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
719 CodeGenFunction::CXXDefaultArgExprScope Scope(CGF, DAE);
722 Value *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
723 CodeGenFunction::CXXDefaultInitExprScope Scope(CGF, DIE);
726 Value *VisitCXXThisExpr(CXXThisExpr *TE) {
730 Value *VisitExprWithCleanups(ExprWithCleanups *E);
731 Value *VisitCXXNewExpr(
const CXXNewExpr *E) {
734 Value *VisitCXXDeleteExpr(
const CXXDeleteExpr *E) {
739 Value *VisitTypeTraitExpr(
const TypeTraitExpr *E) {
741 return llvm::ConstantInt::get(ConvertType(E->
getType()),
744 return llvm::ConstantInt::get(ConvertType(E->
getType()),
748 Value *VisitConceptSpecializationExpr(
const ConceptSpecializationExpr *E) {
756 Value *VisitArrayTypeTraitExpr(
const ArrayTypeTraitExpr *E) {
757 return llvm::ConstantInt::get(ConvertType(E->
getType()), E->
getValue());
760 Value *VisitExpressionTraitExpr(
const ExpressionTraitExpr *E) {
761 return llvm::ConstantInt::get(Builder.getInt1Ty(), E->
getValue());
764 Value *VisitCXXPseudoDestructorExpr(
const CXXPseudoDestructorExpr *E) {
774 Value *VisitCXXNullPtrLiteralExpr(
const CXXNullPtrLiteralExpr *E) {
775 return EmitNullValue(E->
getType());
778 Value *VisitCXXThrowExpr(
const CXXThrowExpr *E) {
783 Value *VisitCXXNoexceptExpr(
const CXXNoexceptExpr *E) {
784 return Builder.getInt1(E->
getValue());
788 Value *EmitMul(
const BinOpInfo &Ops) {
789 if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
790 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
791 case LangOptions::SOB_Defined:
792 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
793 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
795 case LangOptions::SOB_Undefined:
796 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
797 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
799 case LangOptions::SOB_Trapping:
800 if (CanElideOverflowCheck(CGF.
getContext(), Ops))
801 return Builder.CreateNSWMul(Ops.LHS, Ops.RHS,
"mul");
802 return EmitOverflowCheckedBinOp(Ops);
806 if (Ops.Ty->isConstantMatrixType()) {
807 llvm::MatrixBuilder MB(Builder);
811 auto *LHSMatTy = dyn_cast<ConstantMatrixType>(
812 BO->getLHS()->getType().getCanonicalType());
813 auto *RHSMatTy = dyn_cast<ConstantMatrixType>(
814 BO->getRHS()->getType().getCanonicalType());
815 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
816 if (LHSMatTy && RHSMatTy)
817 return MB.CreateMatrixMultiply(Ops.LHS, Ops.RHS, LHSMatTy->getNumRows(),
818 LHSMatTy->getNumColumns(),
819 RHSMatTy->getNumColumns());
820 return MB.CreateScalarMultiply(Ops.LHS, Ops.RHS);
823 if (Ops.Ty->isUnsignedIntegerType() &&
824 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
825 !CanElideOverflowCheck(CGF.
getContext(), Ops))
826 return EmitOverflowCheckedBinOp(Ops);
828 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
830 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
831 return Builder.CreateFMul(Ops.LHS, Ops.RHS,
"mul");
833 if (Ops.isFixedPointOp())
834 return EmitFixedPointBinOp(Ops);
835 return Builder.CreateMul(Ops.LHS, Ops.RHS,
"mul");
839 Value *EmitOverflowCheckedBinOp(
const BinOpInfo &Ops);
842 void EmitUndefinedBehaviorIntegerDivAndRemCheck(
const BinOpInfo &Ops,
843 llvm::Value *
Zero,
bool isDiv);
845 static Value *GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
bool RHSIsSigned);
851 Value *EmitDiv(
const BinOpInfo &Ops);
852 Value *EmitRem(
const BinOpInfo &Ops);
853 Value *EmitAdd(
const BinOpInfo &Ops);
854 Value *EmitSub(
const BinOpInfo &Ops);
855 Value *EmitShl(
const BinOpInfo &Ops);
856 Value *EmitShr(
const BinOpInfo &Ops);
857 Value *EmitAnd(
const BinOpInfo &Ops) {
858 return Builder.CreateAnd(Ops.LHS, Ops.RHS,
"and");
860 Value *EmitXor(
const BinOpInfo &Ops) {
861 return Builder.CreateXor(Ops.LHS, Ops.RHS,
"xor");
863 Value *EmitOr (
const BinOpInfo &Ops) {
864 return Builder.CreateOr(Ops.LHS, Ops.RHS,
"or");
868 Value *EmitFixedPointBinOp(
const BinOpInfo &Ops);
870 BinOpInfo EmitBinOps(
const BinaryOperator *E,
871 QualType PromotionTy = QualType());
873 Value *EmitPromotedValue(
Value *result, QualType PromotionType);
874 Value *EmitUnPromotedValue(
Value *result, QualType ExprType);
875 Value *EmitPromoted(
const Expr *E, QualType PromotionType);
877 LValue EmitCompoundAssignLValue(
const CompoundAssignOperator *E,
878 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &),
881 Value *EmitCompoundAssign(
const CompoundAssignOperator *E,
882 Value *(ScalarExprEmitter::*F)(
const BinOpInfo &));
884 QualType getPromotionType(QualType Ty) {
886 if (
auto *CT = Ty->
getAs<ComplexType>()) {
887 QualType ElementType = CT->getElementType();
893 if (
auto *VT = Ty->
getAs<VectorType>()) {
894 unsigned NumElements = VT->getNumElements();
904#define HANDLEBINOP(OP) \
905 Value *VisitBin##OP(const BinaryOperator *E) { \
906 QualType promotionTy = getPromotionType(E->getType()); \
907 auto result = Emit##OP(EmitBinOps(E, promotionTy)); \
908 if (result && !promotionTy.isNull()) \
909 result = EmitUnPromotedValue(result, E->getType()); \
912 Value *VisitBin##OP##Assign(const CompoundAssignOperator *E) { \
913 ApplyAtomGroup Grp(CGF.getDebugInfo()); \
914 return EmitCompoundAssign(E, &ScalarExprEmitter::Emit##OP); \
930 llvm::CmpInst::Predicate SICmpOpc,
931 llvm::CmpInst::Predicate FCmpOpc,
bool IsSignaling);
932#define VISITCOMP(CODE, UI, SI, FP, SIG) \
933 Value *VisitBin##CODE(const BinaryOperator *E) { \
934 return EmitCompare(E, llvm::ICmpInst::UI, llvm::ICmpInst::SI, \
935 llvm::FCmpInst::FP, SIG); }
936 VISITCOMP(LT, ICMP_ULT, ICMP_SLT, FCMP_OLT,
true)
950 Value *VisitBinPtrMemD(
const Expr *E) {
return EmitLoadOfLValue(E); }
951 Value *VisitBinPtrMemI(
const Expr *E) {
return EmitLoadOfLValue(E); }
953 Value *VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator *E) {
958 Value *VisitBlockExpr(
const BlockExpr *BE);
959 Value *VisitAbstractConditionalOperator(
const AbstractConditionalOperator *);
960 Value *VisitChooseExpr(ChooseExpr *CE);
961 Value *VisitVAArgExpr(VAArgExpr *VE);
962 Value *VisitObjCStringLiteral(
const ObjCStringLiteral *E) {
965 Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
968 Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
971 Value *VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
974 Value *VisitAsTypeExpr(AsTypeExpr *CE);
975 Value *VisitAtomicExpr(AtomicExpr *AE);
976 Value *VisitPackIndexingExpr(PackIndexingExpr *E) {
989 assert(SrcType.
isCanonical() &&
"EmitScalarConversion strips typedefs");
992 return EmitFloatToBoolConversion(Src);
994 if (
const MemberPointerType *MPT = dyn_cast<MemberPointerType>(SrcType))
998 "Unknown scalar type to convert");
1001 return EmitIntToBoolConversion(Src);
1004 return EmitPointerToBoolConversion(Src, SrcType);
1007void ScalarExprEmitter::EmitFloatConversionCheck(
1008 Value *OrigSrc, QualType OrigSrcType,
Value *Src, QualType SrcType,
1009 QualType DstType, llvm::Type *DstTy, SourceLocation Loc) {
1010 assert(SrcType->
isFloatingType() &&
"not a conversion from floating point");
1014 auto CheckOrdinal = SanitizerKind::SO_FloatCastOverflow;
1015 auto CheckHandler = SanitizerHandler::FloatCastOverflow;
1016 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
1017 using llvm::APFloat;
1020 llvm::Value *Check =
nullptr;
1021 const llvm::fltSemantics &SrcSema =
1031 APFloat MinSrc(SrcSema, APFloat::uninitialized);
1032 if (MinSrc.convertFromAPInt(
Min, !
Unsigned, APFloat::rmTowardZero) &
1033 APFloat::opOverflow)
1036 MinSrc = APFloat::getInf(SrcSema,
true);
1040 MinSrc.subtract(
APFloat(SrcSema, 1), APFloat::rmTowardNegative);
1043 APFloat MaxSrc(SrcSema, APFloat::uninitialized);
1044 if (MaxSrc.convertFromAPInt(
Max, !
Unsigned, APFloat::rmTowardZero) &
1045 APFloat::opOverflow)
1048 MaxSrc = APFloat::getInf(SrcSema,
false);
1052 MaxSrc.add(
APFloat(SrcSema, 1), APFloat::rmTowardPositive);
1057 const llvm::fltSemantics &Sema =
1060 MinSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1061 MaxSrc.convert(Sema, APFloat::rmTowardZero, &IsInexact);
1065 Builder.CreateFCmpOGT(Src, llvm::ConstantFP::get(VMContext, MinSrc));
1067 Builder.CreateFCmpOLT(Src, llvm::ConstantFP::get(VMContext, MaxSrc));
1068 Check = Builder.CreateAnd(GE, LE);
1073 CGF.
EmitCheck(std::make_pair(Check, CheckOrdinal), CheckHandler, StaticArgs,
1079static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1080 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1083 llvm::Type *SrcTy = Src->
getType();
1084 llvm::Type *DstTy = Dst->
getType();
1089 assert(SrcTy->getScalarSizeInBits() > Dst->
getType()->getScalarSizeInBits());
1091 "non-integer llvm type");
1098 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1100 if (!SrcSigned && !DstSigned) {
1101 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1102 Ordinal = SanitizerKind::SO_ImplicitUnsignedIntegerTruncation;
1104 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1105 Ordinal = SanitizerKind::SO_ImplicitSignedIntegerTruncation;
1108 llvm::Value *Check =
nullptr;
1110 Check = Builder.CreateIntCast(Dst, SrcTy, DstSigned,
"anyext");
1112 Check = Builder.CreateICmpEQ(Check, Src,
"truncheck");
1114 return std::make_pair(Kind, std::make_pair(Check, Ordinal));
1122void ScalarExprEmitter::EmitIntegerTruncationCheck(
Value *Src, QualType SrcType,
1123 Value *Dst, QualType DstType,
1124 SourceLocation Loc) {
1134 unsigned SrcBits = Src->
getType()->getScalarSizeInBits();
1135 unsigned DstBits = Dst->
getType()->getScalarSizeInBits();
1137 if (SrcBits <= DstBits)
1140 assert(!DstType->
isBooleanType() &&
"we should not get here with booleans.");
1147 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitIntegerSignChange) &&
1148 (!SrcSigned && DstSigned))
1151 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1152 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1155 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1160 SanitizerDebugLocation SanScope(
1162 {SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1163 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1174 SanitizerDebugLocation SanScope(&CGF, {Check.second.second}, CheckHandler);
1181 llvm::Constant *StaticArgs[] = {
1184 llvm::ConstantInt::get(Builder.getInt8Ty(), Check.first),
1185 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1187 CGF.
EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1194 llvm::Type *VTy =
V->getType();
1197 return llvm::ConstantInt::getFalse(VTy->getContext());
1199 llvm::Constant *
Zero = llvm::ConstantInt::get(VTy, 0);
1200 return Builder.CreateICmp(llvm::ICmpInst::ICMP_SLT,
V,
Zero,
1201 llvm::Twine(Name) +
"." +
V->getName() +
1202 ".negativitycheck");
1207static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1208 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1211 llvm::Type *SrcTy = Src->
getType();
1212 llvm::Type *DstTy = Dst->
getType();
1215 "non-integer llvm type");
1221 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1222 unsigned DstBits = DstTy->getScalarSizeInBits();
1226 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1227 "either the widths should be different, or the signednesses.");
1230 llvm::Value *SrcIsNegative =
1233 llvm::Value *DstIsNegative =
1239 llvm::Value *Check =
nullptr;
1240 Check = Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"signchangecheck");
1242 return std::make_pair(
1243 ScalarExprEmitter::ICCK_IntegerSignChange,
1244 std::make_pair(Check, SanitizerKind::SO_ImplicitIntegerSignChange));
1247void ScalarExprEmitter::EmitIntegerSignChangeCheck(
Value *Src, QualType SrcType,
1248 Value *Dst, QualType DstType,
1249 SourceLocation Loc) {
1250 if (!CGF.
SanOpts.
has(SanitizerKind::SO_ImplicitIntegerSignChange))
1253 llvm::Type *SrcTy = Src->
getType();
1254 llvm::Type *DstTy = Dst->
getType();
1264 unsigned SrcBits = SrcTy->getScalarSizeInBits();
1265 unsigned DstBits = DstTy->getScalarSizeInBits();
1272 if (SrcSigned == DstSigned && SrcBits == DstBits)
1276 if (!SrcSigned && !DstSigned)
1281 if ((DstBits > SrcBits) && DstSigned)
1283 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1284 (SrcBits > DstBits) && SrcSigned) {
1293 SanitizerKind::ImplicitSignedIntegerTruncation, DstType))
1297 SanitizerKind::ImplicitUnsignedIntegerTruncation, DstType))
1301 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1302 SanitizerDebugLocation SanScope(
1304 {SanitizerKind::SO_ImplicitIntegerSignChange,
1305 SanitizerKind::SO_ImplicitUnsignedIntegerTruncation,
1306 SanitizerKind::SO_ImplicitSignedIntegerTruncation},
1309 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1310 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1314 ImplicitConversionCheckKind CheckKind;
1315 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
1322 CheckKind = Check.first;
1323 Checks.emplace_back(Check.second);
1325 if (CGF.
SanOpts.
has(SanitizerKind::ImplicitSignedIntegerTruncation) &&
1326 (SrcBits > DstBits) && !SrcSigned && DstSigned) {
1332 CheckKind = ICCK_SignedIntegerTruncationOrSignChange;
1333 Checks.emplace_back(Check.second);
1337 llvm::Constant *StaticArgs[] = {
1340 llvm::ConstantInt::get(Builder.getInt8Ty(), CheckKind),
1341 llvm::ConstantInt::get(Builder.getInt32Ty(), 0)};
1343 CGF.
EmitCheck(Checks, CheckHandler, StaticArgs, {Src, Dst});
1348static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1349 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1355 ScalarExprEmitter::ImplicitConversionCheckKind Kind;
1356 if (!SrcSigned && !DstSigned)
1357 Kind = ScalarExprEmitter::ICCK_UnsignedIntegerTruncation;
1359 Kind = ScalarExprEmitter::ICCK_SignedIntegerTruncation;
1361 llvm::Value *Check =
nullptr;
1363 Check = Builder.CreateIntCast(Dst, Src->
getType(), DstSigned,
"bf.anyext");
1365 Check = Builder.CreateICmpEQ(Check, Src,
"bf.truncheck");
1368 return std::make_pair(
1370 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1375static std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1376 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1380 llvm::Value *SrcIsNegative =
1383 llvm::Value *DstIsNegative =
1389 llvm::Value *Check =
nullptr;
1391 Builder.CreateICmpEQ(SrcIsNegative, DstIsNegative,
"bf.signchangecheck");
1393 return std::make_pair(
1394 ScalarExprEmitter::ICCK_IntegerSignChange,
1395 std::make_pair(Check, SanitizerKind::SO_ImplicitBitfieldConversion));
1403 if (!
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
1421 unsigned SrcBits =
ConvertType(SrcType)->getScalarSizeInBits();
1422 unsigned DstBits = Info.
Size;
1427 auto CheckHandler = SanitizerHandler::ImplicitConversion;
1429 this, {SanitizerKind::SO_ImplicitBitfieldConversion}, CheckHandler);
1431 std::pair<ScalarExprEmitter::ImplicitConversionCheckKind,
1432 std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>>
1436 bool EmitTruncation = DstBits < SrcBits;
1440 bool EmitTruncationFromUnsignedToSigned =
1441 EmitTruncation && DstSigned && !SrcSigned;
1443 bool SameTypeSameSize = SrcSigned == DstSigned && SrcBits == DstBits;
1444 bool BothUnsigned = !SrcSigned && !DstSigned;
1445 bool LargerSigned = (DstBits > SrcBits) && DstSigned;
1452 bool EmitSignChange = !SameTypeSameSize && !BothUnsigned && !LargerSigned;
1457 else if (EmitSignChange) {
1458 assert(((SrcBits != DstBits) || (SrcSigned != DstSigned)) &&
1459 "either the widths should be different, or the signednesses.");
1465 ScalarExprEmitter::ImplicitConversionCheckKind CheckKind = Check.first;
1466 if (EmitTruncationFromUnsignedToSigned)
1467 CheckKind = ScalarExprEmitter::ICCK_SignedIntegerTruncationOrSignChange;
1469 llvm::Constant *StaticArgs[] = {
1472 llvm::ConstantInt::get(
Builder.getInt8Ty(), CheckKind),
1473 llvm::ConstantInt::get(
Builder.getInt32Ty(), Info.
Size)};
1475 EmitCheck(Check.second, CheckHandler, StaticArgs, {Src, Dst});
1479 QualType DstType, llvm::Type *SrcTy,
1481 ScalarConversionOpts Opts) {
1483 llvm::Type *SrcElementTy;
1484 llvm::Type *DstElementTy;
1494 "cannot cast between matrix and non-matrix types");
1495 SrcElementTy = SrcTy;
1496 DstElementTy = DstTy;
1497 SrcElementType = SrcType;
1498 DstElementType = DstType;
1503 if (SrcElementType->
isBooleanType() && Opts.TreatBooleanAsSigned) {
1508 return Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
1510 return Builder.CreateSIToFP(Src, DstTy,
"conv");
1511 return Builder.CreateUIToFP(Src, DstTy,
"conv");
1515 assert(SrcElementTy->isFloatingPointTy() &&
"Unknown real conversion");
1522 llvm::Intrinsic::ID IID =
1523 IsSigned ? llvm::Intrinsic::fptosi_sat : llvm::Intrinsic::fptoui_sat;
1524 return Builder.CreateCall(CGF.
CGM.
getIntrinsic(IID, {DstTy, SrcTy}), Src);
1528 return Builder.CreateFPToSI(Src, DstTy,
"conv");
1529 return Builder.CreateFPToUI(Src, DstTy,
"conv");
1532 if ((DstElementTy->is16bitFPTy() && SrcElementTy->is16bitFPTy())) {
1533 Value *FloatVal = Builder.CreateFPExt(Src, Builder.getFloatTy(),
"fpext");
1534 return Builder.CreateFPTrunc(FloatVal, DstTy,
"fptrunc");
1536 if (DstElementTy->getTypeID() < SrcElementTy->getTypeID())
1537 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1538 return Builder.CreateFPExt(Src, DstTy,
"conv");
1543Value *ScalarExprEmitter::EmitScalarConversion(
Value *Src, QualType SrcType,
1546 ScalarConversionOpts Opts) {
1561 return Builder.CreateIsNotNull(Src,
"tobool");
1564 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1567 "Unhandled scalar conversion from a fixed point type to another type.");
1571 return EmitFixedPointConversion(Src, SrcType, DstType, Loc);
1574 "Unhandled scalar conversion to a fixed point type from another type.");
1577 QualType NoncanonicalSrcType = SrcType;
1578 QualType NoncanonicalDstType = DstType;
1582 if (SrcType == DstType)
return Src;
1586 llvm::Value *OrigSrc = Src;
1587 QualType OrigSrcType = SrcType;
1588 llvm::Type *SrcTy = Src->
getType();
1592 return EmitConversionToBool(Src, SrcType);
1594 llvm::Type *DstTy = ConvertType(DstType);
1599 if (DstTy->isFloatingPointTy()) {
1601 return Builder.CreateCall(
1609 Src = Builder.CreateCall(
1614 Src = Builder.CreateFPExt(Src, CGF.
CGM.
FloatTy,
"conv");
1622 if (SrcTy == DstTy) {
1623 if (Opts.EmitImplicitIntegerSignChangeChecks)
1624 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Src,
1625 NoncanonicalDstType, Loc);
1633 if (
auto DstPT = dyn_cast<llvm::PointerType>(DstTy)) {
1638 assert(SrcType->
isIntegerType() &&
"Not ptr->ptr or int->ptr conversion?");
1643 llvm::Value* IntResult =
1644 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
1646 return Builder.CreateIntToPtr(IntResult, DstTy,
"conv");
1652 return Builder.CreatePtrToInt(Src, DstTy,
"conv");
1659 assert(DstType->
castAs<ExtVectorType>()->getElementType().getTypePtr() ==
1661 "Splatted expr doesn't match with vector element type?");
1665 return Builder.CreateVectorSplat(NumElements, Src,
"splat");
1669 return EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1673 llvm::TypeSize SrcSize = SrcTy->getPrimitiveSizeInBits();
1674 llvm::TypeSize DstSize = DstTy->getPrimitiveSizeInBits();
1675 if (SrcSize == DstSize)
1676 return Builder.CreateBitCast(Src, DstTy,
"conv");
1689 assert(((SrcElementTy->isIntegerTy() &&
1690 DstElementTy->isIntegerTy()) ||
1691 (SrcElementTy->isFloatingPointTy() &&
1692 DstElementTy->isFloatingPointTy())) &&
1693 "unexpected conversion between a floating-point vector and an "
1697 if (SrcElementTy->isIntegerTy())
1698 return Builder.CreateIntCast(Src, DstTy,
false,
"conv");
1701 if (SrcSize > DstSize)
1702 return Builder.CreateFPTrunc(Src, DstTy,
"conv");
1705 return Builder.CreateFPExt(Src, DstTy,
"conv");
1709 Value *Res =
nullptr;
1710 llvm::Type *ResTy = DstTy;
1717 if (CGF.
SanOpts.
has(SanitizerKind::FloatCastOverflow) &&
1719 EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, DstTy,
1725 if (SrcTy->isFloatingPointTy()) {
1729 return Builder.CreateCall(
1732 return Builder.CreateFPTrunc(Src, DstTy);
1737 Res = EmitScalarCast(Src, SrcType, DstType, SrcTy, DstTy, Opts);
1739 if (DstTy != ResTy) {
1741 assert(ResTy->isIntegerTy(16) &&
"Only half FP requires extra conversion");
1742 Res = Builder.CreateCall(
1746 Res = Builder.CreateFPTrunc(Res, ResTy,
"conv");
1750 if (Opts.EmitImplicitIntegerTruncationChecks)
1751 EmitIntegerTruncationCheck(Src, NoncanonicalSrcType, Res,
1752 NoncanonicalDstType, Loc);
1754 if (Opts.EmitImplicitIntegerSignChangeChecks)
1755 EmitIntegerSignChangeCheck(Src, NoncanonicalSrcType, Res,
1756 NoncanonicalDstType, Loc);
1761Value *ScalarExprEmitter::EmitFixedPointConversion(
Value *Src, QualType SrcTy,
1763 SourceLocation Loc) {
1764 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
1767 Result = FPBuilder.CreateFloatingToFixed(Src,
1770 Result = FPBuilder.CreateFixedToFloating(Src,
1772 ConvertType(DstTy));
1778 Result = FPBuilder.CreateFixedToInteger(Src, SrcFPSema,
1779 DstFPSema.getWidth(),
1780 DstFPSema.isSigned());
1782 Result = FPBuilder.CreateIntegerToFixed(Src, SrcFPSema.isSigned(),
1785 Result = FPBuilder.CreateFixedToFixed(Src, SrcFPSema, DstFPSema);
1792Value *ScalarExprEmitter::EmitComplexToScalarConversion(
1794 SourceLocation Loc) {
1796 SrcTy = SrcTy->
castAs<ComplexType>()->getElementType();
1801 Src.first = EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1802 Src.second = EmitScalarConversion(Src.second, SrcTy, DstTy, Loc);
1803 return Builder.CreateOr(Src.first, Src.second,
"tobool");
1810 return EmitScalarConversion(Src.first, SrcTy, DstTy, Loc);
1813Value *ScalarExprEmitter::EmitNullValue(QualType Ty) {
1821void ScalarExprEmitter::EmitBinOpCheck(
1822 ArrayRef<std::pair<Value *, SanitizerKind::SanitizerOrdinal>> Checks,
1823 const BinOpInfo &Info) {
1826 SmallVector<llvm::Constant *, 4> StaticData;
1827 SmallVector<llvm::Value *, 2> DynamicData;
1835 const UnaryOperator *UO = dyn_cast<UnaryOperator>(Info.E);
1836 if (UO && UO->
getOpcode() == UO_Minus) {
1837 Check = SanitizerHandler::NegateOverflow;
1839 DynamicData.push_back(Info.RHS);
1843 Check = SanitizerHandler::ShiftOutOfBounds;
1845 StaticData.push_back(
1847 StaticData.push_back(
1849 }
else if (Opcode == BO_Div || Opcode == BO_Rem) {
1851 Check = SanitizerHandler::DivremOverflow;
1855 int ArithOverflowKind = 0;
1858 Check = SanitizerHandler::AddOverflow;
1859 ArithOverflowKind = diag::UBSanArithKind::Add;
1863 Check = SanitizerHandler::SubOverflow;
1864 ArithOverflowKind = diag::UBSanArithKind::Sub;
1868 Check = SanitizerHandler::MulOverflow;
1869 ArithOverflowKind = diag::UBSanArithKind::Mul;
1873 llvm_unreachable(
"unexpected opcode for bin op check");
1877 SanitizerKind::UnsignedIntegerOverflow) ||
1879 SanitizerKind::SignedIntegerOverflow)) {
1883 << Info.Ty->isSignedIntegerOrEnumerationType() << ArithOverflowKind
1887 DynamicData.push_back(Info.LHS);
1888 DynamicData.push_back(Info.RHS);
1891 CGF.
EmitCheck(Checks, Check, StaticData, DynamicData, &TR);
1898Value *ScalarExprEmitter::VisitExpr(Expr *E) {
1906ScalarExprEmitter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
1908 unsigned AddrSpace =
1910 llvm::Constant *GlobalConstStr = Builder.CreateGlobalString(
1913 llvm::Type *ExprTy = ConvertType(E->
getType());
1914 return Builder.CreatePointerBitCastOrAddrSpaceCast(GlobalConstStr, ExprTy,
1918Value *ScalarExprEmitter::VisitEmbedExpr(EmbedExpr *E) {
1920 auto It = E->
begin();
1921 return Builder.getInt((*It)->getValue());
1924Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
1932 unsigned LHSElts = LTy->getNumElements();
1940 llvm::ConstantInt::get(MTy, llvm::NextPowerOf2(LHSElts - 1) - 1);
1941 Mask = Builder.CreateAnd(Mask, MaskBits,
"mask");
1949 auto *RTy = llvm::FixedVectorType::get(LTy->getElementType(),
1950 MTy->getNumElements());
1951 Value* NewV = llvm::PoisonValue::get(RTy);
1952 for (
unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
1953 Value *IIndx = llvm::ConstantInt::get(CGF.
SizeTy, i);
1954 Value *Indx = Builder.CreateExtractElement(Mask, IIndx,
"shuf_idx");
1956 Value *VExt = Builder.CreateExtractElement(LHS, Indx,
"shuf_elt");
1957 NewV = Builder.CreateInsertElement(NewV, VExt, IIndx,
"shuf_ins");
1965 SmallVector<int, 32> Indices;
1969 if (Idx.isSigned() && Idx.isAllOnes())
1970 Indices.push_back(-1);
1972 Indices.push_back(Idx.getZExtValue());
1975 return Builder.CreateShuffleVector(V1, V2, Indices,
"shuffle");
1978Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
1986 if (SrcType == DstType)
return Src;
1989 "ConvertVector source type must be a vector");
1991 "ConvertVector destination type must be a vector");
1993 llvm::Type *SrcTy = Src->
getType();
1994 llvm::Type *DstTy = ConvertType(DstType);
2000 QualType SrcEltType = SrcType->
castAs<VectorType>()->getElementType(),
2001 DstEltType = DstType->
castAs<VectorType>()->getElementType();
2003 assert(SrcTy->isVectorTy() &&
2004 "ConvertVector source IR type must be a vector");
2005 assert(DstTy->isVectorTy() &&
2006 "ConvertVector destination IR type must be a vector");
2011 if (DstEltType->isBooleanType()) {
2012 assert((SrcEltTy->isFloatingPointTy() ||
2015 llvm::Value *
Zero = llvm::Constant::getNullValue(SrcTy);
2016 if (SrcEltTy->isFloatingPointTy()) {
2017 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2018 return Builder.CreateFCmpUNE(Src,
Zero,
"tobool");
2020 return Builder.CreateICmpNE(Src,
Zero,
"tobool");
2025 Value *Res =
nullptr;
2030 Res = Builder.CreateIntCast(Src, DstTy, InputSigned,
"conv");
2032 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2034 Res = Builder.CreateSIToFP(Src, DstTy,
"conv");
2036 Res = Builder.CreateUIToFP(Src, DstTy,
"conv");
2039 assert(SrcEltTy->isFloatingPointTy() &&
"Unknown real conversion");
2040 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2041 if (DstEltType->isSignedIntegerOrEnumerationType())
2042 Res = Builder.CreateFPToSI(Src, DstTy,
"conv");
2044 Res = Builder.CreateFPToUI(Src, DstTy,
"conv");
2046 assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
2047 "Unknown real conversion");
2048 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
2049 if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
2050 Res = Builder.CreateFPTrunc(Src, DstTy,
"conv");
2052 Res = Builder.CreateFPExt(Src, DstTy,
"conv");
2058Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
2067 return Builder.getInt(
Value);
2071 llvm::Value *
Result = EmitLoadOfLValue(E);
2077 if (llvm::LoadInst *Load = dyn_cast<llvm::LoadInst>(
Result)) {
2078 if (llvm::GetElementPtrInst *GEP =
2079 dyn_cast<llvm::GetElementPtrInst>(
Load->getPointerOperand())) {
2080 if (llvm::Instruction *
Pointer =
2081 dyn_cast<llvm::Instruction>(GEP->getPointerOperand())) {
2093Value *ScalarExprEmitter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
2094 TestAndClearIgnoreResultAssign();
2102 return EmitLoadOfLValue(E);
2110 if (CGF.
SanOpts.
has(SanitizerKind::ArrayBounds))
2113 return Builder.CreateExtractElement(Base, Idx,
"vecext");
2116Value *ScalarExprEmitter::VisitMatrixSingleSubscriptExpr(
2117 MatrixSingleSubscriptExpr *E) {
2118 TestAndClearIgnoreResultAssign();
2121 unsigned NumRows = MatrixTy->getNumRows();
2122 unsigned NumColumns = MatrixTy->getNumColumns();
2126 llvm::MatrixBuilder MB(Builder);
2130 MB.CreateIndexAssumption(RowIdx, NumRows);
2133 llvm::Type *ElemTy = CGF.
ConvertType(MatrixTy->getElementType());
2134 auto *ResultTy = llvm::FixedVectorType::get(ElemTy, NumColumns);
2135 Value *RowVec = llvm::PoisonValue::get(ResultTy);
2137 for (
unsigned Col = 0; Col != NumColumns; ++Col) {
2138 Value *ColVal = llvm::ConstantInt::get(RowIdx->
getType(), Col);
2139 bool IsMatrixRowMajor = CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
2140 LangOptions::MatrixMemoryLayout::MatrixRowMajor;
2141 Value *EltIdx = MB.CreateIndex(RowIdx, ColVal, NumRows, NumColumns,
2142 IsMatrixRowMajor,
"matrix_row_idx");
2144 Builder.CreateExtractElement(FlatMatrix, EltIdx,
"matrix_elem");
2145 Value *Lane = llvm::ConstantInt::get(Builder.getInt32Ty(), Col);
2146 RowVec = Builder.CreateInsertElement(RowVec, Elt, Lane,
"matrix_row_ins");
2152Value *ScalarExprEmitter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
2153 TestAndClearIgnoreResultAssign();
2161 llvm::MatrixBuilder MB(Builder);
2164 unsigned NumCols = MatrixTy->getNumColumns();
2165 unsigned NumRows = MatrixTy->getNumRows();
2166 bool IsMatrixRowMajor = CGF.
getLangOpts().getDefaultMatrixMemoryLayout() ==
2167 LangOptions::MatrixMemoryLayout::MatrixRowMajor;
2168 Idx = MB.CreateIndex(RowIdx, ColumnIdx, NumRows, NumCols, IsMatrixRowMajor);
2171 MB.CreateIndexAssumption(Idx, MatrixTy->getNumElementsFlattened());
2176 return Builder.CreateExtractElement(Matrix, Idx,
"matrixext");
2181 int MV = SVI->getMaskValue(Idx);
2188 assert(llvm::ConstantInt::isValueValidForType(I32Ty,
C->getZExtValue()) &&
2189 "Index operand too large for shufflevector mask!");
2190 return C->getZExtValue();
2193Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
2194 bool Ignore = TestAndClearIgnoreResultAssign();
2197 assert((Ignore ==
false ||
2199 "init list ignored");
2216 llvm::VectorType *VType =
2217 dyn_cast<llvm::VectorType>(ConvertType(E->
getType()));
2220 if (NumInitElements == 0) {
2222 return EmitNullValue(E->
getType());
2229 if (NumInitElements == 0) {
2231 return EmitNullValue(E->
getType());
2234 if (NumInitElements == 1) {
2235 Expr *InitVector = E->
getInit(0);
2240 return Visit(InitVector);
2243 llvm_unreachable(
"Unexpected initialization of a scalable vector!");
2253 unsigned CurIdx = 0;
2254 bool VIsPoisonShuffle =
false;
2255 llvm::Value *
V = llvm::PoisonValue::get(VType);
2256 for (
unsigned i = 0; i != NumInitElements; ++i) {
2259 SmallVector<int, 16> Args;
2261 llvm::VectorType *VVT = dyn_cast<llvm::VectorType>(
Init->getType());
2271 ->getNumElements() == ResElts) {
2273 Value *LHS =
nullptr, *RHS =
nullptr;
2278 Args.resize(ResElts, -1);
2280 LHS = EI->getVectorOperand();
2282 VIsPoisonShuffle =
true;
2283 }
else if (VIsPoisonShuffle) {
2286 for (
unsigned j = 0; j != CurIdx; ++j)
2288 Args.push_back(ResElts +
C->getZExtValue());
2289 Args.resize(ResElts, -1);
2292 RHS = EI->getVectorOperand();
2293 VIsPoisonShuffle =
false;
2295 if (!Args.empty()) {
2296 V = Builder.CreateShuffleVector(LHS, RHS, Args);
2302 V = Builder.CreateInsertElement(
V,
Init, Builder.getInt32(CurIdx),
2304 VIsPoisonShuffle =
false;
2314 unsigned Offset = (CurIdx == 0) ? 0 : ResElts;
2317 Value *SVOp = SVI->getOperand(0);
2320 if (OpTy->getNumElements() == ResElts) {
2321 for (
unsigned j = 0; j != CurIdx; ++j) {
2324 if (VIsPoisonShuffle) {
2330 for (
unsigned j = 0, je = InitElts; j != je; ++j)
2332 Args.resize(ResElts, -1);
2334 if (VIsPoisonShuffle)
2344 for (
unsigned j = 0; j != InitElts; ++j)
2346 Args.resize(ResElts, -1);
2347 Init = Builder.CreateShuffleVector(
Init, Args,
"vext");
2350 for (
unsigned j = 0; j != CurIdx; ++j)
2352 for (
unsigned j = 0; j != InitElts; ++j)
2353 Args.push_back(j + Offset);
2354 Args.resize(ResElts, -1);
2361 V = Builder.CreateShuffleVector(
V,
Init, Args,
"vecinit");
2368 llvm::Type *EltTy = VType->getElementType();
2371 for (; CurIdx < ResElts; ++CurIdx) {
2372 Value *Idx = Builder.getInt32(CurIdx);
2373 llvm::Value *
Init = llvm::Constant::getNullValue(EltTy);
2374 V = Builder.CreateInsertElement(
V,
Init, Idx,
"vecinit");
2386 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2390 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
2393 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
2412 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2416 if (
const auto *CE = dyn_cast<CastExpr>(E))
2417 if (CE->getCastKind() == CK_FunctionToPointerDecay ||
2418 CE->getCastKind() == CK_ArrayToPointerDecay)
2429 if (CE->
getCastKind() == CK_UncheckedDerivedToBase)
2439 if (ICE->isGLValue())
2454 assert(LoadList.size() >= VecTy->getNumElements() &&
2455 "Flattened type on RHS must have the same number or more elements "
2456 "than vector on LHS.");
2460 for (
unsigned I = 0, E = VecTy->getNumElements(); I < E; I++) {
2463 "All flattened source values should be scalars.");
2466 VecTy->getElementType(), Loc);
2467 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2472 assert(LoadList.size() >= MatTy->getNumElementsFlattened() &&
2473 "Flattened type on RHS must have the same number or more elements "
2474 "than vector on LHS.");
2479 for (
unsigned I = 0, E = MatTy->getNumElementsFlattened(); I < E; I++) {
2480 unsigned ColMajorIndex =
2481 (I % MatTy->getNumRows()) * MatTy->getNumColumns() +
2482 (I / MatTy->getNumRows());
2485 "All flattened source values should be scalars.");
2487 RVal.
getScalarVal(), LoadList[ColMajorIndex].getType(),
2488 MatTy->getElementType(), Loc);
2489 V = CGF.
Builder.CreateInsertElement(
V, Cast, I);
2495 "Destination type must be a vector, matrix, or builtin type.");
2497 assert(RVal.
isScalar() &&
"All flattened source values should be scalars.");
2506 llvm::scope_exit RestoreCurCast(
2507 [
this, Prev = CGF.
CurCast] { CGF.CurCast = Prev; });
2511 QualType DestTy = CE->
getType();
2513 CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, CE);
2517 bool Ignored = TestAndClearIgnoreResultAssign();
2523 case CK_Dependent: llvm_unreachable(
"dependent cast kind in IR gen!");
2524 case CK_BuiltinFnToFnPtr:
2525 llvm_unreachable(
"builtin functions are handled elsewhere");
2527 case CK_LValueBitCast:
2528 case CK_ObjCObjectLValueCast: {
2529 Address
Addr = EmitLValue(E).getAddress();
2532 return EmitLoadOfLValue(LV, CE->
getExprLoc());
2535 case CK_LValueToRValueBitCast: {
2541 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2544 case CK_CPointerToObjCPointerCast:
2545 case CK_BlockPointerToObjCPointerCast:
2546 case CK_AnyPointerToBlockPointerCast:
2548 Value *Src = Visit(E);
2549 llvm::Type *SrcTy = Src->
getType();
2550 llvm::Type *DstTy = ConvertType(DestTy);
2561 if (
auto A = dyn_cast<llvm::Argument>(Src); A && A->hasStructRetAttr())
2566 (!SrcTy->isPtrOrPtrVectorTy() || !DstTy->isPtrOrPtrVectorTy() ||
2567 SrcTy->getPointerAddressSpace() == DstTy->getPointerAddressSpace()) &&
2568 "Address-space cast must be used to convert address spaces");
2570 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
2571 if (
auto *PT = DestTy->
getAs<PointerType>()) {
2573 PT->getPointeeType(),
2584 const QualType SrcType = E->
getType();
2589 Src = Builder.CreateLaunderInvariantGroup(Src);
2597 Src = Builder.CreateStripInvariantGroup(Src);
2602 if (
auto *CI = dyn_cast<llvm::CallBase>(Src)) {
2606 if (!PointeeType.
isNull())
2615 if (
auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2616 if (
auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2619 if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
2620 FixedSrcTy->getElementType()->isIntegerTy(8)) {
2621 ScalableDstTy = llvm::ScalableVectorType::get(
2622 FixedSrcTy->getElementType(),
2624 ScalableDstTy->getElementCount().getKnownMinValue(), 8));
2626 if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) {
2627 llvm::Value *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
2628 llvm::Value *
Result = Builder.CreateInsertVector(
2629 ScalableDstTy, PoisonVec, Src,
uint64_t(0),
"cast.scalable");
2631 llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, DstTy));
2632 if (
Result->getType() != ScalableDstTy)
2634 if (
Result->getType() != DstTy)
2644 if (
auto *ScalableSrcTy = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2645 if (
auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2648 if (ScalableSrcTy->getElementType()->isIntegerTy(1) &&
2649 FixedDstTy->getElementType()->isIntegerTy(8)) {
2650 if (!ScalableSrcTy->getElementCount().isKnownMultipleOf(8)) {
2651 ScalableSrcTy = llvm::ScalableVectorType::get(
2652 ScalableSrcTy->getElementType(),
2654 ScalableSrcTy->getElementCount().getKnownMinValue()));
2655 llvm::Value *ZeroVec = llvm::Constant::getNullValue(ScalableSrcTy);
2656 Src = Builder.CreateInsertVector(ScalableSrcTy, ZeroVec, Src,
2660 ScalableSrcTy = llvm::ScalableVectorType::get(
2661 FixedDstTy->getElementType(),
2662 ScalableSrcTy->getElementCount().getKnownMinValue() / 8);
2663 Src = Builder.CreateBitCast(Src, ScalableSrcTy);
2665 if (ScalableSrcTy->getElementType() == FixedDstTy->getElementType())
2666 return Builder.CreateExtractVector(DstTy, Src,
uint64_t(0),
2687 return EmitLoadOfLValue(DestLV, CE->
getExprLoc());
2690 llvm::Value *
Result = Builder.CreateBitCast(Src, DstTy);
2693 case CK_AddressSpaceConversion: {
2696 Result.Val.isNullPointer()) {
2700 if (
Result.HasSideEffects)
2703 ConvertType(DestTy)), DestTy);
2709 ConvertType(DestTy));
2711 case CK_AtomicToNonAtomic:
2712 case CK_NonAtomicToAtomic:
2713 case CK_UserDefinedConversion:
2720 case CK_BaseToDerived: {
2722 assert(DerivedClassDecl &&
"BaseToDerived arg isn't a C++ object pointer!");
2736 if (CGF.
SanOpts.
has(SanitizerKind::CFIDerivedCast))
2744 case CK_UncheckedDerivedToBase:
2745 case CK_DerivedToBase: {
2758 case CK_ArrayToPointerDecay:
2761 case CK_FunctionToPointerDecay:
2762 return EmitLValue(E).getPointer(CGF);
2764 case CK_NullToPointer:
2765 if (MustVisitNullValue(E))
2771 case CK_NullToMemberPointer: {
2772 if (MustVisitNullValue(E))
2775 const MemberPointerType *MPT = CE->
getType()->
getAs<MemberPointerType>();
2779 case CK_ReinterpretMemberPointer:
2780 case CK_BaseToDerivedMemberPointer:
2781 case CK_DerivedToBaseMemberPointer: {
2782 Value *Src = Visit(E);
2793 case CK_ARCProduceObject:
2795 case CK_ARCConsumeObject:
2797 case CK_ARCReclaimReturnedObject:
2799 case CK_ARCExtendBlockObject:
2802 case CK_CopyAndAutoreleaseBlockObject:
2805 case CK_FloatingRealToComplex:
2806 case CK_FloatingComplexCast:
2807 case CK_IntegralRealToComplex:
2808 case CK_IntegralComplexCast:
2809 case CK_IntegralComplexToFloatingComplex:
2810 case CK_FloatingComplexToIntegralComplex:
2811 case CK_ConstructorConversion:
2813 case CK_HLSLArrayRValue:
2814 llvm_unreachable(
"scalar cast to non-scalar value");
2816 case CK_LValueToRValue:
2818 assert(E->
isGLValue() &&
"lvalue-to-rvalue applied to r-value!");
2821 case CK_IntegralToPointer: {
2822 Value *Src = Visit(E);
2826 auto DestLLVMTy = ConvertType(DestTy);
2829 llvm::Value* IntResult =
2830 Builder.CreateIntCast(Src, MiddleTy, InputSigned,
"conv");
2832 auto *IntToPtr = Builder.CreateIntToPtr(IntResult, DestLLVMTy);
2838 IntToPtr = Builder.CreateLaunderInvariantGroup(IntToPtr);
2844 case CK_PointerToIntegral: {
2845 assert(!DestTy->
isBooleanType() &&
"bool should use PointerToBool");
2846 auto *PtrExpr = Visit(E);
2849 const QualType SrcType = E->
getType();
2854 PtrExpr = Builder.CreateStripInvariantGroup(PtrExpr);
2858 return Builder.CreatePtrToInt(PtrExpr, ConvertType(DestTy));
2864 case CK_MatrixCast: {
2865 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2872 case CK_HLSLAggregateSplatCast:
2873 case CK_VectorSplat: {
2874 llvm::Type *DstTy = ConvertType(DestTy);
2875 Value *Elt = Visit(E);
2877 llvm::ElementCount NumElements =
2879 return Builder.CreateVectorSplat(NumElements, Elt,
"splat");
2882 case CK_FixedPointCast:
2883 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2886 case CK_FixedPointToBoolean:
2888 "Expected src type to be fixed point type");
2889 assert(DestTy->
isBooleanType() &&
"Expected dest type to be boolean type");
2890 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2893 case CK_FixedPointToIntegral:
2895 "Expected src type to be fixed point type");
2896 assert(DestTy->
isIntegerType() &&
"Expected dest type to be an integer");
2897 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2900 case CK_IntegralToFixedPoint:
2902 "Expected src type to be an integer");
2904 "Expected dest type to be fixed point type");
2905 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2908 case CK_IntegralCast: {
2910 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
2911 return Builder.CreateIntCast(Visit(E), ConvertType(DestTy),
2915 ScalarConversionOpts Opts;
2916 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(CE)) {
2917 if (!ICE->isPartOfExplicitCast())
2918 Opts = ScalarConversionOpts(CGF.
SanOpts);
2920 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2923 case CK_IntegralToFloating: {
2926 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
2928 return Builder.CreateSIToFP(Visit(E), ConvertType(DestTy),
"conv");
2929 return Builder.CreateUIToFP(Visit(E), ConvertType(DestTy),
"conv");
2931 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2932 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2935 case CK_FloatingToIntegral: {
2938 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
2940 return Builder.CreateFPToSI(Visit(E), ConvertType(DestTy),
"conv");
2941 return Builder.CreateFPToUI(Visit(E), ConvertType(DestTy),
"conv");
2943 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2944 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2947 case CK_FloatingCast: {
2950 QualType SrcElTy = E->
getType()->
castAs<VectorType>()->getElementType();
2951 QualType DstElTy = DestTy->
castAs<VectorType>()->getElementType();
2952 if (DstElTy->
castAs<BuiltinType>()->getKind() <
2953 SrcElTy->
castAs<BuiltinType>()->getKind())
2954 return Builder.CreateFPTrunc(Visit(E), ConvertType(DestTy),
"conv");
2955 return Builder.CreateFPExt(Visit(E), ConvertType(DestTy),
"conv");
2957 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2958 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2961 case CK_FixedPointToFloating:
2962 case CK_FloatingToFixedPoint: {
2963 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2964 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2967 case CK_BooleanToSignedIntegral: {
2968 ScalarConversionOpts Opts;
2969 Opts.TreatBooleanAsSigned =
true;
2970 return EmitScalarConversion(Visit(E), E->
getType(), DestTy,
2973 case CK_IntegralToBoolean:
2974 return EmitIntToBoolConversion(Visit(E));
2975 case CK_PointerToBoolean:
2976 return EmitPointerToBoolConversion(Visit(E), E->
getType());
2977 case CK_FloatingToBoolean: {
2978 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, CE);
2979 return EmitFloatToBoolConversion(Visit(E));
2981 case CK_MemberPointerToBoolean: {
2982 llvm::Value *MemPtr = Visit(E);
2983 const MemberPointerType *MPT = E->
getType()->
getAs<MemberPointerType>();
2987 case CK_FloatingComplexToReal:
2988 case CK_IntegralComplexToReal:
2991 case CK_FloatingComplexToBoolean:
2992 case CK_IntegralComplexToBoolean: {
2996 return EmitComplexToScalarConversion(
V, E->
getType(), DestTy,
3000 case CK_ZeroToOCLOpaqueType: {
3003 "CK_ZeroToOCLEvent cast on non-event type");
3004 return llvm::Constant::getNullValue(ConvertType(DestTy));
3007 case CK_IntToOCLSampler:
3010 case CK_HLSLVectorTruncation: {
3012 "Destination type must be a vector or builtin type.");
3013 Value *Vec = Visit(E);
3014 if (
auto *VecTy = DestTy->
getAs<VectorType>()) {
3015 SmallVector<int> Mask;
3016 unsigned NumElts = VecTy->getNumElements();
3017 for (
unsigned I = 0; I != NumElts; ++I)
3020 return Builder.CreateShuffleVector(Vec, Mask,
"trunc");
3022 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3023 return Builder.CreateExtractElement(Vec,
Zero,
"cast.vtrunc");
3025 case CK_HLSLMatrixTruncation: {
3027 "Destination type must be a matrix or builtin type.");
3028 Value *Mat = Visit(E);
3029 if (
auto *MatTy = DestTy->
getAs<ConstantMatrixType>()) {
3030 SmallVector<int> Mask;
3031 unsigned NumCols = MatTy->getNumColumns();
3032 unsigned NumRows = MatTy->getNumRows();
3033 unsigned ColOffset = NumCols;
3034 if (
auto *SrcMatTy = E->
getType()->
getAs<ConstantMatrixType>())
3035 ColOffset = SrcMatTy->getNumColumns();
3036 for (
unsigned R = 0; R < NumRows; R++) {
3037 for (
unsigned C = 0;
C < NumCols;
C++) {
3038 unsigned I = R * ColOffset +
C;
3043 return Builder.CreateShuffleVector(Mat, Mask,
"trunc");
3045 llvm::Value *
Zero = llvm::Constant::getNullValue(CGF.
SizeTy);
3046 return Builder.CreateExtractElement(Mat,
Zero,
"cast.mtrunc");
3048 case CK_HLSLElementwiseCast: {
3068 llvm_unreachable(
"unknown scalar cast");
3071Value *ScalarExprEmitter::VisitStmtExpr(
const StmtExpr *E) {
3072 CodeGenFunction::StmtExprEvaluation eval(CGF);
3081Value *ScalarExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) {
3082 CodeGenFunction::RunCleanupsScope Scope(CGF);
3086 Scope.ForceCleanup({&
V});
3095 llvm::Value *InVal,
bool IsInc,
3099 BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1,
false);
3101 BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
3102 BinOp.FPFeatures = FPFeatures;
3107llvm::Value *ScalarExprEmitter::EmitIncDecConsiderOverflowBehavior(
3108 const UnaryOperator *E, llvm::Value *InVal,
bool IsInc) {
3109 llvm::Value *Amount =
3110 llvm::ConstantInt::get(InVal->getType(), IsInc ? 1 : -1,
true);
3111 StringRef Name = IsInc ?
"inc" :
"dec";
3112 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
3113 case LangOptions::SOB_Defined:
3114 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3115 return Builder.CreateAdd(InVal, Amount, Name);
3117 case LangOptions::SOB_Undefined:
3118 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
3119 return Builder.CreateNSWAdd(InVal, Amount, Name);
3121 case LangOptions::SOB_Trapping:
3125 return Builder.CreateNSWAdd(InVal, Amount, Name);
3126 return EmitOverflowCheckedBinOp(Info);
3128 llvm_unreachable(
"Unknown SignedOverflowBehaviorTy");
3153class OMPLastprivateConditionalUpdateRAII {
3155 CodeGenFunction &CGF;
3156 const UnaryOperator *E;
3159 OMPLastprivateConditionalUpdateRAII(CodeGenFunction &CGF,
3160 const UnaryOperator *E)
3162 ~OMPLastprivateConditionalUpdateRAII() {
3171ScalarExprEmitter::EmitScalarPrePostIncDec(
const UnaryOperator *E, LValue LV,
3172 bool isInc,
bool isPre) {
3174 OMPLastprivateConditionalUpdateRAII OMPRegion(CGF, E);
3176 llvm::PHINode *atomicPHI =
nullptr;
3180 QualType SrcType = E->
getType();
3182 int amount = (isInc ? 1 : -1);
3183 bool isSubtraction = !isInc;
3185 if (
const AtomicType *atomicTy =
type->getAs<AtomicType>()) {
3186 type = atomicTy->getValueType();
3187 if (isInc &&
type->isBooleanType()) {
3190 Builder.CreateStore(
True, LV.getAddress(), LV.isVolatileQualified())
3191 ->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
3192 return Builder.getTrue();
3196 return Builder.CreateAtomicRMW(
3197 llvm::AtomicRMWInst::Xchg, LV.getAddress(),
True,
3198 llvm::AtomicOrdering::SequentiallyConsistent);
3203 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3204 !(
type->isUnsignedIntegerType() &&
3205 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3207 LangOptions::SOB_Trapping) {
3208 llvm::AtomicRMWInst::BinOp aop = isInc ? llvm::AtomicRMWInst::Add :
3209 llvm::AtomicRMWInst::Sub;
3210 llvm::Instruction::BinaryOps op = isInc ? llvm::Instruction::Add :
3211 llvm::Instruction::Sub;
3213 llvm::ConstantInt::get(ConvertType(
type), 1,
true),
type);
3215 Builder.CreateAtomicRMW(aop, LV.getAddress(), amt,
3216 llvm::AtomicOrdering::SequentiallyConsistent);
3217 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3221 if (
type->isFloatingType()) {
3222 llvm::Type *Ty = ConvertType(
type);
3223 if (llvm::has_single_bit(Ty->getScalarSizeInBits())) {
3224 llvm::AtomicRMWInst::BinOp aop =
3225 isInc ? llvm::AtomicRMWInst::FAdd : llvm::AtomicRMWInst::FSub;
3226 llvm::Instruction::BinaryOps op =
3227 isInc ? llvm::Instruction::FAdd : llvm::Instruction::FSub;
3228 llvm::Value *amt = llvm::ConstantFP::get(Ty, 1.0);
3229 llvm::AtomicRMWInst *old =
3231 llvm::AtomicOrdering::SequentiallyConsistent);
3233 return isPre ? Builder.CreateBinOp(op, old, amt) : old;
3236 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3239 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
3242 Builder.CreateBr(opBB);
3243 Builder.SetInsertPoint(opBB);
3244 atomicPHI = Builder.CreatePHI(value->getType(), 2);
3245 atomicPHI->addIncoming(value, startBB);
3248 value = EmitLoadOfLValue(LV, E->
getExprLoc());
3259 if (isInc &&
type->isBooleanType()) {
3260 value = Builder.getTrue();
3263 }
else if (
type->isIntegerType()) {
3264 QualType promotedType;
3265 bool canPerformLossyDemotionCheck =
false;
3267 bool excludeOverflowPattern =
3272 assert(promotedType !=
type &&
"Shouldn't promote to the same type.");
3273 canPerformLossyDemotionCheck =
true;
3274 canPerformLossyDemotionCheck &=
3277 canPerformLossyDemotionCheck &=
3279 type, promotedType);
3280 assert((!canPerformLossyDemotionCheck ||
3281 type->isSignedIntegerOrEnumerationType() ||
3283 ConvertType(
type)->getScalarSizeInBits() ==
3284 ConvertType(promotedType)->getScalarSizeInBits()) &&
3285 "The following check expects that if we do promotion to different "
3286 "underlying canonical type, at least one of the types (either "
3287 "base or promoted) will be signed, or the bitwidths will match.");
3290 SanitizerKind::ImplicitIntegerArithmeticValueChange |
3291 SanitizerKind::ImplicitBitfieldConversion) &&
3292 canPerformLossyDemotionCheck) {
3306 value = EmitScalarConversion(value,
type, promotedType, E->
getExprLoc());
3307 Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3308 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3312 ScalarConversionOpts Opts;
3313 if (!LV.isBitField())
3314 Opts = ScalarConversionOpts(CGF.
SanOpts);
3315 else if (CGF.
SanOpts.
has(SanitizerKind::ImplicitBitfieldConversion)) {
3317 SrcType = promotedType;
3320 value = EmitScalarConversion(value, promotedType,
type, E->
getExprLoc(),
3326 }
else if (E->
canOverflow() &&
type->isSignedIntegerOrEnumerationType()) {
3327 value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
3329 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
3330 !excludeOverflowPattern &&
3332 SanitizerKind::UnsignedIntegerOverflow, E->
getType())) {
3336 llvm::Value *amt = llvm::ConstantInt::get(value->getType(), amount,
true);
3337 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3341 }
else if (
const PointerType *ptr =
type->getAs<PointerType>()) {
3342 QualType
type = ptr->getPointeeType();
3345 if (
const VariableArrayType *vla
3348 if (!isInc) numElts = Builder.CreateNSWNeg(numElts,
"vla.negsize");
3351 value = Builder.CreateGEP(elemTy, value, numElts,
"vla.inc");
3354 elemTy, value, numElts,
false, isSubtraction,
3358 }
else if (
type->isFunctionType()) {
3359 llvm::Value *amt = Builder.getInt32(amount);
3362 value = Builder.CreateGEP(CGF.
Int8Ty, value, amt,
"incdec.funcptr");
3366 false, isSubtraction,
3371 llvm::Value *amt = Builder.getInt32(amount);
3374 value = Builder.CreateGEP(elemTy, value, amt,
"incdec.ptr");
3377 elemTy, value, amt,
false, isSubtraction,
3382 }
else if (
type->isVectorType()) {
3383 if (
type->hasIntegerRepresentation()) {
3384 llvm::Value *amt = llvm::ConstantInt::getSigned(value->getType(), amount);
3386 value = Builder.CreateAdd(value, amt, isInc ?
"inc" :
"dec");
3388 value = Builder.CreateFAdd(
3390 llvm::ConstantFP::get(value->getType(), amount),
3391 isInc ?
"inc" :
"dec");
3395 }
else if (
type->isRealFloatingType()) {
3398 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
3403 value = Builder.CreateCall(
3406 input,
"incdec.conv");
3408 value = Builder.CreateFPExt(input, CGF.
CGM.
FloatTy,
"incdec.conv");
3412 if (value->getType()->isFloatTy())
3413 amt = llvm::ConstantFP::get(VMContext,
3414 llvm::APFloat(
static_cast<float>(amount)));
3415 else if (value->getType()->isDoubleTy())
3416 amt = llvm::ConstantFP::get(VMContext,
3417 llvm::APFloat(
static_cast<double>(amount)));
3421 llvm::APFloat F(
static_cast<float>(amount));
3423 const llvm::fltSemantics *FS;
3426 if (value->getType()->isFP128Ty())
3428 else if (value->getType()->isHalfTy())
3430 else if (value->getType()->isBFloatTy())
3432 else if (value->getType()->isPPC_FP128Ty())
3436 F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
3437 amt = llvm::ConstantFP::get(VMContext, F);
3439 value = Builder.CreateFAdd(value, amt, isInc ?
"inc" :
"dec");
3443 value = Builder.CreateCall(
3446 value,
"incdec.conv");
3448 value = Builder.CreateFPTrunc(value, input->getType(),
"incdec.conv");
3453 }
else if (
type->isFixedPointType()) {
3460 Info.Opcode = isInc ? BO_Add : BO_Sub;
3462 Info.RHS = llvm::ConstantInt::get(value->getType(), 1,
false);
3465 if (
type->isSignedFixedPointType()) {
3466 Info.Opcode = isInc ? BO_Sub : BO_Add;
3467 Info.RHS = Builder.CreateNeg(Info.RHS);
3472 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
3474 Info.RHS = FPBuilder.CreateIntegerToFixed(Info.RHS,
true, DstSema);
3475 value = EmitFixedPointBinOp(Info);
3479 const ObjCObjectPointerType *OPT =
type->castAs<ObjCObjectPointerType>();
3482 if (!isInc) size = -size;
3483 llvm::Value *sizeValue =
3484 llvm::ConstantInt::getSigned(CGF.
SizeTy, size.getQuantity());
3487 value = Builder.CreateGEP(CGF.
Int8Ty, value, sizeValue,
"incdec.objptr");
3490 CGF.
Int8Ty, value, sizeValue,
false, isSubtraction,
3492 value = Builder.CreateBitCast(value, input->getType());
3496 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
3501 llvm::Value *
success = Pair.second;
3502 atomicPHI->addIncoming(old, curBlock);
3503 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
3504 Builder.SetInsertPoint(contBB);
3505 return isPre ? value : input;
3509 if (LV.isBitField()) {
3519 return isPre ? value : input;
3523Value *ScalarExprEmitter::VisitUnaryPlus(
const UnaryOperator *E,
3524 QualType PromotionType) {
3525 QualType promotionTy = PromotionType.
isNull()
3528 Value *result = VisitPlus(E, promotionTy);
3529 if (result && !promotionTy.
isNull())
3530 result = EmitUnPromotedValue(result, E->
getType());
3534Value *ScalarExprEmitter::VisitPlus(
const UnaryOperator *E,
3535 QualType PromotionType) {
3537 TestAndClearIgnoreResultAssign();
3538 if (!PromotionType.
isNull())
3543Value *ScalarExprEmitter::VisitUnaryMinus(
const UnaryOperator *E,
3544 QualType PromotionType) {
3545 QualType promotionTy = PromotionType.
isNull()
3548 Value *result = VisitMinus(E, promotionTy);
3549 if (result && !promotionTy.
isNull())
3550 result = EmitUnPromotedValue(result, E->
getType());
3554Value *ScalarExprEmitter::VisitMinus(
const UnaryOperator *E,
3555 QualType PromotionType) {
3556 TestAndClearIgnoreResultAssign();
3558 if (!PromotionType.
isNull())
3564 if (Op->
getType()->isFPOrFPVectorTy())
3565 return Builder.CreateFNeg(Op,
"fneg");
3570 BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
3572 BinOp.Opcode = BO_Sub;
3575 return EmitSub(BinOp);
3578Value *ScalarExprEmitter::VisitUnaryNot(
const UnaryOperator *E) {
3579 TestAndClearIgnoreResultAssign();
3581 return Builder.CreateNot(Op,
"not");
3584Value *ScalarExprEmitter::VisitUnaryLNot(
const UnaryOperator *E) {
3588 VectorKind::Generic) {
3592 if (Oper->
getType()->isFPOrFPVectorTy()) {
3593 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
3595 Result = Builder.CreateFCmp(llvm::CmpInst::FCMP_OEQ, Oper,
Zero,
"cmp");
3597 Result = Builder.CreateICmp(llvm::CmpInst::ICMP_EQ, Oper,
Zero,
"cmp");
3598 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
3607 BoolVal = Builder.CreateNot(BoolVal,
"lnot");
3610 return Builder.CreateZExt(BoolVal, ConvertType(E->
getType()),
"lnot.ext");
3613Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
3615 Expr::EvalResult EVResult;
3618 return Builder.getInt(
Value);
3623 llvm::Type* ResultType = ConvertType(E->
getType());
3624 llvm::Value*
Result = llvm::Constant::getNullValue(ResultType);
3626 for (
unsigned i = 0; i != n; ++i) {
3628 llvm::Value *Offset =
nullptr;
3635 Idx = Builder.CreateIntCast(Idx, ResultType, IdxSigned,
"conv");
3642 llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType,
3646 Offset = Builder.CreateMul(Idx, ElemSize);
3651 FieldDecl *MemberDecl = ON.
getField();
3659 FieldEnd = RD->field_end();
3660 Field != FieldEnd; ++Field, ++i) {
3661 if (*Field == MemberDecl)
3664 assert(i < RL.
getFieldCount() &&
"offsetof field in wrong type");
3669 Offset = llvm::ConstantInt::get(ResultType, OffsetInt);
3672 CurrentType = MemberDecl->
getType();
3677 llvm_unreachable(
"dependent __builtin_offsetof");
3694 Offset = llvm::ConstantInt::get(ResultType, OffsetInt.
getQuantity());
3706ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
3707 const UnaryExprOrTypeTraitExpr *E) {
3710 Kind == UETT_SizeOf || Kind == UETT_DataSizeOf || Kind == UETT_CountOf) {
3711 if (
const VariableArrayType *VAT =
3716 bool EvaluateExtent =
true;
3717 if (Kind == UETT_CountOf && VAT->getElementType()->isArrayType()) {
3719 !VAT->getSizeExpr()->isIntegerConstantExpr(CGF.
getContext());
3721 if (EvaluateExtent) {
3732 if (Kind == UETT_CountOf)
3741 if (!eltSize.
isOne())
3744 return VlaSize.NumElts;
3747 }
else if (E->
getKind() == UETT_OpenMPRequiredSimdAlign) {
3753 return llvm::ConstantInt::get(CGF.
SizeTy, Alignment);
3754 }
else if (E->
getKind() == UETT_VectorElements) {
3756 return Builder.CreateElementCount(CGF.
SizeTy, VecTy->getElementCount());
3764Value *ScalarExprEmitter::VisitUnaryReal(
const UnaryOperator *E,
3765 QualType PromotionType) {
3766 QualType promotionTy = PromotionType.
isNull()
3769 Value *result = VisitReal(E, promotionTy);
3770 if (result && !promotionTy.
isNull())
3771 result = EmitUnPromotedValue(result, E->
getType());
3775Value *ScalarExprEmitter::VisitReal(
const UnaryOperator *E,
3776 QualType PromotionType) {
3783 if (!PromotionType.
isNull()) {
3785 Op, IgnoreResultAssign,
true);
3800 if (!PromotionType.
isNull())
3805Value *ScalarExprEmitter::VisitUnaryImag(
const UnaryOperator *E,
3806 QualType PromotionType) {
3807 QualType promotionTy = PromotionType.
isNull()
3810 Value *result = VisitImag(E, promotionTy);
3811 if (result && !promotionTy.
isNull())
3812 result = EmitUnPromotedValue(result, E->
getType());
3816Value *ScalarExprEmitter::VisitImag(
const UnaryOperator *E,
3817 QualType PromotionType) {
3824 if (!PromotionType.
isNull()) {
3826 Op,
true, IgnoreResultAssign);
3830 return result.second
3846 else if (!PromotionType.
isNull())
3850 if (!PromotionType.
isNull())
3851 return llvm::Constant::getNullValue(ConvertType(PromotionType));
3852 return llvm::Constant::getNullValue(ConvertType(E->
getType()));
3859Value *ScalarExprEmitter::EmitPromotedValue(
Value *result,
3860 QualType PromotionType) {
3861 return CGF.
Builder.CreateFPExt(result, ConvertType(PromotionType),
"ext");
3864Value *ScalarExprEmitter::EmitUnPromotedValue(
Value *result,
3865 QualType ExprType) {
3866 return CGF.
Builder.CreateFPTrunc(result, ConvertType(ExprType),
"unpromotion");
3869Value *ScalarExprEmitter::EmitPromoted(
const Expr *E, QualType PromotionType) {
3871 if (
auto BO = dyn_cast<BinaryOperator>(E)) {
3873#define HANDLE_BINOP(OP) \
3875 return Emit##OP(EmitBinOps(BO, PromotionType));
3884 }
else if (
auto UO = dyn_cast<UnaryOperator>(E)) {
3887 return VisitImag(UO, PromotionType);
3889 return VisitReal(UO, PromotionType);
3891 return VisitMinus(UO, PromotionType);
3893 return VisitPlus(UO, PromotionType);
3898 auto result = Visit(
const_cast<Expr *
>(E));
3900 if (!PromotionType.
isNull())
3901 return EmitPromotedValue(result, PromotionType);
3903 return EmitUnPromotedValue(result, E->
getType());
3908BinOpInfo ScalarExprEmitter::EmitBinOps(
const BinaryOperator *E,
3909 QualType PromotionType) {
3910 TestAndClearIgnoreResultAssign();
3914 if (!PromotionType.
isNull())
3915 Result.Ty = PromotionType;
3924LValue ScalarExprEmitter::EmitCompoundAssignLValue(
3925 const CompoundAssignOperator *E,
3926 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &),
3937 QualType PromotionTypeCR;
3939 if (PromotionTypeCR.
isNull())
3942 QualType PromotionTypeRHS = getPromotionType(E->
getRHS()->
getType());
3943 if (!PromotionTypeRHS.
isNull())
3946 OpInfo.RHS = Visit(E->
getRHS());
3947 OpInfo.Ty = PromotionTypeCR;
3954 llvm::PHINode *atomicPHI =
nullptr;
3955 if (
const AtomicType *atomicTy = LHSTy->
getAs<AtomicType>()) {
3956 QualType
type = atomicTy->getValueType();
3957 if (!
type->isBooleanType() &&
type->isIntegerType() &&
3958 !(
type->isUnsignedIntegerType() &&
3959 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow)) &&
3961 LangOptions::SOB_Trapping) {
3962 llvm::AtomicRMWInst::BinOp AtomicOp = llvm::AtomicRMWInst::BAD_BINOP;
3963 llvm::Instruction::BinaryOps Op;
3964 switch (OpInfo.Opcode) {
3966 case BO_MulAssign:
case BO_DivAssign:
3972 AtomicOp = llvm::AtomicRMWInst::Add;
3973 Op = llvm::Instruction::Add;
3976 AtomicOp = llvm::AtomicRMWInst::Sub;
3977 Op = llvm::Instruction::Sub;
3980 AtomicOp = llvm::AtomicRMWInst::And;
3981 Op = llvm::Instruction::And;
3984 AtomicOp = llvm::AtomicRMWInst::Xor;
3985 Op = llvm::Instruction::Xor;
3988 AtomicOp = llvm::AtomicRMWInst::Or;
3989 Op = llvm::Instruction::Or;
3992 llvm_unreachable(
"Invalid compound assignment type");
3994 if (AtomicOp != llvm::AtomicRMWInst::BAD_BINOP) {
3996 EmitScalarConversion(OpInfo.RHS, E->
getRHS()->
getType(), LHSTy,
4000 llvm::AtomicRMWInst *OldVal =
4005 Result = Builder.CreateBinOp(Op, OldVal, Amt);
4011 llvm::BasicBlock *startBB = Builder.GetInsertBlock();
4013 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4015 Builder.CreateBr(opBB);
4016 Builder.SetInsertPoint(opBB);
4017 atomicPHI = Builder.CreatePHI(OpInfo.LHS->getType(), 2);
4018 atomicPHI->addIncoming(OpInfo.LHS, startBB);
4019 OpInfo.LHS = atomicPHI;
4022 OpInfo.LHS = EmitLoadOfLValue(LHSLV, E->
getExprLoc());
4024 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, OpInfo.FPFeatures);
4026 if (!PromotionTypeLHS.
isNull())
4027 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy, PromotionTypeLHS,
4030 OpInfo.LHS = EmitScalarConversion(OpInfo.LHS, LHSTy,
4041 if (LHSLV.isBitField()) {
4043 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc);
4045 Result = EmitScalarConversion(
Result, PromotionTypeCR, LHSTy, Loc,
4046 ScalarConversionOpts(CGF.
SanOpts));
4049 llvm::BasicBlock *curBlock = Builder.GetInsertBlock();
4053 llvm::Value *old = CGF.
EmitToMemory(Pair.first.getScalarVal(), LHSTy);
4054 llvm::Value *
success = Pair.second;
4055 atomicPHI->addIncoming(old, curBlock);
4056 Builder.CreateCondBr(success, contBB, atomicPHI->getParent());
4057 Builder.SetInsertPoint(contBB);
4065 if (LHSLV.isBitField()) {
4081Value *ScalarExprEmitter::EmitCompoundAssign(
const CompoundAssignOperator *E,
4082 Value *(ScalarExprEmitter::*
Func)(
const BinOpInfo &)) {
4083 bool Ignore = TestAndClearIgnoreResultAssign();
4084 Value *RHS =
nullptr;
4085 LValue LHS = EmitCompoundAssignLValue(E,
Func, RHS);
4096 if (!LHS.isVolatileQualified())
4100 return EmitLoadOfLValue(LHS, E->
getExprLoc());
4103void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
4104 const BinOpInfo &Ops, llvm::Value *
Zero,
bool isDiv) {
4105 SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>, 2>
4108 if (CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero)) {
4109 Checks.push_back(std::make_pair(Builder.CreateICmpNE(Ops.RHS,
Zero),
4110 SanitizerKind::SO_IntegerDivideByZero));
4114 if (CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow) &&
4115 Ops.Ty->hasSignedIntegerRepresentation() &&
4117 Ops.mayHaveIntegerOverflow()) {
4120 llvm::Value *IntMin =
4121 Builder.getInt(llvm::APInt::getSignedMinValue(Ty->getBitWidth()));
4122 llvm::Value *NegOne = llvm::Constant::getAllOnesValue(Ty);
4124 llvm::Value *LHSCmp = Builder.CreateICmpNE(Ops.LHS, IntMin);
4125 llvm::Value *RHSCmp = Builder.CreateICmpNE(Ops.RHS, NegOne);
4126 llvm::Value *NotOverflow = Builder.CreateOr(LHSCmp, RHSCmp,
"or");
4128 std::make_pair(NotOverflow, SanitizerKind::SO_SignedIntegerOverflow));
4131 if (Checks.size() > 0)
4132 EmitBinOpCheck(Checks, Ops);
4135Value *ScalarExprEmitter::EmitDiv(
const BinOpInfo &Ops) {
4137 SanitizerDebugLocation SanScope(&CGF,
4138 {SanitizerKind::SO_IntegerDivideByZero,
4139 SanitizerKind::SO_SignedIntegerOverflow,
4140 SanitizerKind::SO_FloatDivideByZero},
4141 SanitizerHandler::DivremOverflow);
4142 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4143 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4144 Ops.Ty->isIntegerType() &&
4145 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4146 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4147 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
true);
4148 }
else if (CGF.
SanOpts.
has(SanitizerKind::FloatDivideByZero) &&
4149 Ops.Ty->isRealFloatingType() &&
4150 Ops.mayHaveFloatDivisionByZero()) {
4151 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4152 llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS,
Zero);
4154 std::make_pair(NonZero, SanitizerKind::SO_FloatDivideByZero), Ops);
4158 if (Ops.Ty->isConstantMatrixType()) {
4159 llvm::MatrixBuilder MB(Builder);
4166 "first operand must be a matrix");
4168 "second operand must be an arithmetic type");
4169 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4170 return MB.CreateScalarDiv(Ops.LHS, Ops.RHS,
4171 Ops.Ty->hasUnsignedIntegerRepresentation());
4174 if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
4176 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures);
4177 Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS,
"div");
4181 else if (Ops.isFixedPointOp())
4182 return EmitFixedPointBinOp(Ops);
4183 else if (Ops.Ty->hasUnsignedIntegerRepresentation())
4184 return Builder.CreateUDiv(Ops.LHS, Ops.RHS,
"div");
4186 return Builder.CreateSDiv(Ops.LHS, Ops.RHS,
"div");
4189Value *ScalarExprEmitter::EmitRem(
const BinOpInfo &Ops) {
4191 if ((CGF.
SanOpts.
has(SanitizerKind::IntegerDivideByZero) ||
4192 CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) &&
4193 Ops.Ty->isIntegerType() &&
4194 (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
4195 SanitizerDebugLocation SanScope(&CGF,
4196 {SanitizerKind::SO_IntegerDivideByZero,
4197 SanitizerKind::SO_SignedIntegerOverflow},
4198 SanitizerHandler::DivremOverflow);
4199 llvm::Value *
Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
4200 EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops,
Zero,
false);
4203 if (Ops.Ty->hasUnsignedIntegerRepresentation())
4204 return Builder.CreateURem(Ops.LHS, Ops.RHS,
"rem");
4206 if (CGF.
getLangOpts().HLSL && Ops.Ty->hasFloatingRepresentation())
4207 return Builder.CreateFRem(Ops.LHS, Ops.RHS,
"rem");
4209 return Builder.CreateSRem(Ops.LHS, Ops.RHS,
"rem");
4212Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(
const BinOpInfo &Ops) {
4217 bool isSigned = Ops.Ty->isSignedIntegerOrEnumerationType();
4218 switch (Ops.Opcode) {
4222 IID = isSigned ? llvm::Intrinsic::sadd_with_overflow :
4223 llvm::Intrinsic::uadd_with_overflow;
4224 OverflowKind = SanitizerHandler::AddOverflow;
4229 IID = isSigned ? llvm::Intrinsic::ssub_with_overflow :
4230 llvm::Intrinsic::usub_with_overflow;
4231 OverflowKind = SanitizerHandler::SubOverflow;
4236 IID = isSigned ? llvm::Intrinsic::smul_with_overflow :
4237 llvm::Intrinsic::umul_with_overflow;
4238 OverflowKind = SanitizerHandler::MulOverflow;
4241 llvm_unreachable(
"Unsupported operation for overflow detection");
4247 SanitizerDebugLocation SanScope(&CGF,
4248 {SanitizerKind::SO_SignedIntegerOverflow,
4249 SanitizerKind::SO_UnsignedIntegerOverflow},
4255 Value *resultAndOverflow = Builder.CreateCall(intrinsic, {Ops.LHS, Ops.RHS});
4256 Value *result = Builder.CreateExtractValue(resultAndOverflow, 0);
4257 Value *overflow = Builder.CreateExtractValue(resultAndOverflow, 1);
4260 const std::string *handlerName =
4262 if (handlerName->empty()) {
4265 if (!isSigned || CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow)) {
4266 llvm::Value *NotOverflow = Builder.CreateNot(overflow);
4268 isSigned ? SanitizerKind::SO_SignedIntegerOverflow
4269 : SanitizerKind::SO_UnsignedIntegerOverflow;
4270 EmitBinOpCheck(std::make_pair(NotOverflow, Ordinal), Ops);
4272 CGF.
EmitTrapCheck(Builder.CreateNot(overflow), OverflowKind);
4277 llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
4278 llvm::BasicBlock *continueBB =
4282 Builder.CreateCondBr(overflow, overflowBB, continueBB);
4286 Builder.SetInsertPoint(overflowBB);
4289 llvm::Type *Int8Ty = CGF.
Int8Ty;
4290 llvm::Type *argTypes[] = { CGF.
Int64Ty, CGF.
Int64Ty, Int8Ty, Int8Ty };
4291 llvm::FunctionType *handlerTy =
4292 llvm::FunctionType::get(CGF.
Int64Ty, argTypes,
true);
4293 llvm::FunctionCallee handler =
4298 llvm::Value *lhs = Builder.CreateSExt(Ops.LHS, CGF.
Int64Ty);
4299 llvm::Value *rhs = Builder.CreateSExt(Ops.RHS, CGF.
Int64Ty);
4303 llvm::Value *handlerArgs[] = {
4306 Builder.getInt8(OpID),
4309 llvm::Value *handlerResult =
4313 handlerResult = Builder.CreateTrunc(handlerResult, opTy);
4314 Builder.CreateBr(continueBB);
4316 Builder.SetInsertPoint(continueBB);
4317 llvm::PHINode *phi = Builder.CreatePHI(opTy, 2);
4318 phi->addIncoming(result, initialBB);
4319 phi->addIncoming(handlerResult, overflowBB);
4328 bool isSubtraction) {
4333 Value *pointer = op.LHS;
4334 Expr *pointerOperand =
expr->getLHS();
4336 Expr *indexOperand =
expr->getRHS();
4339 if (!isSubtraction && !pointer->
getType()->isPointerTy()) {
4340 std::swap(pointer,
index);
4341 std::swap(pointerOperand, indexOperand);
4345 index, isSubtraction);
4351 Expr *indexOperand, llvm::Value *
index,
bool isSubtraction) {
4355 auto &DL =
CGM.getDataLayout();
4378 llvm::Value *Ptr =
Builder.CreateIntToPtr(
index, pointer->getType());
4380 !
SanOpts.has(SanitizerKind::PointerOverflow) ||
4381 NullPointerIsDefined(
Builder.GetInsertBlock()->getParent(),
4382 PtrTy->getPointerAddressSpace()))
4385 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
4386 auto CheckHandler = SanitizerHandler::PointerOverflow;
4388 llvm::Value *IsZeroIndex =
Builder.CreateIsNull(
index);
4390 llvm::Type *
IntPtrTy = DL.getIntPtrType(PtrTy);
4391 llvm::Value *IntPtr = llvm::Constant::getNullValue(
IntPtrTy);
4393 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
4394 EmitCheck({{IsZeroIndex, CheckOrdinal}}, CheckHandler, StaticArgs,
4399 if (width != DL.getIndexTypeSizeInBits(PtrTy)) {
4410 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4420 llvm::Value *objectSize =
4426 return Builder.CreateBitCast(result, pointer->getType());
4431 getContext().getAsVariableArrayType(elementType)) {
4433 llvm::Value *numElements =
getVLASize(vla).NumElts;
4442 pointer =
Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4462 return Builder.CreateGEP(elemTy, pointer,
index,
"add.ptr");
4475 bool negMul,
bool negAdd) {
4476 Value *MulOp0 = MulOp->getOperand(0);
4477 Value *MulOp1 = MulOp->getOperand(1);
4479 MulOp0 = Builder.CreateFNeg(MulOp0,
"neg");
4481 Addend = Builder.CreateFNeg(Addend,
"neg");
4483 Value *FMulAdd =
nullptr;
4484 if (Builder.getIsFPConstrained()) {
4486 "Only constrained operation should be created when Builder is in FP "
4487 "constrained mode");
4488 FMulAdd = Builder.CreateConstrainedFPCall(
4489 CGF.
CGM.
getIntrinsic(llvm::Intrinsic::experimental_constrained_fmuladd,
4491 {MulOp0, MulOp1, Addend});
4493 FMulAdd = Builder.CreateCall(
4495 {MulOp0, MulOp1, Addend});
4497 MulOp->eraseFromParent();
4512 assert((op.Opcode == BO_Add || op.Opcode == BO_AddAssign ||
4513 op.Opcode == BO_Sub || op.Opcode == BO_SubAssign) &&
4514 "Only fadd/fsub can be the root of an fmuladd.");
4517 if (!op.FPFeatures.allowFPContractWithinStatement())
4520 Value *LHS = op.LHS;
4521 Value *RHS = op.RHS;
4525 bool NegLHS =
false;
4526 if (
auto *LHSUnOp = dyn_cast<llvm::UnaryOperator>(LHS)) {
4527 if (LHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4528 LHSUnOp->use_empty() && LHSUnOp->getOperand(0)->hasOneUse()) {
4529 LHS = LHSUnOp->getOperand(0);
4534 bool NegRHS =
false;
4535 if (
auto *RHSUnOp = dyn_cast<llvm::UnaryOperator>(RHS)) {
4536 if (RHSUnOp->getOpcode() == llvm::Instruction::FNeg &&
4537 RHSUnOp->use_empty() && RHSUnOp->getOperand(0)->hasOneUse()) {
4538 RHS = RHSUnOp->getOperand(0);
4546 if (
auto *LHSBinOp = dyn_cast<llvm::BinaryOperator>(LHS)) {
4547 if (LHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4548 (LHSBinOp->use_empty() || NegLHS)) {
4552 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4555 if (
auto *RHSBinOp = dyn_cast<llvm::BinaryOperator>(RHS)) {
4556 if (RHSBinOp->getOpcode() == llvm::Instruction::FMul &&
4557 (RHSBinOp->use_empty() || NegRHS)) {
4561 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4565 if (
auto *LHSBinOp = dyn_cast<llvm::CallBase>(LHS)) {
4566 if (LHSBinOp->getIntrinsicID() ==
4567 llvm::Intrinsic::experimental_constrained_fmul &&
4568 (LHSBinOp->use_empty() || NegLHS)) {
4572 return buildFMulAdd(LHSBinOp, op.RHS, CGF, Builder, NegLHS, isSub);
4575 if (
auto *RHSBinOp = dyn_cast<llvm::CallBase>(RHS)) {
4576 if (RHSBinOp->getIntrinsicID() ==
4577 llvm::Intrinsic::experimental_constrained_fmul &&
4578 (RHSBinOp->use_empty() || NegRHS)) {
4582 return buildFMulAdd(RHSBinOp, op.LHS, CGF, Builder, isSub ^ NegRHS,
false);
4589Value *ScalarExprEmitter::EmitAdd(
const BinOpInfo &op) {
4590 if (op.LHS->getType()->isPointerTy() ||
4591 op.RHS->getType()->isPointerTy())
4594 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4595 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4596 case LangOptions::SOB_Defined:
4597 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4598 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4600 case LangOptions::SOB_Undefined:
4601 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4602 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4604 case LangOptions::SOB_Trapping:
4605 if (CanElideOverflowCheck(CGF.
getContext(), op))
4606 return Builder.CreateNSWAdd(op.LHS, op.RHS,
"add");
4607 return EmitOverflowCheckedBinOp(op);
4612 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4613 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4619 if (op.Ty->isConstantMatrixType()) {
4620 llvm::MatrixBuilder MB(Builder);
4621 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4622 return MB.CreateAdd(op.LHS, op.RHS);
4625 if (op.Ty->isUnsignedIntegerType() &&
4626 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4627 !CanElideOverflowCheck(CGF.
getContext(), op))
4628 return EmitOverflowCheckedBinOp(op);
4630 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4631 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4632 return Builder.CreateFAdd(op.LHS, op.RHS,
"add");
4635 if (op.isFixedPointOp())
4636 return EmitFixedPointBinOp(op);
4638 return Builder.CreateAdd(op.LHS, op.RHS,
"add");
4643Value *ScalarExprEmitter::EmitFixedPointBinOp(
const BinOpInfo &op) {
4645 using llvm::ConstantInt;
4651 QualType ResultTy = op.Ty;
4652 QualType LHSTy, RHSTy;
4653 if (
const auto *BinOp = dyn_cast<BinaryOperator>(op.E)) {
4654 RHSTy = BinOp->getRHS()->getType();
4655 if (
const auto *CAO = dyn_cast<CompoundAssignOperator>(BinOp)) {
4660 LHSTy = CAO->getComputationLHSType();
4661 ResultTy = CAO->getComputationResultType();
4663 LHSTy = BinOp->getLHS()->getType();
4664 }
else if (
const auto *UnOp = dyn_cast<UnaryOperator>(op.E)) {
4665 LHSTy = UnOp->getSubExpr()->getType();
4666 RHSTy = UnOp->getSubExpr()->getType();
4669 Value *LHS = op.LHS;
4670 Value *RHS = op.RHS;
4675 auto CommonFixedSema = LHSFixedSema.getCommonSemantics(RHSFixedSema);
4679 llvm::FixedPointBuilder<CGBuilderTy> FPBuilder(Builder);
4680 switch (op.Opcode) {
4683 Result = FPBuilder.CreateAdd(LHS, LHSFixedSema, RHS, RHSFixedSema);
4687 Result = FPBuilder.CreateSub(LHS, LHSFixedSema, RHS, RHSFixedSema);
4691 Result = FPBuilder.CreateMul(LHS, LHSFixedSema, RHS, RHSFixedSema);
4695 Result = FPBuilder.CreateDiv(LHS, LHSFixedSema, RHS, RHSFixedSema);
4699 Result = FPBuilder.CreateShl(LHS, LHSFixedSema, RHS);
4703 Result = FPBuilder.CreateShr(LHS, LHSFixedSema, RHS);
4706 return FPBuilder.CreateLT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4708 return FPBuilder.CreateGT(LHS, LHSFixedSema, RHS, RHSFixedSema);
4710 return FPBuilder.CreateLE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4712 return FPBuilder.CreateGE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4717 return FPBuilder.CreateEQ(LHS, LHSFixedSema, RHS, RHSFixedSema);
4719 return FPBuilder.CreateNE(LHS, LHSFixedSema, RHS, RHSFixedSema);
4723 llvm_unreachable(
"Found unimplemented fixed point binary operation");
4736 llvm_unreachable(
"Found unsupported binary operation for fixed point types.");
4742 return FPBuilder.CreateFixedToFixed(
Result, IsShift ? LHSFixedSema
4747Value *ScalarExprEmitter::EmitSub(
const BinOpInfo &op) {
4749 if (!op.LHS->getType()->isPointerTy()) {
4750 if (op.Ty->isSignedIntegerOrEnumerationType()) {
4751 switch (CGF.
getLangOpts().getSignedOverflowBehavior()) {
4752 case LangOptions::SOB_Defined:
4753 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4754 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4756 case LangOptions::SOB_Undefined:
4757 if (!CGF.
SanOpts.
has(SanitizerKind::SignedIntegerOverflow))
4758 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4760 case LangOptions::SOB_Trapping:
4761 if (CanElideOverflowCheck(CGF.
getContext(), op))
4762 return Builder.CreateNSWSub(op.LHS, op.RHS,
"sub");
4763 return EmitOverflowCheckedBinOp(op);
4768 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4769 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4775 if (op.Ty->isConstantMatrixType()) {
4776 llvm::MatrixBuilder MB(Builder);
4777 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4778 return MB.CreateSub(op.LHS, op.RHS);
4781 if (op.Ty->isUnsignedIntegerType() &&
4782 CGF.
SanOpts.
has(SanitizerKind::UnsignedIntegerOverflow) &&
4783 !CanElideOverflowCheck(CGF.
getContext(), op))
4784 return EmitOverflowCheckedBinOp(op);
4786 if (op.LHS->getType()->isFPOrFPVectorTy()) {
4787 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, op.FPFeatures);
4788 return Builder.CreateFSub(op.LHS, op.RHS,
"sub");
4791 if (op.isFixedPointOp())
4792 return EmitFixedPointBinOp(op);
4794 return Builder.CreateSub(op.LHS, op.RHS,
"sub");
4799 if (!op.RHS->getType()->isPointerTy())
4806 = Builder.CreatePtrToInt(op.LHS, CGF.
PtrDiffTy,
"sub.ptr.lhs.cast");
4808 = Builder.CreatePtrToInt(op.RHS, CGF.
PtrDiffTy,
"sub.ptr.rhs.cast");
4809 Value *diffInChars = Builder.CreateSub(LHS, RHS,
"sub.ptr.sub");
4813 QualType elementType =
expr->getLHS()->getType()->getPointeeType();
4815 llvm::Value *divisor =
nullptr;
4818 if (
const VariableArrayType *vla
4821 elementType = VlaSize.Type;
4822 divisor = VlaSize.NumElts;
4826 if (!eltSize.
isOne())
4833 CharUnits elementSize;
4842 if (elementSize.
isOne())
4851 return Builder.CreateExactSDiv(diffInChars, divisor,
"sub.ptr.div");
4854Value *ScalarExprEmitter::GetMaximumShiftAmount(
Value *LHS,
Value *RHS,
4856 llvm::IntegerType *Ty;
4857 if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4865 llvm::Type *RHSTy = RHS->
getType();
4866 llvm::APInt RHSMax =
4867 RHSIsSigned ? llvm::APInt::getSignedMaxValue(RHSTy->getScalarSizeInBits())
4868 : llvm::
APInt::getMaxValue(RHSTy->getScalarSizeInBits());
4869 if (RHSMax.ult(Ty->getBitWidth()))
4870 return llvm::ConstantInt::get(RHSTy, RHSMax);
4871 return llvm::ConstantInt::get(RHSTy, Ty->getBitWidth() - 1);
4875 const Twine &Name) {
4876 llvm::IntegerType *Ty;
4877 if (
auto *VT = dyn_cast<llvm::VectorType>(LHS->
getType()))
4882 if (llvm::isPowerOf2_64(Ty->getBitWidth()))
4883 return Builder.CreateAnd(RHS, GetMaximumShiftAmount(LHS, RHS,
false), Name);
4885 return Builder.CreateURem(
4886 RHS, llvm::ConstantInt::get(RHS->
getType(), Ty->getBitWidth()), Name);
4889Value *ScalarExprEmitter::EmitShl(
const BinOpInfo &Ops) {
4891 if (Ops.isFixedPointOp())
4892 return EmitFixedPointBinOp(Ops);
4896 Value *RHS = Ops.RHS;
4897 if (Ops.LHS->getType() != RHS->
getType())
4898 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4900 bool SanitizeSignedBase = CGF.
SanOpts.
has(SanitizerKind::ShiftBase) &&
4901 Ops.Ty->hasSignedIntegerRepresentation() &&
4904 bool SanitizeUnsignedBase =
4905 CGF.
SanOpts.
has(SanitizerKind::UnsignedShiftBase) &&
4906 Ops.Ty->hasUnsignedIntegerRepresentation();
4907 bool SanitizeBase = SanitizeSignedBase || SanitizeUnsignedBase;
4908 bool SanitizeExponent = CGF.
SanOpts.
has(SanitizerKind::ShiftExponent);
4911 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shl.mask");
4912 else if ((SanitizeBase || SanitizeExponent) &&
4914 SmallVector<SanitizerKind::SanitizerOrdinal, 3> Ordinals;
4915 if (SanitizeSignedBase)
4916 Ordinals.push_back(SanitizerKind::SO_ShiftBase);
4917 if (SanitizeUnsignedBase)
4918 Ordinals.push_back(SanitizerKind::SO_UnsignedShiftBase);
4919 if (SanitizeExponent)
4920 Ordinals.push_back(SanitizerKind::SO_ShiftExponent);
4922 SanitizerDebugLocation SanScope(&CGF, Ordinals,
4923 SanitizerHandler::ShiftOutOfBounds);
4924 SmallVector<std::pair<Value *, SanitizerKind::SanitizerOrdinal>, 2> Checks;
4925 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4926 llvm::Value *WidthMinusOne =
4927 GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned);
4928 llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
4930 if (SanitizeExponent) {
4932 std::make_pair(ValidExponent, SanitizerKind::SO_ShiftExponent));
4939 llvm::BasicBlock *Orig = Builder.GetInsertBlock();
4942 Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
4943 llvm::Value *PromotedWidthMinusOne =
4944 (RHS == Ops.RHS) ? WidthMinusOne
4945 : GetMaximumShiftAmount(Ops.LHS, RHS, RHSIsSigned);
4947 llvm::Value *BitsShiftedOff = Builder.CreateLShr(
4948 Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS,
"shl.zeros",
4957 llvm::Value *One = llvm::ConstantInt::get(BitsShiftedOff->getType(), 1);
4958 BitsShiftedOff = Builder.CreateLShr(BitsShiftedOff, One);
4960 llvm::Value *
Zero = llvm::ConstantInt::get(BitsShiftedOff->getType(), 0);
4961 llvm::Value *ValidBase = Builder.CreateICmpEQ(BitsShiftedOff,
Zero);
4963 llvm::PHINode *BaseCheck = Builder.CreatePHI(ValidBase->getType(), 2);
4964 BaseCheck->addIncoming(Builder.getTrue(), Orig);
4965 BaseCheck->addIncoming(ValidBase, CheckShiftBase);
4966 Checks.push_back(std::make_pair(
4967 BaseCheck, SanitizeSignedBase ? SanitizerKind::SO_ShiftBase
4968 : SanitizerKind::SO_UnsignedShiftBase));
4971 assert(!Checks.empty());
4972 EmitBinOpCheck(Checks, Ops);
4975 return Builder.CreateShl(Ops.LHS, RHS,
"shl");
4978Value *ScalarExprEmitter::EmitShr(
const BinOpInfo &Ops) {
4980 if (Ops.isFixedPointOp())
4981 return EmitFixedPointBinOp(Ops);
4985 Value *RHS = Ops.RHS;
4986 if (Ops.LHS->getType() != RHS->
getType())
4987 RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(),
false,
"sh_prom");
4991 RHS = ConstrainShiftValue(Ops.LHS, RHS,
"shr.mask");
4992 else if (CGF.
SanOpts.
has(SanitizerKind::ShiftExponent) &&
4994 SanitizerDebugLocation SanScope(&CGF, {SanitizerKind::SO_ShiftExponent},
4995 SanitizerHandler::ShiftOutOfBounds);
4996 bool RHSIsSigned = Ops.rhsHasSignedIntegerRepresentation();
4997 llvm::Value *
Valid = Builder.CreateICmpULE(
4998 Ops.RHS, GetMaximumShiftAmount(Ops.LHS, Ops.RHS, RHSIsSigned));
4999 EmitBinOpCheck(std::make_pair(
Valid, SanitizerKind::SO_ShiftExponent), Ops);
5002 if (Ops.Ty->hasUnsignedIntegerRepresentation())
5003 return Builder.CreateLShr(Ops.LHS, RHS,
"shr");
5004 return Builder.CreateAShr(Ops.LHS, RHS,
"shr");
5012 default: llvm_unreachable(
"unexpected element type");
5013 case BuiltinType::Char_U:
5014 case BuiltinType::UChar:
5015 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5016 llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
5017 case BuiltinType::Char_S:
5018 case BuiltinType::SChar:
5019 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
5020 llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
5021 case BuiltinType::UShort:
5022 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5023 llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
5024 case BuiltinType::Short:
5025 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
5026 llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
5027 case BuiltinType::UInt:
5028 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5029 llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
5030 case BuiltinType::Int:
5031 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
5032 llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
5033 case BuiltinType::ULong:
5034 case BuiltinType::ULongLong:
5035 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5036 llvm::Intrinsic::ppc_altivec_vcmpgtud_p;
5037 case BuiltinType::Long:
5038 case BuiltinType::LongLong:
5039 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequd_p :
5040 llvm::Intrinsic::ppc_altivec_vcmpgtsd_p;
5041 case BuiltinType::Float:
5042 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
5043 llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
5044 case BuiltinType::Double:
5045 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_vsx_xvcmpeqdp_p :
5046 llvm::Intrinsic::ppc_vsx_xvcmpgtdp_p;
5047 case BuiltinType::UInt128:
5048 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5049 : llvm::Intrinsic::ppc_altivec_vcmpgtuq_p;
5050 case BuiltinType::Int128:
5051 return (IT ==
VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequq_p
5052 : llvm::Intrinsic::ppc_altivec_vcmpgtsq_p;
5056Value *ScalarExprEmitter::EmitCompare(
const BinaryOperator *E,
5057 llvm::CmpInst::Predicate UICmpOpc,
5058 llvm::CmpInst::Predicate SICmpOpc,
5059 llvm::CmpInst::Predicate FCmpOpc,
5061 TestAndClearIgnoreResultAssign();
5065 if (
const MemberPointerType *MPT = LHSTy->
getAs<MemberPointerType>()) {
5071 CGF, LHS, RHS, MPT, E->
getOpcode() == BO_NE);
5073 BinOpInfo BOInfo = EmitBinOps(E);
5074 Value *LHS = BOInfo.LHS;
5075 Value *RHS = BOInfo.RHS;
5081 enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
5083 llvm::Intrinsic::ID
ID = llvm::Intrinsic::not_intrinsic;
5086 Value *FirstVecArg = LHS,
5087 *SecondVecArg = RHS;
5089 QualType ElTy = LHSTy->
castAs<VectorType>()->getElementType();
5093 default: llvm_unreachable(
"is not a comparison operation");
5105 std::swap(FirstVecArg, SecondVecArg);
5112 if (ElementKind == BuiltinType::Float) {
5114 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5115 std::swap(FirstVecArg, SecondVecArg);
5123 if (ElementKind == BuiltinType::Float) {
5125 ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
5130 std::swap(FirstVecArg, SecondVecArg);
5135 Value *CR6Param = Builder.getInt32(CR6);
5137 Result = Builder.CreateCall(F, {CR6Param, FirstVecArg, SecondVecArg});
5145 if (ResultTy->getBitWidth() > 1 &&
5147 Result = Builder.CreateTrunc(
Result, Builder.getInt1Ty());
5152 if (BOInfo.isFixedPointOp()) {
5153 Result = EmitFixedPointBinOp(BOInfo);
5154 }
else if (LHS->
getType()->isFPOrFPVectorTy()) {
5155 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, BOInfo.FPFeatures);
5157 Result = Builder.CreateFCmp(FCmpOpc, LHS, RHS,
"cmp");
5159 Result = Builder.CreateFCmpS(FCmpOpc, LHS, RHS,
"cmp");
5161 Result = Builder.CreateICmp(SICmpOpc, LHS, RHS,
"cmp");
5176 LHS = Builder.CreateStripInvariantGroup(LHS);
5178 RHS = Builder.CreateStripInvariantGroup(RHS);
5181 Result = Builder.CreateICmp(UICmpOpc, LHS, RHS,
"cmp");
5187 return Builder.CreateSExt(
Result, ConvertType(E->
getType()),
"sext");
5193 if (
auto *CTy = LHSTy->
getAs<ComplexType>()) {
5195 CETy = CTy->getElementType();
5197 LHS.first = Visit(E->
getLHS());
5198 LHS.second = llvm::Constant::getNullValue(LHS.first->getType());
5201 if (
auto *CTy = RHSTy->
getAs<ComplexType>()) {
5204 CTy->getElementType()) &&
5205 "The element types must always match.");
5208 RHS.first = Visit(E->
getRHS());
5209 RHS.second = llvm::Constant::getNullValue(RHS.first->getType());
5211 "The element types must always match.");
5214 Value *ResultR, *ResultI;
5218 ResultR = Builder.CreateFCmp(FCmpOpc, LHS.first, RHS.first,
"cmp.r");
5219 ResultI = Builder.CreateFCmp(FCmpOpc, LHS.second, RHS.second,
"cmp.i");
5223 ResultR = Builder.CreateICmp(UICmpOpc, LHS.first, RHS.first,
"cmp.r");
5224 ResultI = Builder.CreateICmp(UICmpOpc, LHS.second, RHS.second,
"cmp.i");
5228 Result = Builder.CreateAnd(ResultR, ResultI,
"and.ri");
5231 "Complex comparison other than == or != ?");
5232 Result = Builder.CreateOr(ResultR, ResultI,
"or.ri");
5244 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E->
getRHS())) {
5245 CastKind Kind = ICE->getCastKind();
5246 if (Kind == CK_IntegralCast || Kind == CK_LValueToRValue) {
5247 *SrcType = ICE->getSubExpr()->getType();
5260 bool Ignore = TestAndClearIgnoreResultAssign();
5294 RHS = Visit(E->
getRHS());
5310 RHS = Visit(E->
getRHS());
5350 return EmitLoadOfLValue(LHS, E->
getExprLoc());
5353Value *ScalarExprEmitter::VisitBinLAnd(
const BinaryOperator *E) {
5361 if (LHS->
getType()->isFPOrFPVectorTy()) {
5362 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5364 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5365 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5367 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5368 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5370 Value *
And = Builder.CreateAnd(LHS, RHS);
5371 return Builder.CreateSExt(
And, ConvertType(E->
getType()),
"sext");
5375 llvm::Type *ResTy = ConvertType(E->
getType());
5396 if (InstrumentRegions &&
5401 Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock);
5415 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"land.ext");
5421 return llvm::Constant::getNullValue(ResTy);
5434 CodeGenFunction::ConditionalEvaluation eval(CGF);
5443 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5445 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5447 PN->addIncoming(llvm::ConstantInt::getFalse(VMContext), *PI);
5456 RHSBlock = Builder.GetInsertBlock();
5461 if (InstrumentRegions &&
5465 Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock);
5469 PN->addIncoming(RHSCond, RHSBlockCnt);
5479 PN->addIncoming(RHSCond, RHSBlock);
5489 PN->setDebugLoc(Builder.getCurrentDebugLocation());
5493 return Builder.CreateZExtOrBitCast(PN, ResTy,
"land.ext");
5496Value *ScalarExprEmitter::VisitBinLOr(
const BinaryOperator *E) {
5504 if (LHS->
getType()->isFPOrFPVectorTy()) {
5505 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(
5507 LHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, LHS,
Zero,
"cmp");
5508 RHS = Builder.CreateFCmp(llvm::CmpInst::FCMP_UNE, RHS,
Zero,
"cmp");
5510 LHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, LHS,
Zero,
"cmp");
5511 RHS = Builder.CreateICmp(llvm::CmpInst::ICMP_NE, RHS,
Zero,
"cmp");
5513 Value *
Or = Builder.CreateOr(LHS, RHS);
5514 return Builder.CreateSExt(
Or, ConvertType(E->
getType()),
"sext");
5518 llvm::Type *ResTy = ConvertType(E->
getType());
5539 if (InstrumentRegions &&
5544 Builder.CreateCondBr(RHSCond, FBlock, RHSBlockCnt);
5558 return Builder.CreateZExtOrBitCast(RHSCond, ResTy,
"lor.ext");
5564 return llvm::ConstantInt::get(ResTy, 1);
5577 CodeGenFunction::ConditionalEvaluation eval(CGF);
5587 llvm::PHINode *PN = llvm::PHINode::Create(llvm::Type::getInt1Ty(VMContext), 2,
5589 for (llvm::pred_iterator PI = pred_begin(ContBlock), PE = pred_end(ContBlock);
5591 PN->addIncoming(llvm::ConstantInt::getTrue(VMContext), *PI);
5603 RHSBlock = Builder.GetInsertBlock();
5608 if (InstrumentRegions &&
5612 Builder.CreateCondBr(RHSCond, ContBlock, RHSBlockCnt);
5616 PN->addIncoming(RHSCond, RHSBlockCnt);
5622 PN->addIncoming(RHSCond, RHSBlock);
5630 return Builder.CreateZExtOrBitCast(PN, ResTy,
"lor.ext");
5633Value *ScalarExprEmitter::VisitBinComma(
const BinaryOperator *E) {
5636 return Visit(E->
getRHS());
5661Value *ScalarExprEmitter::
5662VisitAbstractConditionalOperator(
const AbstractConditionalOperator *E) {
5663 TestAndClearIgnoreResultAssign();
5666 CodeGenFunction::OpaqueValueMapping binding(CGF, E);
5668 Expr *condExpr = E->
getCond();
5676 Expr *live = lhsExpr, *dead = rhsExpr;
5677 if (!CondExprBool) std::swap(live, dead);
5708 llvm::Value *LHS = Visit(lhsExpr);
5709 llvm::Value *RHS = Visit(rhsExpr);
5711 llvm::Type *condType = ConvertType(condExpr->
getType());
5714 unsigned numElem = vecTy->getNumElements();
5715 llvm::Type *elemType = vecTy->getElementType();
5717 llvm::Value *zeroVec = llvm::Constant::getNullValue(vecTy);
5718 llvm::Value *TestMSB = Builder.CreateICmpSLT(CondV, zeroVec);
5719 llvm::Value *tmp = Builder.CreateSExt(
5720 TestMSB, llvm::FixedVectorType::get(elemType, numElem),
"sext");
5721 llvm::Value *tmp2 = Builder.CreateNot(tmp);
5724 llvm::Value *RHSTmp = RHS;
5725 llvm::Value *LHSTmp = LHS;
5726 bool wasCast =
false;
5728 if (rhsVTy->getElementType()->isFloatingPointTy()) {
5729 RHSTmp = Builder.CreateBitCast(RHS, tmp2->getType());
5730 LHSTmp = Builder.CreateBitCast(LHS, tmp->getType());
5734 llvm::Value *tmp3 = Builder.CreateAnd(RHSTmp, tmp2);
5735 llvm::Value *tmp4 = Builder.CreateAnd(LHSTmp, tmp);
5736 llvm::Value *tmp5 = Builder.CreateOr(tmp3, tmp4,
"cond");
5738 tmp5 = Builder.CreateBitCast(tmp5, RHS->getType());
5748 llvm::Value *LHS = Visit(lhsExpr);
5749 llvm::Value *RHS = Visit(rhsExpr);
5751 llvm::Type *CondType = ConvertType(condExpr->
getType());
5754 if (VecTy->getElementType()->isIntegerTy(1))
5755 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5758 llvm::Value *ZeroVec = llvm::Constant::getNullValue(VecTy);
5760 CondV = Builder.CreateICmpSLT(CondV, ZeroVec,
"vector_cond");
5762 CondV = Builder.CreateICmpNE(CondV, ZeroVec,
"vector_cond");
5763 return Builder.CreateSelect(CondV, LHS, RHS,
"vector_select");
5772 llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.
Int64Ty);
5781 llvm::Value *LHS = Visit(lhsExpr);
5782 llvm::Value *RHS = Visit(rhsExpr);
5785 assert(!RHS &&
"LHS and RHS types must match");
5788 return Builder.CreateSelect(CondV, LHS, RHS,
"cond");
5799 CodeGenFunction::ConditionalEvaluation eval(CGF);
5817 Value *LHS = Visit(lhsExpr);
5820 LHSBlock = Builder.GetInsertBlock();
5821 Builder.CreateBr(ContBlock);
5835 Value *RHS = Visit(rhsExpr);
5838 RHSBlock = Builder.GetInsertBlock();
5848 llvm::PHINode *PN = Builder.CreatePHI(LHS->
getType(), 2,
"cond");
5849 PN->addIncoming(LHS, LHSBlock);
5850 PN->addIncoming(RHS, RHSBlock);
5860Value *ScalarExprEmitter::VisitChooseExpr(ChooseExpr *E) {
5864Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
5866 RValue ArgPtr = CGF.
EmitVAArg(VE, ArgValue);
5871Value *ScalarExprEmitter::VisitBlockExpr(
const BlockExpr *block) {
5877 Value *Src,
unsigned NumElementsDst) {
5878 static constexpr int Mask[] = {0, 1, 2, -1};
5879 return Builder.CreateShuffleVector(Src,
llvm::ArrayRef(Mask, NumElementsDst));
5899 const llvm::DataLayout &DL,
5900 Value *Src, llvm::Type *DstTy,
5901 StringRef Name =
"") {
5905 if (!SrcTy->isPointerTy() && !DstTy->isPointerTy())
5906 return Builder.CreateBitCast(Src, DstTy, Name);
5909 if (SrcTy->isPointerTy() && DstTy->isPointerTy())
5910 return Builder.CreatePointerBitCastOrAddrSpaceCast(Src, DstTy, Name);
5913 if (SrcTy->isPointerTy() && !DstTy->isPointerTy()) {
5915 if (!DstTy->isIntegerTy())
5916 Src = Builder.CreatePtrToInt(Src, DL.getIntPtrType(SrcTy));
5918 return Builder.CreateBitOrPointerCast(Src, DstTy, Name);
5922 if (!SrcTy->isIntegerTy())
5923 Src = Builder.CreateBitCast(Src, DL.getIntPtrType(DstTy));
5925 return Builder.CreateIntToPtr(Src, DstTy, Name);
5928Value *ScalarExprEmitter::VisitAsTypeExpr(AsTypeExpr *E) {
5930 llvm::Type *DstTy = ConvertType(E->
getType());
5932 llvm::Type *SrcTy = Src->
getType();
5933 unsigned NumElementsSrc =
5937 unsigned NumElementsDst =
5948 if (NumElementsSrc == 3 && NumElementsDst != 3) {
5953 Src->setName(
"astype");
5960 if (NumElementsSrc != 3 && NumElementsDst == 3) {
5961 auto *Vec4Ty = llvm::FixedVectorType::get(
5967 Src->setName(
"astype");
5972 Src, DstTy,
"astype");
5975Value *ScalarExprEmitter::VisitAtomicExpr(AtomicExpr *E) {
5987 "Invalid scalar expression to emit");
5989 return ScalarExprEmitter(*
this, IgnoreResultAssign)
5990 .Visit(
const_cast<Expr *
>(E));
5999 "Invalid scalar expression to emit");
6000 return ScalarExprEmitter(*this).EmitScalarConversion(Src, SrcTy, DstTy, Loc);
6010 "Invalid complex -> scalar conversion");
6011 return ScalarExprEmitter(*
this)
6012 .EmitComplexToScalarConversion(Src, SrcTy, DstTy, Loc);
6019 if (!PromotionType.
isNull())
6020 return ScalarExprEmitter(*this).EmitPromoted(E, PromotionType);
6022 return ScalarExprEmitter(*this).Visit(
const_cast<Expr *
>(E));
6028 bool isInc,
bool isPre) {
6029 return ScalarExprEmitter(*this).EmitScalarPrePostIncDec(E, LV, isInc, isPre);
6039 llvm::Type *BaseTy =
6055 ScalarExprEmitter Scalar(*
this);
6058#define COMPOUND_OP(Op) \
6059 case BO_##Op##Assign: \
6060 return Scalar.EmitCompoundAssignLValue(E, &ScalarExprEmitter::Emit##Op, \
6097 llvm_unreachable(
"Not valid compound assignment operators");
6100 llvm_unreachable(
"Unhandled compound assignment operator");
6115 llvm::LLVMContext &VMContext,
6121 llvm::Value *TotalOffset =
nullptr;
6127 Value *BasePtr_int =
6128 Builder.CreatePtrToInt(BasePtr, DL.getIntPtrType(BasePtr->
getType()));
6130 Builder.CreatePtrToInt(GEPVal, DL.getIntPtrType(GEPVal->
getType()));
6131 TotalOffset = Builder.CreateSub(GEPVal_int, BasePtr_int);
6132 return {TotalOffset, Builder.getFalse()};
6136 assert(GEP->getPointerOperand() == BasePtr &&
6137 "BasePtr must be the base of the GEP.");
6138 assert(GEP->isInBounds() &&
"Expected inbounds GEP");
6140 auto *IntPtrTy = DL.getIntPtrType(GEP->getPointerOperandType());
6143 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6144 auto *SAddIntrinsic =
6145 CGM.
getIntrinsic(llvm::Intrinsic::sadd_with_overflow, IntPtrTy);
6146 auto *SMulIntrinsic =
6147 CGM.
getIntrinsic(llvm::Intrinsic::smul_with_overflow, IntPtrTy);
6150 llvm::Value *OffsetOverflows = Builder.getFalse();
6154 llvm::Value *RHS) -> llvm::Value * {
6155 assert((Opcode == BO_Add || Opcode == BO_Mul) &&
"Can't eval binop");
6158 if (
auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS)) {
6159 if (
auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS)) {
6161 bool HasOverflow = mayHaveIntegerOverflow(LHSCI, RHSCI, Opcode,
6164 OffsetOverflows = Builder.getTrue();
6165 return llvm::ConstantInt::get(VMContext, N);
6170 auto *ResultAndOverflow = Builder.CreateCall(
6171 (Opcode == BO_Add) ? SAddIntrinsic : SMulIntrinsic, {LHS, RHS});
6172 OffsetOverflows = Builder.CreateOr(
6173 Builder.CreateExtractValue(ResultAndOverflow, 1), OffsetOverflows);
6174 return Builder.CreateExtractValue(ResultAndOverflow, 0);
6178 for (
auto GTI = llvm::gep_type_begin(GEP), GTE = llvm::gep_type_end(GEP);
6179 GTI != GTE; ++GTI) {
6180 llvm::Value *LocalOffset;
6181 auto *Index = GTI.getOperand();
6183 if (
auto *STy = GTI.getStructTypeOrNull()) {
6187 LocalOffset = llvm::ConstantInt::get(
6188 IntPtrTy, DL.getStructLayout(STy)->getElementOffset(FieldNo));
6193 llvm::ConstantInt::get(IntPtrTy, GTI.getSequentialElementStride(DL));
6194 auto *IndexS = Builder.CreateIntCast(Index, IntPtrTy,
true);
6195 LocalOffset = eval(BO_Mul, ElementSize, IndexS);
6200 if (!TotalOffset || TotalOffset ==
Zero)
6201 TotalOffset = LocalOffset;
6203 TotalOffset = eval(BO_Add, TotalOffset, LocalOffset);
6206 return {TotalOffset, OffsetOverflows};
6211 ArrayRef<Value *> IdxList,
6212 bool SignedIndices,
bool IsSubtraction,
6213 SourceLocation Loc,
const Twine &Name) {
6214 llvm::Type *PtrTy = Ptr->
getType();
6216 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6217 if (!SignedIndices && !IsSubtraction)
6218 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6220 Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags);
6223 if (!SanOpts.has(SanitizerKind::PointerOverflow))
6227 bool PerformNullCheck = !NullPointerIsDefined(
6228 Builder.GetInsertBlock()->getParent(), PtrTy->getPointerAddressSpace());
6231 bool PerformOverflowCheck =
6234 if (!(PerformNullCheck || PerformOverflowCheck))
6237 const auto &DL = CGM.getDataLayout();
6239 auto CheckOrdinal = SanitizerKind::SO_PointerOverflow;
6240 auto CheckHandler = SanitizerHandler::PointerOverflow;
6241 SanitizerDebugLocation SanScope(
this, {CheckOrdinal}, CheckHandler);
6242 llvm::Type *IntPtrTy = DL.getIntPtrType(PtrTy);
6244 GEPOffsetAndOverflow EvaluatedGEP =
6249 "If the offset got constant-folded, we don't expect that there was an "
6252 auto *
Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
6260 auto *IntPtr = Builder.CreatePtrToInt(Ptr, IntPtrTy);
6261 auto *ComputedGEP = Builder.CreateAdd(IntPtr, EvaluatedGEP.
TotalOffset);
6263 llvm::SmallVector<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>,
6267 if (PerformNullCheck) {
6275 auto *BaseIsNotNullptr = Builder.CreateIsNotNull(Ptr);
6276 auto *ResultIsNotNullptr = Builder.CreateIsNotNull(ComputedGEP);
6277 auto *
Valid = Builder.CreateICmpEQ(BaseIsNotNullptr, ResultIsNotNullptr);
6278 Checks.emplace_back(
Valid, CheckOrdinal);
6281 if (PerformOverflowCheck) {
6286 llvm::Value *ValidGEP;
6287 auto *NoOffsetOverflow = Builder.CreateNot(EvaluatedGEP.
OffsetOverflows);
6288 if (SignedIndices) {
6294 auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6295 auto *PosOrZeroOffset =
6297 llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
6299 Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid);
6300 }
else if (!IsSubtraction) {
6305 ValidGEP = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
6311 ValidGEP = Builder.CreateICmpULE(ComputedGEP, IntPtr);
6313 ValidGEP = Builder.CreateAnd(ValidGEP, NoOffsetOverflow);
6314 Checks.emplace_back(ValidGEP, CheckOrdinal);
6317 assert(!Checks.empty() &&
"Should have produced some checks.");
6319 llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
6321 llvm::Value *DynamicArgs[] = {IntPtr, ComputedGEP};
6322 EmitCheck(Checks, CheckHandler, StaticArgs, DynamicArgs);
6328 Address
Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType,
6329 bool SignedIndices,
bool IsSubtraction, SourceLocation Loc, CharUnits Align,
6330 const Twine &Name) {
6331 if (!SanOpts.has(SanitizerKind::PointerOverflow)) {
6332 llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds();
6333 if (!SignedIndices && !IsSubtraction)
6334 NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap();
6336 return Builder.CreateGEP(
Addr, IdxList, elementType, Align, Name, NWFlags);
6340 EmitCheckedInBoundsGEP(
Addr.getElementType(),
Addr.emitRawPointer(*
this),
6341 IdxList, SignedIndices, IsSubtraction, Loc, Name),
6342 elementType, Align);
Defines the clang::ASTContext interface.
static llvm::Value * EmitCompare(CGBuilderTy &Builder, CodeGenFunction &CGF, const BinaryOperator *E, llvm::Value *LHS, llvm::Value *RHS, CompareKind Kind, const char *NameSuffix="")
static void EmitHLSLElementwiseCast(CodeGenFunction &CGF, LValue DestVal, LValue SrcVal, SourceLocation Loc)
static int getAsInt32(llvm::ConstantInt *C, llvm::Type *I32Ty)
static llvm::Value * EmitIsNegativeTestHelper(Value *V, QualType VType, const char *Name, CGBuilderTy &Builder)
static Value * createCastsForTypeOfSameSize(CGBuilderTy &Builder, const llvm::DataLayout &DL, Value *Src, llvm::Type *DstTy, StringRef Name="")
static bool isLValueKnownNonNull(CodeGenFunction &CGF, const Expr *E)
static bool matchesPostDecrInWhile(const UnaryOperator *UO, bool isInc, bool isPre, ASTContext &Ctx)
For the purposes of overflow pattern exclusion, does this match the "while(i--)" pattern?
static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT, BuiltinType::Kind ElemKind)
static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal, llvm::LLVMContext &VMContext, CodeGenModule &CGM, CGBuilderTy &Builder)
Evaluate given GEPVal, which is either an inbounds GEP, or a constant, and compute the total offset i...
static bool isDeclRefKnownNonNull(CodeGenFunction &CGF, const ValueDecl *D)
static bool PromotionIsPotentiallyEligibleForImplicitIntegerConversionCheck(QualType SrcType, QualType DstType)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitBitfieldTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static Value * buildFMulAdd(llvm::Instruction *MulOp, Value *Addend, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool negMul, bool negAdd)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitBitfieldSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitIntegerSignChangeCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static int getMaskElt(llvm::ShuffleVectorInst *SVI, unsigned Idx, unsigned Off)
static std::pair< ScalarExprEmitter::ImplicitConversionCheckKind, std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > EmitIntegerTruncationCheckHelper(Value *Src, QualType SrcType, Value *Dst, QualType DstType, CGBuilderTy &Builder)
static Value * ConvertVec3AndVec4(CGBuilderTy &Builder, CodeGenFunction &CGF, Value *Src, unsigned NumElementsDst)
static Value * tryEmitFMulAdd(const BinOpInfo &op, const CodeGenFunction &CGF, CGBuilderTy &Builder, bool isSub=false)
static BinOpInfo createBinOpInfoFromIncDec(const UnaryOperator *E, llvm::Value *InVal, bool IsInc, FPOptions FPFeatures)
static mlir::Value emitPointerArithmetic(CIRGenFunction &cgf, const BinOpInfo &op, bool isSubtraction)
Emit pointer + index arithmetic.
static bool isCheapEnoughToEvaluateUnconditionally(const Expr *e, CIRGenFunction &cgf)
Return true if the specified expression is cheap enough and side-effect-free enough to evaluate uncon...
static std::optional< QualType > getUnwidenedIntegerType(const ASTContext &astContext, const Expr *e)
If e is a widened promoted integer, get its base (unpromoted) type.
static uint32_t getBitWidth(const Expr *E)
static Decl::Kind getKind(const Decl *D)
static QualType getPointeeType(const MemRegion *R)
This file contains the declaration of TrapReasonBuilder and related classes.
llvm::APInt getValue() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
ParentMapContext & getParentMapContext()
Returns the dynamic AST node parent map context.
unsigned getIntWidth(QualType T) const
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
bool isTypeIgnoredBySanitizer(const SanitizerMask &Mask, const QualType &Ty) const
Check if a type can have its sanitizer instrumentation elided based on its presence within an ignorel...
unsigned getOpenMPDefaultSimdAlign(QualType T) const
Get default simd alignment of the specified complete type in bits.
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
const VariableArrayType * getAsVariableArrayType(QualType T) const
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
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
unsigned getTargetAddressSpace(LangAS AS) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
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...
LabelDecl * getLabel() const
uint64_t getValue() const
QualType getElementType() const
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
A builtin binary operation expression such as "x + y" or "x <= y".
static Opcode getOpForCompoundAssignment(Opcode Opc)
bool isCompoundAssignmentOp() const
SourceLocation getExprLoc() const
bool isShiftAssignOp() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc, const Expr *LHS, const Expr *RHS)
Return true if a binary operator using the specified opcode and operands would match the 'p = (i8*)nu...
BinaryOperatorKind Opcode
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
Expr * getExpr()
Get the initialization expression that will be used.
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.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
bool changesVolatileQualification() const
Return.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
bool isOne() const
isOne - Test whether the quantity equals one.
unsigned getValue() const
Expr * getChosenSubExpr() const
getChosenSubExpr - Return the subexpression chosen according to the condition.
bool hasProfileClangInstr() const
Check if Clang profile instrumenation is on.
SanitizerSet SanitizeTrap
Set of sanitizer checks that trap rather than diagnose.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
A scoped helper to set the current source atom group for CGDebugInfo::addInstToCurrentSourceAtom.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
virtual llvm::Value * EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Value *MemPtr, const MemberPointerType *MPT)
Determine if a member pointer is non-null. Returns an i1.
virtual llvm::Value * EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, llvm::Value *R, const MemberPointerType *MPT, bool Inequality)
Emit a comparison between two member pointers. Returns an i1.
virtual llvm::Value * EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src)
Perform a derived-to-base, base-to-derived, or bitcast member pointer conversion.
void EmitPseudoVariable(CGBuilderTy &Builder, llvm::Instruction *Value, QualType Ty)
Emit a pseudo variable and debug info for an intermediate value if it does not correspond to a variab...
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
void emitInitListOpaqueValues(CodeGenFunction &CGF, InitListExpr *E)
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 ...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)
Produce the code for a CK_ARCConsumeObject.
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())
llvm::Value * emitBoolVecConversion(llvm::Value *SrcVec, unsigned NumElementsDst, const llvm::Twine &Name="")
CurrentSourceLocExprScope CurSourceLocExprScope
Source location information about the default argument or member initializer expression we're evaluat...
llvm::Value * EmitARCReclaimReturnedObject(const Expr *e, bool allowUnsafeClaim)
std::pair< LValue, llvm::Value * > EmitARCStoreAutoreleasing(const BinaryOperator *e)
void SetDivFPAccuracy(llvm::Value *Val)
Set the minimum required accuracy of the given sqrt operation based on CodeGenOpts.
llvm::Value * EmitObjCSelectorExpr(const ObjCSelectorExpr *E)
Emit a selector.
SanitizerSet SanOpts
Sanitizers enabled for this function.
RawAddress CreateIRTemp(QualType T, const Twine &Name="tmp")
CreateIRTemp - Create a temporary IR object of the given type, with appropriate alignment.
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
llvm::Value * EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E)
llvm::BlockAddress * GetAddrOfLabel(const LabelDecl *L)
const CastExpr * CurCast
If a cast expression is being visited, this holds the current cast's expression.
static bool hasScalarEvaluationKind(QualType T)
llvm::Type * ConvertType(QualType T)
llvm::Value * EmitObjCProtocolExpr(const ObjCProtocolExpr *E)
llvm::Value * EmitPointerAuthQualify(PointerAuthQualifier Qualifier, llvm::Value *Pointer, QualType ValueType, Address StorageAddress, bool IsKnownNonNull)
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
LValue EmitObjCIsaExpr(const ObjCIsaExpr *E)
void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, llvm::Value **Result=nullptr)
EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints as EmitStoreThroughLValue.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
llvm::Value * EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre)
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.
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
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 maybeUpdateMCDCTestVectorBitmap(const Expr *E)
Increment the profiler's counter for the given expression by StepV.
void EmitCXXDeleteExpr(const CXXDeleteExpr *E)
llvm::Value * EmitObjCArrayLiteral(const ObjCArrayLiteral *E)
llvm::Value * EmitPromotedScalarExpr(const Expr *E, QualType PromotionType)
const LangOptions & getLangOpts() const
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
Store into a strong object.
bool isPointerKnownNonNull(const Expr *E)
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc)
Given an assignment *LHS = RHS, emit a test that checks if RHS is nonnull, if LHS is marked _Nonnull.
llvm::Value * EmitPointerAuthUnqualify(PointerAuthQualifier Qualifier, llvm::Value *Pointer, QualType PointerType, Address StorageAddress, bool IsKnownNonNull)
std::pair< RValue, llvm::Value * > EmitAtomicCompareExchange(LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc, llvm::AtomicOrdering Success=llvm::AtomicOrdering::SequentiallyConsistent, llvm::AtomicOrdering Failure=llvm::AtomicOrdering::SequentiallyConsistent, bool IsWeak=false, AggValueSlot Slot=AggValueSlot::ignored())
Emit a compare-and-exchange op for atomic type.
void EmitVTablePtrCheckForCast(QualType T, Address Derived, bool MayBeNull, CFITypeCheckKind TCK, SourceLocation Loc)
Derived is the presumed address of an object of type T after a cast.
TypeCheckKind
Situations in which we might emit a check for the suitability of a pointer or glvalue.
@ TCK_DowncastPointer
Checking the operand of a static_cast to a derived pointer type.
@ TCK_Store
Checking the destination of a store. Must be suitably sized and aligned.
@ TCK_Load
Checking the operand of a load. Must be suitably sized and aligned.
llvm::Value * EmitCXXNewExpr(const CXXNewExpr *E)
void EmitBitfieldConversionCheck(llvm::Value *Src, QualType SrcType, llvm::Value *Dst, QualType DstType, const CGBitFieldInfo &Info, SourceLocation Loc)
Emit a check that an [implicit] conversion of a bitfield.
std::pair< LValue, llvm::Value * > EmitARCStoreUnsafeUnretained(const BinaryOperator *e, bool ignored)
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
LValue EmitScalarCompoundAssignWithComplex(const CompoundAssignOperator *E, llvm::Value *&Result)
RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...
const TargetInfo & getTarget() const
LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E)
llvm::Value * EmitBlockCopyAndAutorelease(llvm::Value *Block, QualType Ty)
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)
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type,...
static bool isInstrumentedCondition(const Expr *C)
isInstrumentedCondition - Determine whether the given condition is an instrumentable condition (i....
VlaSizePair getVLAElements1D(const VariableArrayType *vla)
Return the number of elements for a single dimension for the given array type.
llvm::Value * EmitObjCBoxedExpr(const ObjCBoxedExpr *E)
EmitObjCBoxedExpr - This routine generates code to call the appropriate expression boxing method.
void EmitBoundsCheck(const Expr *ArrayExpr, const Expr *ArrayExprBase, llvm::Value *Index, QualType IndexType, bool Accessed)
Emit a check that Base points into an array object, which we can access at index Index.
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
void maybeResetMCDCCondBitmap(const Expr *E)
Zero-init the MCDC temp value.
RValue EmitCoyieldExpr(const CoyieldExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
SmallVector< const BinaryOperator *, 16 > MCDCLogOpStack
Stack to track the Logical Operator recursion nest for MC/DC.
RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its RValue mapping if it exists, otherwise create one.
CGDebugInfo * getDebugInfo()
llvm::Value * emitScalarConstant(const ConstantEmission &Constant, Expr *E)
llvm::Value * EmitARCRetainScalarExpr(const Expr *expr)
EmitARCRetainScalarExpr - Semantically equivalent to EmitARCRetainObject(e->getType(),...
llvm::Value * EmitBlockLiteral(const BlockExpr *)
Emit block literal.
llvm::Value * EmitToMemory(llvm::Value *Value, QualType Ty)
EmitToMemory - Change a scalar value from its value representation to its in-memory representation.
void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val)
Update the MCDC temp value with the condition's evaluated result.
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,...
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitWithOriginalRHSBitfieldAssignment(const BinaryOperator *E, llvm::Value **Previous, QualType *SrcType)
Retrieve the implicit cast expression of the rhs in a binary operator expression by passing pointers ...
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 EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
Address EmitArrayToPointerDecay(const Expr *Array, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
Address EmitCompoundStmt(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
EmitCompoundStmt - Emit a compound statement {..} node.
llvm::AtomicRMWInst * emitAtomicRMWInst(llvm::AtomicRMWInst::BinOp Op, Address Addr, llvm::Value *Val, llvm::AtomicOrdering Order=llvm::AtomicOrdering::SequentiallyConsistent, llvm::SyncScope::ID SSID=llvm::SyncScope::System, const AtomicExpr *AE=nullptr)
Emit an atomicrmw instruction, and applying relevant metadata when applicable.
llvm::Value * EmitPointerArithmetic(const BinaryOperator *BO, Expr *pointerOperand, llvm::Value *pointer, Expr *indexOperand, llvm::Value *index, bool isSubtraction)
Emit pointer + index arithmetic.
RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
EmitAnyExpr - Emit code to compute the specified expression which can have any type.
uint64_t getCurrentProfileCount()
Get the profiler's current count.
llvm::Type * ConvertTypeForMem(QualType T)
RValue EmitAtomicExpr(AtomicExpr *E)
void markStmtMaybeUsed(const Stmt *S)
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
void FlattenAccessAndTypeLValue(LValue LVal, SmallVectorImpl< LValue > &AccessList)
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, QualType Type, SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
RValue EmitCoawaitExpr(const CoawaitExpr &E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
llvm::Value * authPointerToPointerCast(llvm::Value *ResultPtr, QualType SourceType, QualType DestType)
Address EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitPointerWithAlignment - Given an expression with a pointer type, emit the value and compute our be...
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)
Same as EmitLValue but additionally we generate checking code to guard against undefined behavior.
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
llvm::Type * convertTypeForLoadStore(QualType ASTTy, llvm::Type *LLVMTy=nullptr)
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
llvm::Value * EmitCheckedInBoundsGEP(llvm::Type *ElemTy, llvm::Value *Ptr, ArrayRef< llvm::Value * > IdxList, bool SignedIndices, bool IsSubtraction, SourceLocation Loc, const Twine &Name="")
Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to detect undefined behavior whe...
llvm::Value * EmitBuiltinAvailable(const VersionTuple &Version)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
llvm::Value * EmitMatrixIndexExpr(const Expr *E)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID, bool NoMerge=false, const TrapReason *TR=nullptr)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation.
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
llvm::Value * getArrayInitIndex()
Get the index of the current ArrayInitLoopExpr, if any.
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...
llvm::Value * EmitObjCStringLiteral(const ObjCStringLiteral *E)
Emits an instance of NSConstantString representing the object.
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::Value * EmitARCExtendBlockObject(const Expr *expr)
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
i8* @objc_storeWeak(i8** addr, i8* value) Returns value.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
ComplexPairTy EmitPromotedValue(ComplexPairTy result, QualType PromotionType)
void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
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 EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
static bool ShouldNullCheckClassCastValue(const CastExpr *Cast)
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...
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
This class organizes the cross-function state that is used while generating LLVM code.
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
CGHLSLRuntime & getHLSLRuntime()
Return a reference to the configured HLSL runtime.
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.
TrapReasonBuilder BuildTrapReason(unsigned DiagID, TrapReason &TR)
Helper function to construct a TrapReasonBuilder.
llvm::Constant * getNullPointer(llvm::PointerType *T, QualType QT)
Get target specific null pointer.
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
llvm::Constant * getMemberPointerConstant(const UnaryOperator *e)
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
llvm::Value * createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF)
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
LangAS GetGlobalConstantAddressSpace() const
Return the AST address space of constant literal, which is used to emit the constant literal as globa...
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
LValue - This represents an lvalue references.
bool isVolatileQualified() const
const Qualifiers & getQuals() const
Address getAddress() const
const CGBitFieldInfo & getBitFieldInfo() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, LangAS SrcAddr, llvm::Type *DestTy, bool IsNonNull=false) const
CompoundAssignOperator - For compound assignments (e.g.
QualType getComputationLHSType() const
QualType getComputationResultType() const
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
APValue getAPValueResult() const
bool hasAPValueResult() const
Represents a concrete matrix type with constant number of rows and columns.
Expr * getSrcExpr() const
getSrcExpr - Return the Expr to be converted.
const Expr * getDefaultExpr() const
ChildElementIter< false > begin()
size_t getDataElementCount() const
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
bool isIntegerConstantExpr(const ASTContext &Ctx) const
@ SE_AllowSideEffects
Allow any unmodeled side effect.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts 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...
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
llvm::APInt getValue() const
Returns an internal integer representation of the literal.
llvm::APFloat getValue() const
const Expr * getSubExpr() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
unsigned getNumInits() const
bool hadArrayRangeDesignator() const
const Expr * getInit(unsigned Init) const
@ PostDecrInWhile
while (count–)
bool isSignedOverflowDefined() const
bool isOverflowPatternExcluded(OverflowPatternExclusionKind Kind) const
std::string OverflowHandler
The name of the handler function to be called when -ftrapv is specified.
Represents a matrix type, as defined in the Matrix Types clang extensions.
VersionTuple getVersion() const
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
SourceLocation getExprLoc() const LLVM_READONLY
const ObjCMethodDecl * getMethodDecl() const
QualType getReturnType() const
Represents a pointer to an Objective C object.
const ObjCObjectType * getObjectType() const
Gets the type pointed to by this ObjC pointer.
Expr * getIndexExpr(unsigned Idx)
const OffsetOfNode & getComponent(unsigned Idx) const
TypeSourceInfo * getTypeSourceInfo() const
unsigned getNumComponents() const
unsigned getArrayExprIndex() const
For an array element node, returns the index into the array of expressions.
FieldDecl * getField() const
For a field offsetof node, returns the field.
@ Array
An index into an array.
@ Identifier
A field in a dependent type, known only by its name.
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Kind getKind() const
Determine what kind of offsetof node this is.
CXXBaseSpecifier * getBase() const
For a base class node, returns the base specifier.
SourceLocation getExprLoc() const LLVM_READONLY
Expr * getSelectedExpr() const
const Expr * getSubExpr() const
DynTypedNodeList getParents(const NodeT &Node)
Returns the parents of the given node (within the traversal scope).
Pointer-authentication qualifiers.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
PointerAuthQualifier getPointerAuth() const
bool mayBeDynamicClass() const
Returns true if it is a class and it might be dynamic.
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.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
bool UseExcessPrecision(const ASTContext &Ctx)
bool mayBeNotDynamicClass() const
Returns true if it is not a class or if the class might not be dynamic.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
specific_decl_iterator< FieldDecl > field_iterator
bool isSatisfied() const
Whether or not the requires clause is satisfied.
std::string ComputeName(ASTContext &Context) const
static constexpr SanitizerMask bitPosToMask(const unsigned Pos)
Create a mask with a bit enabled at position Pos.
llvm::APSInt getShuffleMaskIdx(unsigned N) const
unsigned getNumSubExprs() const
getNumSubExprs - Return the size of the SubExprs array.
Expr * getExpr(unsigned Index)
getExpr - Return the Expr at the specified index.
unsigned getPackLength() const
Retrieve the length of the parameter pack.
APValue EvaluateInContext(const ASTContext &Ctx, const Expr *DefaultExpr) const
Return the result of evaluating this SourceLocExpr in the specified (and possibly null) default argum...
SourceLocation getLocation() const
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().
SourceLocation getBeginLoc() const LLVM_READONLY
Expr * getReplacement() const
virtual bool useFP16ConversionIntrinsics() const
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
const llvm::fltSemantics & getHalfFormat() const
const llvm::fltSemantics & getBFloat16Format() const
const llvm::fltSemantics & getLongDoubleFormat() const
const llvm::fltSemantics & getFloat128Format() const
const llvm::fltSemantics & getIbm128Format() const
QualType getType() const
Return the type wrapped by this type source info.
bool getBoolValue() const
const APValue & getAPValue() const
bool isStoredAsBoolean() const
bool isBooleanType() const
bool isSignableType(const ASTContext &Ctx) const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
CXXRecordDecl * castAsCXXRecordDecl() const
bool isArithmeticType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
bool isExtVectorBoolType() const
bool isOCLIntelSubgroupAVCType() const
bool isBuiltinType() const
Helper methods to distinguish type categories.
RecordDecl * castAsRecordDecl() const
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
bool isMatrixType() const
bool isFunctionType() const
bool isVectorType() 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 * castAsCanonical() const
Return this type's canonical type cast to the specified type.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
QualType getTypeOfArgument() const
Gets the argument type, or the type of the argument expression, whichever is appropriate.
bool isArgumentType() const
UnaryExprOrTypeTrait getKind() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
bool canOverflow() const
Returns true if the unary operator can cause an overflow.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a C array with a specified size that is not an integer-constant-expression.
Represents a GCC generic vector type.
WhileStmt - This represents a 'while' stmt.
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::ArgumentAdaptingMatcherFunc< internal::HasMatcher > has
Matches AST nodes that have child AST nodes that match the provided matcher.
const AstTypeMatcher< PointerType > pointerType
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
bool LE(InterpState &S, CodePtr OpPC)
bool Load(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ Result
The result type of a method or function.
const FunctionProtoType * T
CastKind
CastKind - The kind of operation required for a conversion.
U cast(CodeGen::Address addr)
Diagnostic wrappers for TextAPI types for error reporting.
cl::opt< bool > EnableSingleByteCoverage
llvm::Value * TotalOffset
llvm::Value * OffsetOverflows
Structure with information about how a bitfield should be accessed.
unsigned Size
The total size of the bit-field, in bits.
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const
static TBAAAccessInfo getMayAliasInfo()
APValue Val
Val - This is the value the expression can be folded to.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.